NIFI-6382: Allow Parameters to have null values

Signed-off-by: Bryan Bende <bbende@apache.org>
This commit is contained in:
Mark Payne 2019-08-08 10:54:03 -04:00 committed by Bryan Bende
parent 9c8f40415e
commit bcf373a049
No known key found for this signature in database
GPG Key ID: A0DDA9ED50711C39
25 changed files with 530 additions and 153 deletions

View File

@ -106,4 +106,12 @@ public interface ValidationContext extends PropertyContext {
* @return <code>true</code> if a Parameter with the given name is defined in the currently selected Parameter Context
*/
boolean isParameterDefined(String parameterName);
/**
* Returns <code>true</code> if a Parameter with the given name is defined and has a non-null value, <code>false</code> if either the Parameter
* is not defined or the Parameter is defined but has a value of <code>null</code>.
* @param parameterName the name of the parameter
* @return <code>true</code> if the Parameter is defined and has a non-null value, false otherwise
*/
boolean isParameterSet(String parameterName);
}

View File

@ -133,4 +133,9 @@ public class NotificationValidationContext implements ValidationContext {
public boolean isParameterDefined(final String parameterName) {
return false;
}
@Override
public boolean isParameterSet(final String parameterName) {
return false;
}
}

View File

@ -181,8 +181,12 @@ public class MockValidationContext extends MockControllerServiceLookup implement
@Override
public boolean isParameterDefined(final String parameterName) {
// TODO: Implement
return false;
return true;
}
@Override
public boolean isParameterSet(final String parameterName) {
return true;
}
}

View File

@ -16,13 +16,26 @@
*/
package org.apache.nifi.util.db;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.apache.avro.Conversions;
import org.apache.avro.LogicalType;
import org.apache.avro.LogicalTypes;
import org.apache.avro.Schema;
import org.apache.avro.file.DataFileStream;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumReader;
import org.apache.avro.util.Utf8;
import org.apache.commons.io.input.ReaderInputStream;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -63,26 +76,13 @@ import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.stream.IntStream;
import org.apache.avro.Conversions;
import org.apache.avro.LogicalType;
import org.apache.avro.LogicalTypes;
import org.apache.avro.Schema;
import org.apache.avro.file.DataFileStream;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumReader;
import org.apache.avro.util.Utf8;
import org.apache.commons.io.input.ReaderInputStream;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class TestJdbcCommon {

View File

@ -659,6 +659,14 @@ public abstract class AbstractComponentNode implements ComponentNode {
.explanation("Property references Parameter '" + paramName + "' but the currently selected Parameter Context does not have a Parameter with that name")
.build());
}
if (!validationContext.isParameterSet(paramName)) {
results.add(new ValidationResult.Builder()
.subject(propertyDescriptor.getDisplayName())
.valid(false)
.explanation("Property references Parameter '" + paramName + "' but the currently selected Parameter Context does not have a value set for that Parameter")
.build());
}
}
}

View File

@ -36,6 +36,7 @@ import org.apache.nifi.web.api.dto.FlowSnippetDTO;
import java.net.URL;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@ -322,7 +323,7 @@ public interface FlowManager {
void removeRootControllerService(final ControllerServiceNode service);
ParameterContext createParameterContext(String id, String name, Set<Parameter> parameters);
ParameterContext createParameterContext(String id, String name, Map<String, Parameter> parameters);
ParameterContextManager getParameterContextManager();
}

View File

@ -20,7 +20,6 @@ import org.apache.nifi.authorization.resource.Authorizable;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
public interface ParameterContext extends ParameterLookup, Authorizable {
@ -52,19 +51,22 @@ public interface ParameterContext extends ParameterLookup, Authorizable {
void setDescription(String description);
/**
* Updates the Parameters within this context to match the given set of Parameters.
* @param updatedParameters the updated set of parameters
* Updates the Parameters within this context to match the given set of Parameters. If the Parameter Context contains any parameters that are not in
* the given set of updated Parameters, those parameters are unaffected. However, if the Map contains any key with a <code>null</code> value, the
* parameter whose name is given by the key will be removed
*
* @param updatedParameters the updated set of parameters, keyed by Parameter name
* @throws IllegalStateException if any parameter is modified or removed and that parameter is being referenced by a running Processor or an enabled Controller Service, or if
* an update would result in changing the sensitivity of any parameter
*/
void setParameters(Set<Parameter> updatedParameters);
void setParameters(Map<String, Parameter> updatedParameters);
/**
* Ensures that it is legal to update the Parameters for this Parameter Context to match the given set of Parameters
* @param parameters the Set of Parameters that are to become the new Parameters for this Parameter Context
* @param parameters the updated set of parameters, keyed by Parameter name
* @throws IllegalStateException if setting the given set of Parameters is not legal
*/
void verifyCanSetParameters(Set<Parameter> parameters);
void verifyCanSetParameters(Map<String, Parameter> parameters);
/**

View File

@ -131,6 +131,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
@ -547,10 +548,10 @@ public class StandardFlowSynchronizer implements FlowSynchronizer {
}
private ParameterContext createParameterContext(final ParameterContextDTO dto, final FlowManager flowManager) {
final Set<Parameter> parameters = dto.getParameters().stream()
final Map<String, Parameter> parameters = dto.getParameters().stream()
.map(ParameterEntity::getParameter)
.map(this::createParameter)
.collect(Collectors.toSet());
.collect(Collectors.toMap(param -> param.getDescriptor().getName(), Function.identity()));
final ParameterContext context = flowManager.createParameterContext(dto.getId(), dto.getName(), parameters);
context.setDescription(dto.getDescription());

View File

@ -736,7 +736,7 @@ public class StandardFlowManager implements FlowManager {
}
@Override
public ParameterContext createParameterContext(final String id, final String name, final Set<Parameter> parameters) {
public ParameterContext createParameterContext(final String id, final String name, final Map<String, Parameter> parameters) {
final boolean namingConflict = parameterContextManager.getParameterContexts().stream()
.anyMatch(paramContext -> paramContext.getName().equals(name));

View File

@ -34,7 +34,6 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@ -97,32 +96,26 @@ public class StandardParameterContext implements ParameterContext {
return description;
}
public void setParameters(final Set<Parameter> updatedParameters) {
public void setParameters(final Map<String, Parameter> updatedParameters) {
writeLock.lock();
try {
this.version++;
verifyCanSetParameters(updatedParameters);
boolean changeAffectingComponents = false;
for (final Parameter parameter : updatedParameters) {
if (parameter.getValue() == null && parameter.getDescriptor().getDescription() == null) {
parameters.remove(parameter.getDescriptor());
changeAffectingComponents = true;
} else if (parameter.getValue() == null) {
// Value is null but description is not. Just update the description of the existing Parameter.
final Parameter existingParameter = parameters.get(parameter.getDescriptor());
final ParameterDescriptor existingDescriptor = existingParameter.getDescriptor();
final ParameterDescriptor replacementDescriptor = new ParameterDescriptor.Builder()
.from(existingDescriptor)
.description(parameter.getDescriptor().getDescription())
.build();
for (final Map.Entry<String, Parameter> entry : updatedParameters.entrySet()) {
final String parameterName = entry.getKey();
final Parameter parameter = entry.getValue();
final Parameter replacementParameter = new Parameter(replacementDescriptor, existingParameter.getValue());
parameters.put(parameter.getDescriptor(), replacementParameter);
} else {
parameters.put(parameter.getDescriptor(), parameter);
if (parameter == null) {
final ParameterDescriptor parameterDescriptor = new ParameterDescriptor.Builder().name(parameterName).build();
parameters.remove(parameterDescriptor);
changeAffectingComponents = true;
} else {
final Parameter oldParameter = parameters.put(parameter.getDescriptor(), parameter);
if (oldParameter == null || !Objects.equals(oldParameter.getValue(), parameter.getValue())) {
changeAffectingComponents = true;
}
}
}
@ -195,25 +188,23 @@ public class StandardParameterContext implements ParameterContext {
}
@Override
public void verifyCanSetParameters(final Set<Parameter> updatedParameters) {
public void verifyCanSetParameters(final Map<String, Parameter> updatedParameters) {
// Ensure that the updated parameters will not result in changing the sensitivity flag of any parameter.
for (final Parameter updatedParameter : updatedParameters) {
validateSensitiveFlag(updatedParameter);
// Parameters' names and sensitivity flags are immutable. However, the description and value are mutable. If both value and description are
// set to `null`, this is the indication that the Parameter should be removed. If the value is `null` but the Description is supplied, the user
// is indicating that only the description is to be changed.
if (updatedParameter.getValue() == null && updatedParameter.getDescriptor().getDescription() == null) {
validateReferencingComponents(updatedParameter, "remove");
} else if (updatedParameter.getValue() != null) {
validateReferencingComponents(updatedParameter, "update");
} else {
// Only parameter is changing. No value is set. This means that the Parameter must already exist.
final Optional<Parameter> existing = getParameter(updatedParameter.getDescriptor());
if (!existing.isPresent()) {
throw new IllegalStateException("Cannot add Parameter '" + updatedParameter.getDescriptor().getName() + "' without providing a value");
}
for (final Map.Entry<String, Parameter> entry : updatedParameters.entrySet()) {
final String parameterName = entry.getKey();
final Parameter parameter = entry.getValue();
if (parameter == null) {
// parameter is being deleted.
validateReferencingComponents(parameterName, null,"remove");
continue;
}
if (!Objects.equals(parameterName, parameter.getDescriptor().getName())) {
throw new IllegalArgumentException("Parameter '" + parameterName + "' was specified with the wrong key in the Map");
}
validateSensitiveFlag(parameter);
validateReferencingComponents(parameterName, parameter, "update");
}
}
@ -236,25 +227,27 @@ public class StandardParameterContext implements ParameterContext {
}
private void validateReferencingComponents(final Parameter updatedParameter, final String parameterAction) {
final String paramName = updatedParameter.getDescriptor().getName();
for (final ProcessorNode procNode : parameterReferenceManager.getProcessorsReferencing(this, paramName)) {
private void validateReferencingComponents(final String parameterName, final Parameter parameter, final String parameterAction) {
for (final ProcessorNode procNode : parameterReferenceManager.getProcessorsReferencing(this, parameterName)) {
if (procNode.isRunning()) {
throw new IllegalStateException("Cannot " + parameterAction + " parameter '" + paramName + "' because it is referenced by " + procNode + ", which is currently running");
throw new IllegalStateException("Cannot " + parameterAction + " parameter '" + parameterName + "' because it is referenced by " + procNode + ", which is currently running");
}
validateParameterSensitivity(updatedParameter, procNode);
if (parameter != null) {
validateParameterSensitivity(parameter, procNode);
}
}
for (final ControllerServiceNode serviceNode : parameterReferenceManager.getControllerServicesReferencing(this, paramName)) {
for (final ControllerServiceNode serviceNode : parameterReferenceManager.getControllerServicesReferencing(this, parameterName)) {
final ControllerServiceState serviceState = serviceNode.getState();
if (serviceState != ControllerServiceState.DISABLED) {
throw new IllegalStateException("Cannot " + parameterAction + " parameter '" + paramName + "' because it is referenced by "
throw new IllegalStateException("Cannot " + parameterAction + " parameter '" + parameterName + "' because it is referenced by "
+ serviceNode + ", which currently has a state of " + serviceState);
}
validateParameterSensitivity(updatedParameter, serviceNode);
if (parameter != null) {
validateParameterSensitivity(parameter, serviceNode);
}
}
}

View File

@ -33,6 +33,7 @@ import org.apache.nifi.controller.service.ControllerServiceProvider;
import org.apache.nifi.controller.service.ControllerServiceState;
import org.apache.nifi.expression.ExpressionLanguageCompiler;
import org.apache.nifi.groups.ProcessGroup;
import org.apache.nifi.parameter.Parameter;
import org.apache.nifi.parameter.ParameterContext;
import org.apache.nifi.parameter.ParameterReference;
import org.apache.nifi.registry.VariableRegistry;
@ -43,6 +44,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -216,6 +218,21 @@ public class StandardValidationContext implements ValidationContext {
return parameterContext.getParameter(parameterName).isPresent();
}
@Override
public boolean isParameterSet(final String parameterName) {
if (parameterContext == null) {
return false;
}
final Optional<Parameter> parameterOption = parameterContext.getParameter(parameterName);
if (!parameterOption.isPresent()) {
return false;
}
final String value = parameterOption.get().getValue();
return value != null;
}
@Override
public String toString() {
return "StandardValidationContext[componentId=" + componentId + ", properties=" + properties + "]";

View File

@ -550,6 +550,11 @@ public class TestStandardProcessorNode {
public boolean isParameterDefined(final String parameterName) {
return false;
}
@Override
public boolean isParameterSet(final String parameterName) {
return false;
}
};
}

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.integration.auth;
import org.apache.nifi.authentication.AuthenticationResponse;
import org.apache.nifi.authentication.LoginCredentials;
import org.apache.nifi.authentication.LoginIdentityProvider;
import org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
import org.apache.nifi.authentication.LoginIdentityProviderInitializationContext;
import org.apache.nifi.authentication.exception.IdentityAccessException;
import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
import org.apache.nifi.authentication.exception.ProviderCreationException;
import org.apache.nifi.authentication.exception.ProviderDestructionException;
public class AlwaysAuthenticate implements LoginIdentityProvider {
@Override
public AuthenticationResponse authenticate(final LoginCredentials credentials) throws InvalidLoginCredentialsException, IdentityAccessException {
return new AuthenticationResponse(credentials.getUsername(), credentials.getUsername(), 1_000_000L, "unit-test-issuer");
}
@Override
public void initialize(final LoginIdentityProviderInitializationContext initializationContext) throws ProviderCreationException {
}
@Override
public void onConfigured(final LoginIdentityProviderConfigurationContext configurationContext) throws ProviderCreationException {
}
@Override
public void preDestruction() throws ProviderDestructionException {
}
}

View File

@ -0,0 +1,118 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.integration.auth;
import org.apache.nifi.authorization.AccessPolicy;
import org.apache.nifi.authorization.AccessPolicyProvider;
import org.apache.nifi.authorization.AccessPolicyProviderInitializationContext;
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class VolatileAccessPolicyProvider implements AccessPolicyProvider {
private final VolatileUserGroupProvider userGroupProvider = new VolatileUserGroupProvider();
private Set<AccessPolicy> accessPolicies = new HashSet<>();
public synchronized void grantAccess(final String user, final String resourceIdentifier, final RequestAction action) {
final AccessPolicy existingPolicy = getAccessPolicy(resourceIdentifier, action);
final AccessPolicy policy;
if (existingPolicy == null) {
policy = new AccessPolicy.Builder()
.addUser(user)
.action(action)
.identifierGenerateRandom()
.resource(resourceIdentifier)
.build();
} else {
policy = new AccessPolicy.Builder()
.addUsers(existingPolicy.getUsers())
.addUser(user)
.action(action)
.identifier(existingPolicy.getIdentifier())
.resource(resourceIdentifier)
.build();
}
accessPolicies.remove(existingPolicy);
accessPolicies.add(policy);
}
public synchronized void revokeAccess(final String user, final String resourceIdentifier, final RequestAction action) {
final AccessPolicy existingPolicy = getAccessPolicy(resourceIdentifier, action);
if (existingPolicy == null) {
return;
}
final AccessPolicy policy= new AccessPolicy.Builder()
.addUsers(existingPolicy.getUsers())
.removeUser(user)
.action(action)
.identifier(existingPolicy.getIdentifier())
.resource(resourceIdentifier)
.build();
accessPolicies.remove(existingPolicy);
accessPolicies.add(policy);
}
@Override
public synchronized Set<AccessPolicy> getAccessPolicies() throws AuthorizationAccessException {
return new HashSet<>(accessPolicies);
}
@Override
public synchronized AccessPolicy getAccessPolicy(final String identifier) throws AuthorizationAccessException {
return accessPolicies.stream()
.filter(policy -> policy.getIdentifier().equals(identifier))
.findAny()
.orElse(null);
}
@Override
public synchronized AccessPolicy getAccessPolicy(final String resourceIdentifier, final RequestAction action) throws AuthorizationAccessException {
return accessPolicies.stream()
.filter(policy -> Objects.equals(policy.getResource(), resourceIdentifier))
.filter(policy -> Objects.equals(policy.getAction(), action))
.findAny()
.orElse(null);
}
@Override
public synchronized VolatileUserGroupProvider getUserGroupProvider() {
return userGroupProvider;
}
@Override
public void initialize(final AccessPolicyProviderInitializationContext initializationContext) throws AuthorizerCreationException {
}
@Override
public void onConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
}
@Override
public void preDestruction() throws AuthorizerDestructionException {
}
}

View File

@ -0,0 +1,111 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.integration.auth;
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
import org.apache.nifi.authorization.Group;
import org.apache.nifi.authorization.User;
import org.apache.nifi.authorization.UserAndGroups;
import org.apache.nifi.authorization.UserGroupProvider;
import org.apache.nifi.authorization.UserGroupProviderInitializationContext;
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public class VolatileUserGroupProvider implements UserGroupProvider {
private final Map<String, User> users = new HashMap<>();
private final Map<String, Group> groups = new HashMap<>();
private final Map<User, Set<Group>> userGroupMapping = new HashMap<>();
public void addUser(final User user) {
this.users.put(user.getIdentifier(), user);
}
public void addGroup(final Group group) {
this.groups.put(group.getIdentifier(), group);
}
public void addUserToGroup(final User user, final Group group) {
userGroupMapping.computeIfAbsent(user, i -> new HashSet<>()).add(group);
}
@Override
public Set<User> getUsers() throws AuthorizationAccessException {
return new HashSet<>(users.values());
}
@Override
public User getUser(final String identifier) throws AuthorizationAccessException {
return users.get(identifier);
}
@Override
public User getUserByIdentity(final String identity) throws AuthorizationAccessException {
return users.values().stream()
.filter(user -> Objects.equals(identity, user.getIdentity()))
.findFirst()
.orElse(null);
}
@Override
public Set<Group> getGroups() throws AuthorizationAccessException {
return new HashSet<>(groups.values());
}
@Override
public Group getGroup(final String identifier) throws AuthorizationAccessException {
return groups.get(identifier);
}
@Override
public UserAndGroups getUserAndGroups(final String identity) throws AuthorizationAccessException {
final User user = getUserByIdentity(identity);
final Set<Group> groups = userGroupMapping.get(user);
final Set<Group> groupCopy = groups == null ? Collections.emptySet() : new HashSet<>(groups);
return new UserAndGroups() {
@Override
public User getUser() {
return user;
}
@Override
public Set<Group> getGroups() {
return groupCopy;
}
};
}
@Override
public void initialize(final UserGroupProviderInitializationContext initializationContext) throws AuthorizerCreationException {
}
@Override
public void onConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
}
@Override
public void preDestruction() throws AuthorizerDestructionException {
}
}

View File

@ -58,7 +58,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);
updateAttribute.setProperties(Collections.singletonMap("test", "#{test}"));
@ -83,7 +83,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);
updateAttribute.setProperties(Collections.singletonMap("test", "${#{test}:toUpper()}"));
@ -108,7 +108,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);
updateAttribute.setProperties(Collections.singletonMap("test", "${#{test}:toUpper()}"));
@ -133,7 +133,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);
@ -165,7 +165,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);
@ -193,7 +193,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);
@ -225,7 +225,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);
@ -267,7 +267,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);
@ -307,7 +307,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);
@ -337,7 +337,7 @@ public class ParametersIT extends FrameworkIntegrationTest {
final ParameterReferenceManager referenceManager = new StandardParameterReferenceManager(getFlowController().getFlowManager());
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "param-context", referenceManager, null);
parameterContext.setParameters(Collections.singleton(new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
parameterContext.setParameters(Collections.singletonMap("test", new Parameter(new ParameterDescriptor.Builder().name("test").build(), "unit")));
getRootGroup().setParameterContext(parameterContext);

View File

@ -40,7 +40,6 @@ import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -77,9 +76,9 @@ public class ProcessorParameterTokenIT extends FrameworkIntegrationTest {
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "testEscapedParameterReference", ParameterReferenceManager.EMPTY, null);
getRootGroup().setParameterContext(parameterContext);
final Set<Parameter> parameters = new HashSet<>();
parameters.add(new Parameter(new ParameterDescriptor.Builder().name("foo").build(), "bar"));
parameters.add(new Parameter(new ParameterDescriptor.Builder().name("sensitive").sensitive(true).build(), "*password*"));
final Map<String, Parameter> parameters = new HashMap<>();
parameters.put("foo", new Parameter(new ParameterDescriptor.Builder().name("foo").build(), "bar"));
parameters.put("sensitive", new Parameter(new ParameterDescriptor.Builder().name("sensitive").sensitive(true).build(), "*password*"));
parameterContext.setParameters(parameters);
verifyText(procNode, "hello", "hello");
@ -107,9 +106,9 @@ public class ProcessorParameterTokenIT extends FrameworkIntegrationTest {
final ParameterContext parameterContext = new StandardParameterContext(UUID.randomUUID().toString(), "testEscapedParameterReference", ParameterReferenceManager.EMPTY, null);
getRootGroup().setParameterContext(parameterContext);
final Set<Parameter> parameters = new HashSet<>();
parameters.add(new Parameter(new ParameterDescriptor.Builder().name("foo").build(), "bar"));
parameters.add(new Parameter(new ParameterDescriptor.Builder().name("sensitive").sensitive(true).build(), "*password*"));
final Map<String, Parameter> parameters = new HashMap<>();
parameters.put("foo", new Parameter(new ParameterDescriptor.Builder().name("foo").build(), "bar"));
parameters.put("sensitive", new Parameter(new ParameterDescriptor.Builder().name("sensitive").sensitive(true).build(), "*password*"));
parameterContext.setParameters(parameters);
verifyCannotSetParameter(procNode, "#{sensitive}", null);

View File

@ -34,6 +34,8 @@ import org.apache.nifi.registry.flow.VersionedControllerService;
import org.apache.nifi.registry.flow.VersionedFlow;
import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
import org.apache.nifi.registry.flow.VersionedParameter;
import org.apache.nifi.registry.flow.VersionedParameterContext;
import org.apache.nifi.registry.flow.VersionedProcessGroup;
import org.apache.nifi.registry.flow.VersionedProcessor;
import org.apache.nifi.registry.flow.mapping.NiFiRegistryFlowMapper;
@ -44,6 +46,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@ -70,7 +73,7 @@ public class ImportFlowIT extends FrameworkIntegrationTest {
processor.setAutoTerminatedRelationships(Collections.singleton(REL_SUCCESS));
processor.setProperties(Collections.singletonMap(NopServiceReferencingProcessor.SERVICE.getName(), controllerService.getIdentifier()));
final VersionedFlowSnapshot proposedFlow = createFlowSnapshot(Collections.singletonList(controllerService), Collections.singletonList(processor));
final VersionedFlowSnapshot proposedFlow = createFlowSnapshot(Collections.singletonList(controllerService), Collections.singletonList(processor), null);
// Create an Inner Process Group and update it to match the Versioned Flow.
final ProcessGroup innerGroup = getFlowController().getFlowManager().createProcessGroup("inner-group-id");
@ -107,7 +110,7 @@ public class ImportFlowIT extends FrameworkIntegrationTest {
}
private VersionedFlowSnapshot createFlowSnapshot(final List<ControllerServiceNode> controllerServices, final List<ProcessorNode> processors) {
private VersionedFlowSnapshot createFlowSnapshot(final List<ControllerServiceNode> controllerServices, final List<ProcessorNode> processors, final Map<String, String> parameters) {
final VersionedFlowSnapshotMetadata snapshotMetadata = new VersionedFlowSnapshotMetadata();
snapshotMetadata.setAuthor("unit-test");
snapshotMetadata.setBucketIdentifier("unit-test-bucket");
@ -159,6 +162,21 @@ public class ImportFlowIT extends FrameworkIntegrationTest {
versionedFlowSnapshot.setFlow(flow);
versionedFlowSnapshot.setFlowContents(flowContents);
if (parameters != null) {
final Set<VersionedParameter> versionedParameters = new HashSet<>();
for (final Map.Entry<String, String> entry : parameters.entrySet()) {
final VersionedParameter versionedParameter = new VersionedParameter();
versionedParameter.setName(entry.getKey());
versionedParameter.setValue(entry.getValue());
versionedParameters.add(versionedParameter);
}
final VersionedParameterContext versionedParameterContext = new VersionedParameterContext();
versionedParameterContext.setName("Unit Test Context");
versionedParameterContext.setParameters(versionedParameters);
versionedFlowSnapshot.setParameterContexts(Collections.singletonMap("unit-test-context", versionedParameterContext));
}
return versionedFlowSnapshot;
}
}

View File

@ -27,7 +27,6 @@ import org.mockito.Mockito;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@ -47,9 +46,9 @@ public class TestStandardParameterContext {
final ParameterDescriptor xyzDescriptor = new ParameterDescriptor.Builder().name("xyz").build();
final ParameterDescriptor fooDescriptor = new ParameterDescriptor.Builder().name("foo").description("bar").sensitive(true).build();
final Set<Parameter> parameters = new HashSet<>();
parameters.add(new Parameter(abcDescriptor, "123"));
parameters.add(new Parameter(xyzDescriptor, "242526"));
final Map<String, Parameter> parameters = new HashMap<>();
parameters.put("abc", new Parameter(abcDescriptor, "123"));
parameters.put("xyz", new Parameter(xyzDescriptor, "242526"));
context.setParameters(parameters);
@ -63,15 +62,15 @@ public class TestStandardParameterContext {
assertNull(xyzParam.getDescriptor().getDescription());
assertEquals("242526", xyzParam.getValue());
final Set<Parameter> secondParameters = new HashSet<>();
secondParameters.add(new Parameter(fooDescriptor, "baz"));
final Map<String, Parameter> secondParameters = new HashMap<>();
secondParameters.put("foo", new Parameter(fooDescriptor, "baz"));
context.setParameters(secondParameters);
assertTrue(context.getParameter("abc").isPresent());
assertTrue(context.getParameter("xyz").isPresent());
secondParameters.add(new Parameter(abcParam.getDescriptor(), null));
secondParameters.add(new Parameter(xyzParam.getDescriptor(), null));
secondParameters.put("abc", null);
secondParameters.put("xyz", null);
context.setParameters(secondParameters);
@ -86,8 +85,8 @@ public class TestStandardParameterContext {
assertEquals(Collections.singletonMap(fooDescriptor, fooParam), context.getParameters());
final Set<Parameter> thirdParameters = new HashSet<>();
thirdParameters.add(new Parameter(fooDescriptor, "other"));
final Map<String, Parameter> thirdParameters = new HashMap<>();
thirdParameters.put("foo", new Parameter(fooDescriptor, "other"));
context.setParameters(thirdParameters);
assertEquals("other", context.getParameter("foo").get().getValue());
@ -100,8 +99,8 @@ public class TestStandardParameterContext {
final ParameterDescriptor abcDescriptor = new ParameterDescriptor.Builder().name("abc").description("abc").build();
final Set<Parameter> parameters = new HashSet<>();
parameters.add(new Parameter(abcDescriptor, "123"));
final Map<String, Parameter> parameters = new HashMap<>();
parameters.put("abc", new Parameter(abcDescriptor, "123"));
context.setParameters(parameters);
@ -112,7 +111,7 @@ public class TestStandardParameterContext {
ParameterDescriptor updatedDescriptor = new ParameterDescriptor.Builder().name("abc").description("Updated").build();
final Parameter newDescriptionParam = new Parameter(updatedDescriptor, "321");
context.setParameters(Collections.singleton(newDescriptionParam));
context.setParameters(Collections.singletonMap("abc", newDescriptionParam));
abcParam = context.getParameter("abc").get();
assertEquals(abcDescriptor, abcParam.getDescriptor());
@ -121,12 +120,12 @@ public class TestStandardParameterContext {
updatedDescriptor = new ParameterDescriptor.Builder().name("abc").description("Updated Again").build();
final Parameter paramWithoutValue = new Parameter(updatedDescriptor, null);
context.setParameters(Collections.singleton(paramWithoutValue));
context.setParameters(Collections.singletonMap("abc", paramWithoutValue));
abcParam = context.getParameter("abc").get();
assertEquals(abcDescriptor, abcParam.getDescriptor());
assertEquals("Updated Again", abcParam.getDescriptor().getDescription());
assertEquals("321", abcParam.getValue());
assertNull(abcParam.getValue());
}
@Test
@ -139,17 +138,17 @@ public class TestStandardParameterContext {
final ParameterDescriptor xyzDescriptor = new ParameterDescriptor.Builder().name("xyz").build();
final ParameterDescriptor fooDescriptor = new ParameterDescriptor.Builder().name("foo").description("bar").sensitive(true).build();
final Set<Parameter> parameters = new HashSet<>();
parameters.add(new Parameter(abcDescriptor, "123"));
parameters.add(new Parameter(xyzDescriptor, "242526"));
final Map<String, Parameter> parameters = new HashMap<>();
parameters.put("abc", new Parameter(abcDescriptor, "123"));
parameters.put("xyz", new Parameter(xyzDescriptor, "242526"));
context.setParameters(parameters);
final ParameterDescriptor sensitiveXyzDescriptor = new ParameterDescriptor.Builder().name("xyz").sensitive(true).build();
final Set<Parameter> updatedParameters = new HashSet<>();
updatedParameters.add(new Parameter(fooDescriptor, "baz"));
updatedParameters.add(new Parameter(sensitiveXyzDescriptor, "242526"));
final Map<String, Parameter> updatedParameters = new HashMap<>();
updatedParameters.put("foo", new Parameter(fooDescriptor, "baz"));
updatedParameters.put("xyz", new Parameter(sensitiveXyzDescriptor, "242526"));
try {
context.setParameters(updatedParameters);
@ -159,7 +158,7 @@ public class TestStandardParameterContext {
final ParameterDescriptor insensitiveAbcDescriptor = new ParameterDescriptor.Builder().name("abc").sensitive(false).build();
updatedParameters.clear();
updatedParameters.add(new Parameter(insensitiveAbcDescriptor, "123"));
updatedParameters.put("abc", new Parameter(insensitiveAbcDescriptor, "123"));
try {
context.setParameters(updatedParameters);
@ -179,13 +178,13 @@ public class TestStandardParameterContext {
final ParameterDescriptor abcDescriptor = new ParameterDescriptor.Builder().name("abc").sensitive(true).build();
final Set<Parameter> parameters = new HashSet<>();
parameters.add(new Parameter(abcDescriptor, "123"));
final Map<String, Parameter> parameters = new HashMap<>();
parameters.put("abc", new Parameter(abcDescriptor, "123"));
context.setParameters(parameters);
parameters.clear();
parameters.add(new Parameter(abcDescriptor, "321"));
parameters.put("abc", new Parameter(abcDescriptor, "321"));
context.setParameters(parameters);
assertEquals("321", context.getParameter("abc").get().getValue());
@ -194,7 +193,7 @@ public class TestStandardParameterContext {
Mockito.when(procNode.isRunning()).thenReturn(true);
parameters.clear();
parameters.add(new Parameter(abcDescriptor, "123"));
parameters.put("abc", new Parameter(abcDescriptor, "123"));
try {
context.setParameters(parameters);
@ -202,10 +201,10 @@ public class TestStandardParameterContext {
} catch (final IllegalStateException expected) {
}
context.setParameters(Collections.emptySet());
context.setParameters(Collections.emptyMap());
parameters.clear();
parameters.add(new Parameter(abcDescriptor, null));
parameters.put("abc", new Parameter(abcDescriptor, null));
try {
context.setParameters(parameters);
Assert.fail("Was able to remove parameter while referencing processor was running");
@ -224,15 +223,15 @@ public class TestStandardParameterContext {
Mockito.when(serviceNode.getState()).thenReturn(ControllerServiceState.ENABLED);
final ParameterDescriptor abcDescriptor = new ParameterDescriptor.Builder().name("abc").sensitive(true).build();
final Set<Parameter> parameters = new HashSet<>();
parameters.add(new Parameter(abcDescriptor, "123"));
final Map<String, Parameter> parameters = new HashMap<>();
parameters.put("abc", new Parameter(abcDescriptor, "123"));
context.setParameters(parameters);
referenceManager.addControllerServiceReference("abc", serviceNode);
parameters.clear();
parameters.add(new Parameter(abcDescriptor, "321"));
parameters.put("abc", new Parameter(abcDescriptor, "321"));
for (final ControllerServiceState state : EnumSet.of(ControllerServiceState.ENABLED, ControllerServiceState.ENABLING, ControllerServiceState.DISABLING)) {
Mockito.when(serviceNode.getState()).thenReturn(state);
@ -249,7 +248,7 @@ public class TestStandardParameterContext {
parameters.clear();
context.setParameters(parameters);
parameters.add(new Parameter(abcDescriptor, null));
parameters.put("abc", new Parameter(abcDescriptor, null));
try {
context.setParameters(parameters);
Assert.fail("Was able to remove parameter being referenced by Controller Service that is DISABLING");

View File

@ -218,7 +218,7 @@ nifi.cluster.flow.election.max.candidates=
# cluster load balancing properties #
nifi.cluster.load.balance.host=
nifi.cluster.load.balance.port=6342
nifi.cluster.load.balance.port=0
nifi.cluster.load.balance.connections.per.node=4
nifi.cluster.load.balance.max.thread.count=8
nifi.cluster.load.balance.comms.timeout=30 sec

View File

@ -1046,10 +1046,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Set<ProcessGroup> boundProcessGroups = parameterContext.getParameterReferenceManager().getProcessGroupsBound(parameterContext);
final ParameterContext updatedParameterContext = new StandardParameterContext(parameterContext.getIdentifier(), parameterContext.getName(), ParameterReferenceManager.EMPTY, null);
final Set<Parameter> parameters = parameterContextDto.getParameters().stream()
final Map<String, Parameter> parameters = new HashMap<>();
parameterContextDto.getParameters().stream()
.map(ParameterEntity::getParameter)
.map(this::createParameter)
.collect(Collectors.toSet());
.forEach(param -> parameters.put(param.getDescriptor().getName(), param));
updatedParameterContext.setParameters(parameters);
final List<ComponentValidationResultEntity> validationResults = new ArrayList<>();
@ -1089,6 +1090,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
private Parameter createParameter(final ParameterDTO dto) {
if (dto.getDescription() == null && dto.getSensitive() == null && dto.getValue() == null) {
return null; // null description, sensitivity flag, and value indicates a deletion, which we want to represent as a null Parameter.
}
final ParameterDescriptor descriptor = new ParameterDescriptor.Builder()
.name(dto.getName())
.description(dto.getDescription())

View File

@ -37,10 +37,10 @@ import org.apache.nifi.web.api.entity.ParameterEntity;
import org.apache.nifi.web.dao.ParameterContextDAO;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class StandardParameterContextDAO implements ParameterContextDAO {
private FlowManager flowManager;
@ -57,7 +57,7 @@ public class StandardParameterContextDAO implements ParameterContextDAO {
@Override
public ParameterContext createParameterContext(final ParameterContextDTO parameterContextDto) {
final Set<Parameter> parameters = getParameters(parameterContextDto);
final Map<String, Parameter> parameters = getParameters(parameterContextDto);
final ParameterContext parameterContext = flowManager.createParameterContext(parameterContextDto.getId(), parameterContextDto.getName(), parameters);
if (parameterContextDto.getDescription() != null) {
parameterContext.setDescription(parameterContextDto.getDescription());
@ -65,16 +65,30 @@ public class StandardParameterContextDAO implements ParameterContextDAO {
return parameterContext;
}
private Set<Parameter> getParameters(final ParameterContextDTO parameterContextDto) {
final Set<ParameterEntity> parameterDtos = parameterContextDto.getParameters();
if (parameterDtos == null) {
return Collections.emptySet();
private Map<String, Parameter> getParameters(final ParameterContextDTO parameterContextDto) {
final Set<ParameterEntity> parameterEntities = parameterContextDto.getParameters();
if (parameterEntities == null) {
return Collections.emptyMap();
}
return parameterContextDto.getParameters().stream()
.map(ParameterEntity::getParameter)
.map(this::createParameter)
.collect(Collectors.toSet());
final Map<String, Parameter> parameterMap = new HashMap<>();
for (final ParameterEntity parameterEntity : parameterEntities) {
final ParameterDTO parameterDto = parameterEntity.getParameter();
if (parameterDto.getName() == null) {
throw new IllegalArgumentException("Cannot specify a Parameter without a name");
}
final boolean deletion = parameterDto.getDescription() == null && parameterDto.getSensitive() == null && parameterDto.getValue() == null;
if (deletion) {
parameterMap.put(parameterDto.getName(), null);
} else {
final Parameter parameter = createParameter(parameterDto);
parameterMap.put(parameterDto.getName(), parameter);
}
}
return parameterMap;
}
private Parameter createParameter(final ParameterDTO dto) {
@ -118,7 +132,7 @@ public class StandardParameterContextDAO implements ParameterContextDAO {
}
if (parameterContextDto.getParameters() != null) {
final Set<Parameter> parameters = getParameters(parameterContextDto);
final Map<String, Parameter> parameters = getParameters(parameterContextDto);
context.setParameters(parameters);
}

View File

@ -100,6 +100,11 @@ public abstract class ValidationContextAdapter implements ValidationContext {
return innerValidationContext.isParameterDefined(parameterName);
}
@Override
public boolean isParameterSet(final String parameterName) {
return innerValidationContext.isParameterSet(parameterName);
}
@Override
public Collection<String> getReferencedParameters(final String propertyName) {
return innerValidationContext.getReferencedParameters(propertyName);

View File

@ -61,13 +61,13 @@ public class StatelessParameterContext implements ParameterContext {
}
@Override
public void setParameters(final Set<Parameter> updatedParameters) {
throw new UnsupportedOperationException();
public void setParameters(final Map<String, Parameter> updatedParameters) {
throw new UnsupportedOperationException(); // This parameter context does not support updating - all parameters are provided in the constructor.
}
@Override
public void verifyCanSetParameters(final Set<Parameter> parameters) {
throw new UnsupportedOperationException();
public void verifyCanSetParameters(final Map<String, Parameter> parameters) {
throw new UnsupportedOperationException(); // This parameter context does not support updating - all parameters are provided in the constructor.
}
@Override

View File

@ -26,6 +26,7 @@ import org.apache.nifi.controller.ControllerService;
import org.apache.nifi.controller.ControllerServiceLookup;
import org.apache.nifi.controller.PropertyConfiguration;
import org.apache.nifi.expression.ExpressionLanguageCompiler;
import org.apache.nifi.parameter.Parameter;
import org.apache.nifi.parameter.ParameterContext;
import org.apache.nifi.parameter.ParameterReference;
import org.apache.nifi.registry.VariableRegistry;
@ -36,6 +37,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
public class StatelessValidationContext implements ValidationContext {
@ -146,6 +148,22 @@ public class StatelessValidationContext implements ValidationContext {
return parameterContext.getParameter(parameterName).isPresent();
}
@Override
public boolean isParameterSet(final String parameterName) {
if (parameterContext == null) {
return false;
}
final Optional<Parameter> parameterOption = parameterContext.getParameter(parameterName);
if (!parameterOption.isPresent()) {
return false;
}
final String value = parameterOption.get().getValue();
return value != null;
}
@Override
public ControllerServiceLookup getControllerServiceLookup() {
return this.lookup;