This is an automated email from the ASF dual-hosted git repository.

exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 2609fd5f55 NIFI-11122 Corrected provided parameter context inheritance 
after creation
2609fd5f55 is described below

commit 2609fd5f558e3b39a77c70d10e7a81c07022cad3
Author: Joe Gresock <[email protected]>
AuthorDate: Wed Feb 1 10:30:23 2023 -0500

    NIFI-11122 Corrected provided parameter context inheritance after creation
    
    This closes #6913
    
    Signed-off-by: David Handermann <[email protected]>
---
 .../parameter/StandardParameterProviderNode.java   |  17 ++-
 .../nifi/parameter/StandardParameterContext.java   |   6 +-
 .../apache/nifi/parameter/ParameterContext.java    |   6 +
 .../web/dao/impl/StandardParameterContextDAO.java  |   3 +-
 .../dao/impl/TestStandardParameterContextDAO.java  | 157 +++++++++++++++++++++
 5 files changed, 185 insertions(+), 4 deletions(-)

diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/parameter/StandardParameterProviderNode.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/parameter/StandardParameterProviderNode.java
index aca97a9599..c391e30ade 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/parameter/StandardParameterProviderNode.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/parameter/StandardParameterProviderNode.java
@@ -348,7 +348,22 @@ public class StandardParameterProviderNode extends 
AbstractComponentNode impleme
                 if (groupConfiguration == null) {
                     continue;
                 }
-                
reference.verifyCanSetParameters(getFetchedParameterUpdateMap(reference, 
groupConfiguration));
+                final Map<String, Parameter> parameterUpdates = 
getFetchedParameterUpdateMap(reference, groupConfiguration);
+                final Collection<String> removedParametersWithReferences = new 
HashSet<>();
+                for (final Map.Entry<String, Parameter> entry : 
parameterUpdates.entrySet()) {
+                    final String parameterName = entry.getKey();
+                    if (entry.getValue() == null) {
+                        
reference.getParameter(parameterName).ifPresent(currentParameter -> {
+                            if 
(reference.hasReferencingComponents(currentParameter)) {
+                                
removedParametersWithReferences.add(parameterName);
+                            }
+                        });
+                    }
+                }
+                // Any deletions of parameters with referencing components 
should be removed from consideration,
+                // since we do not remove provided parameters that are deleted 
until they are no longer referenced
+                
removedParametersWithReferences.forEach(parameterUpdates::remove);
+                reference.verifyCanSetParameters(parameterUpdates);
             }
         } finally {
             readLock.unlock();
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java
index 339317fdd9..da3350f099 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java
@@ -640,7 +640,8 @@ public class StandardParameterContext implements 
ParameterContext {
             // If a current parameter is not in the proposed parameters, it 
was effectively removed
             if 
(!effectiveProposedParameters.containsKey(currentParameterDescriptor)) {
                 final Parameter parameter = entry.getValue();
-                if (parameter.isProvided() && 
hasReferencingComponents(parameter)) {
+                final boolean isParameterInherited = 
!parameter.getParameterContextId().equals(id);
+                if (!isParameterInherited && parameter.isProvided() && 
hasReferencingComponents(parameter)) {
                     logger.info("Provided parameter [{}] was removed from the 
source, but it is referenced by a component, so the parameter will be 
preserved",
                             currentParameterDescriptor.getName());
                 } else {
@@ -651,7 +652,8 @@ public class StandardParameterContext implements 
ParameterContext {
         return effectiveParameterUpdates;
     }
 
-    private boolean hasReferencingComponents(final Parameter parameter) {
+    @Override
+    public boolean hasReferencingComponents(final Parameter parameter) {
         if (parameter == null) {
             return false;
         }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java
index aa13288d98..7177bbbed6 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java
@@ -174,6 +174,12 @@ public interface ParameterContext extends ParameterLookup, 
ComponentAuthorizable
      */
     List<String> getInheritedParameterContextNames();
 
+    /**
+     * @param parameter A parameter
+     * @return True if the parameter has referencing components
+     */
+    boolean hasReferencingComponents(Parameter parameter);
+
     /**
      * Returns true if this ParameterContext inherits from the given parameter 
context, either
      * directly or indirectly.
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardParameterContextDAO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardParameterContextDAO.java
index 125dff0d86..6504fd943d 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardParameterContextDAO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardParameterContextDAO.java
@@ -337,7 +337,8 @@ public class StandardParameterContextDAO implements 
ParameterContextDAO {
             }
         } else {
             final boolean hasProvidedParameters = parameters.stream()
-                    .anyMatch(parameter -> 
parameter.getParameter().getProvided() != null && 
parameter.getParameter().getProvided());
+                    .anyMatch(parameter -> 
parameter.getParameter().getProvided() != null && 
parameter.getParameter().getProvided()
+                            && !parameter.getParameter().getInherited());
             if (hasProvidedParameters) {
                 throw new IllegalArgumentException(String.format("Provided 
Parameters may not be set on Context [%s] because its " +
                         "parameters can only be user-entered", 
parameterContextDTO.getName()));
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/dao/impl/TestStandardParameterContextDAO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/dao/impl/TestStandardParameterContextDAO.java
new file mode 100644
index 0000000000..361a68e535
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/dao/impl/TestStandardParameterContextDAO.java
@@ -0,0 +1,157 @@
+/*
+ * 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.web.dao.impl;
+
+import org.apache.nifi.authorization.AuthorizationRequest;
+import org.apache.nifi.authorization.AuthorizationResult;
+import org.apache.nifi.authorization.Authorizer;
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.authorization.user.NiFiUserDetails;
+import org.apache.nifi.authorization.user.StandardNiFiUser;
+import org.apache.nifi.controller.FlowController;
+import org.apache.nifi.controller.flow.FlowManager;
+import org.apache.nifi.parameter.Parameter;
+import org.apache.nifi.parameter.ParameterContext;
+import org.apache.nifi.parameter.ParameterDescriptor;
+import org.apache.nifi.parameter.ParameterReferenceManager;
+import org.apache.nifi.parameter.StandardParameterContext;
+import org.apache.nifi.parameter.StandardParameterContextManager;
+import org.apache.nifi.parameter.StandardParameterReferenceManager;
+import org.apache.nifi.web.api.dto.ParameterContextDTO;
+import org.apache.nifi.web.api.dto.ParameterContextReferenceDTO;
+import org.apache.nifi.web.api.dto.ParameterDTO;
+import org.apache.nifi.web.api.entity.ParameterContextReferenceEntity;
+import org.apache.nifi.web.api.entity.ParameterEntity;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+public class TestStandardParameterContextDAO {
+
+    private StandardParameterContextDAO dao;
+
+    @Mock(answer = RETURNS_DEEP_STUBS)
+    private FlowController flowController;
+
+    @Mock
+    private Authentication authentication;
+
+    @Mock
+    private Authorizer authorizer;
+
+    @BeforeEach
+    void setUp() {
+        dao = new StandardParameterContextDAO();
+        dao.setFlowController(flowController);
+        dao.setAuthorizer(authorizer);
+        
when(authorizer.authorize(any(AuthorizationRequest.class))).thenReturn(AuthorizationResult.approved());
+
+        final SecurityContext securityContext = 
SecurityContextHolder.getContext();
+        securityContext.setAuthentication(authentication);
+        final NiFiUser user = new 
StandardNiFiUser.Builder().identity("user").build();
+        final NiFiUserDetails userDetail = new NiFiUserDetails(user);
+        when(authentication.getPrincipal()).thenReturn(userDetail);
+
+        final ParameterReferenceManager parameterReferenceManager = new 
StandardParameterReferenceManager(flowController.getFlowManager());
+
+        final FlowManager flowManager = flowController.getFlowManager();
+        final StandardParameterContextManager parameterContextLookup = new 
StandardParameterContextManager();
+        
when(flowManager.getParameterContextManager()).thenReturn(parameterContextLookup);
+        parameterContextLookup.addParameterContext(new 
StandardParameterContext.Builder().id("id")
+                .name("Context")
+                .parameterReferenceManager(parameterReferenceManager)
+                .build());
+        final ParameterContext inheritedContext = new 
StandardParameterContext.Builder().id("inherited-id")
+                .parameterReferenceManager(parameterReferenceManager)
+                .name("Inherited")
+                .build();
+        final Map<String, Parameter> parameters = new HashMap<>();
+        parameters.put("inherited-param", new Parameter(new 
ParameterDescriptor.Builder().name("inherited-param").build(),
+                "value", null, true));
+        inheritedContext.setParameters(parameters);
+        parameterContextLookup.addParameterContext(inheritedContext);
+    }
+
+    @Test
+    public void testVerifyUpdateInheritedProvidedParameter() {
+        final ParameterContextDTO dto = new ParameterContextDTO();
+        dto.setId("id");
+        dto.setName("Context");
+
+        final List<ParameterContextReferenceEntity> refs = new ArrayList<>();
+        final ParameterContextReferenceEntity ref = new 
ParameterContextReferenceEntity();
+        ref.setId("inherited-id");
+        ref.setComponent(new ParameterContextReferenceDTO());
+        ref.getComponent().setId("inherited-id");
+        ref.getComponent().setName("Inherited");
+        refs.add(ref);
+        dto.setInheritedParameterContexts(refs);
+
+        // Updating a provided parameter that is inherited is allowed
+        dao.verifyUpdate(dto, true);
+    }
+
+    @Test
+    public void testVerifyUpdateNonInheritedProvidedParameter() {
+        final ParameterContextDTO dto = new ParameterContextDTO();
+        dto.setId("id");
+        dto.setName("Context");
+        final Set<ParameterEntity> parameters = new HashSet<>();
+        final ParameterEntity parameter = new ParameterEntity();
+        parameter.setCanWrite(true);
+        final ParameterDTO parameterDto = new ParameterDTO();
+        parameterDto.setProvided(true);
+        parameterDto.setName("param");
+        parameterDto.setValue("value");
+        parameterDto.setInherited(false);
+        parameter.setParameter(parameterDto);
+        parameters.add(parameter);
+        dto.setParameters(parameters);
+
+        final List<ParameterContextReferenceEntity> refs = new ArrayList<>();
+        final ParameterContextReferenceEntity ref = new 
ParameterContextReferenceEntity();
+        ref.setId("inherited-id");
+        ref.setComponent(new ParameterContextReferenceDTO());
+        ref.getComponent().setId("inherited-id");
+        ref.getComponent().setName("Inherited");
+        refs.add(ref);
+        dto.setInheritedParameterContexts(refs);
+
+
+        // Updating a provided parameter that is not inherited should fail
+        assertThrows(IllegalArgumentException.class, () -> 
dao.verifyUpdate(dto, true));
+    }
+}
\ No newline at end of file

Reply via email to