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 42910e80d1 NIFI-11658 Streamline using single Parameter Context for
nested PGs
42910e80d1 is described below
commit 42910e80d1d0a71c8f3de51bdd5c6dd0183da26d
Author: Timea Barna <[email protected]>
AuthorDate: Fri Jun 2 10:58:44 2023 +0200
NIFI-11658 Streamline using single Parameter Context for nested PGs
This closes #7353
Co-authored-by: Matt Gilman <[email protected]>
Signed-off-by: David Handermann <[email protected]>
---
.../nifi/web/api/entity/ProcessGroupEntity.java | 14 ++
.../web/api/entity/ProcessGroupUpdateStrategy.java | 22 +++
.../org/apache/nifi/web/NiFiServiceFacade.java | 10 +-
.../apache/nifi/web/StandardNiFiServiceFacade.java | 5 +-
.../apache/nifi/web/api/ProcessGroupResource.java | 149 +++++++++-----
.../org/apache/nifi/web/dao/ProcessGroupDAO.java | 4 +-
.../nifi/web/dao/impl/StandardProcessGroupDAO.java | 9 +-
.../nifi/web/api/TestProcessGroupResource.java | 43 +++-
.../nifi-framework/nifi-web/nifi-web-ui/pom.xml | 1 +
.../partials/canvas/new-process-group-dialog.jsp | 15 +-
.../canvas/process-group-configuration.jsp | 6 +
.../nifi-web-ui/src/main/webapp/css/canvas.css | 1 +
.../nifi-web-ui/src/main/webapp/css/common-ui.css | 2 +-
.../nifi-web-ui/src/main/webapp/css/main.css | 28 +--
.../main/webapp/css/new-process-group-dialog.css | 37 ++++
.../webapp/css/process-group-configuration.css | 19 +-
.../main/webapp/js/jquery/combo/jquery.combo.css | 4 +-
.../header/components/nf-ng-group-component.js | 217 ++++++++++++++-------
.../main/webapp/js/nf/canvas/nf-flow-version.js | 12 +-
.../js/nf/canvas/nf-process-group-configuration.js | 44 ++---
.../nifi-web-ui/src/main/webapp/js/nf/nf-common.js | 40 ++++
21 files changed, 475 insertions(+), 207 deletions(-)
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupEntity.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupEntity.java
index 1e726dc21d..671c448fba 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupEntity.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupEntity.java
@@ -56,6 +56,8 @@ public class ProcessGroupEntity extends ComponentEntity
implements Permissible<P
private ParameterContextReferenceEntity parameterContext;
+ private String processGroupUpdateStrategy;
+
/**
* The ProcessGroupDTO that is being serialized.
*
@@ -328,4 +330,16 @@ public class ProcessGroupEntity extends ComponentEntity
implements Permissible<P
public void setParameterContext(ParameterContextReferenceEntity
parameterContext) {
this.parameterContext = parameterContext;
}
+
+ @ApiModelProperty(
+ value = "Determines the process group update strategy",
+ allowableValues = "CURRENT_GROUP, CURRENT_GROUP_WITH_CHILDREN"
+ )
+ public String getProcessGroupUpdateStrategy() {
+ return processGroupUpdateStrategy;
+ }
+
+ public void setProcessGroupUpdateStrategy(String
processGroupUpdateStrategy) {
+ this.processGroupUpdateStrategy = processGroupUpdateStrategy;
+ }
}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupUpdateStrategy.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupUpdateStrategy.java
new file mode 100644
index 0000000000..aea19be6ea
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupUpdateStrategy.java
@@ -0,0 +1,22 @@
+/*
+ * 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.api.entity;
+
+public enum ProcessGroupUpdateStrategy {
+ CURRENT_GROUP,
+ CURRENT_GROUP_WITH_CHILDREN
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
index 61164dba62..ef7821c460 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
@@ -90,7 +90,6 @@ import org.apache.nifi.web.api.entity.AccessPolicyEntity;
import org.apache.nifi.web.api.entity.ActionEntity;
import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity;
import org.apache.nifi.web.api.entity.AffectedComponentEntity;
-import org.apache.nifi.web.api.entity.FlowRegistryBucketEntity;
import org.apache.nifi.web.api.entity.BulletinEntity;
import org.apache.nifi.web.api.entity.ComponentValidationResultEntity;
import org.apache.nifi.web.api.entity.ConfigurationAnalysisEntity;
@@ -105,6 +104,8 @@ import org.apache.nifi.web.api.entity.CurrentUserEntity;
import org.apache.nifi.web.api.entity.FlowComparisonEntity;
import org.apache.nifi.web.api.entity.FlowConfigurationEntity;
import org.apache.nifi.web.api.entity.FlowEntity;
+import org.apache.nifi.web.api.entity.FlowRegistryBucketEntity;
+import org.apache.nifi.web.api.entity.FlowRegistryClientEntity;
import org.apache.nifi.web.api.entity.FunnelEntity;
import org.apache.nifi.web.api.entity.LabelEntity;
import org.apache.nifi.web.api.entity.ParameterContextEntity;
@@ -115,11 +116,11 @@ import org.apache.nifi.web.api.entity.PortStatusEntity;
import org.apache.nifi.web.api.entity.ProcessGroupEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupUpdateStrategy;
import org.apache.nifi.web.api.entity.ProcessorDiagnosticsEntity;
import org.apache.nifi.web.api.entity.ProcessorEntity;
import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
import org.apache.nifi.web.api.entity.ProcessorsRunStatusDetailsEntity;
-import org.apache.nifi.web.api.entity.FlowRegistryClientEntity;
import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity;
import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
@@ -1209,9 +1210,10 @@ public interface NiFiServiceFacade {
* Gets all process groups in the specified parent group.
*
* @param parentGroupId The id of the parent group
- * @return process group
+ * @param processGroupUpdateStrategy if process groups with its child
groups should be included
+ * @return List of process groups
*/
- Set<ProcessGroupEntity> getProcessGroups(String parentGroupId);
+ Set<ProcessGroupEntity> getProcessGroups(String parentGroupId,
ProcessGroupUpdateStrategy processGroupUpdateStrategy);
/**
* Verifies the contents of the specified process group can be scheduled
or unscheduled.
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index 55ed34be5a..09038d0707 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -300,6 +300,7 @@ import org.apache.nifi.web.api.entity.ProcessGroupEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
import org.apache.nifi.web.api.entity.ProcessGroupStatusSnapshotEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupUpdateStrategy;
import org.apache.nifi.web.api.entity.ProcessorDiagnosticsEntity;
import org.apache.nifi.web.api.entity.ProcessorEntity;
import org.apache.nifi.web.api.entity.ProcessorRunStatusDetailsEntity;
@@ -4542,8 +4543,8 @@ public class StandardNiFiServiceFacade implements
NiFiServiceFacade {
}
@Override
- public Set<ProcessGroupEntity> getProcessGroups(final String
parentGroupId) {
- final Set<ProcessGroup> groups =
processGroupDAO.getProcessGroups(parentGroupId);
+ public Set<ProcessGroupEntity> getProcessGroups(final String
parentGroupId, final ProcessGroupUpdateStrategy processGroupUpdateStrategy) {
+ final Set<ProcessGroup> groups =
processGroupDAO.getProcessGroups(parentGroupId, processGroupUpdateStrategy);
return groups.stream()
.map(group -> createProcessGroupEntity(group))
.collect(Collectors.toSet());
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
index a783087e60..f674a540b3 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
@@ -111,6 +111,7 @@ import org.apache.nifi.web.api.entity.PortEntity;
import org.apache.nifi.web.api.entity.ProcessGroupEntity;
import org.apache.nifi.web.api.entity.ProcessGroupImportEntity;
import org.apache.nifi.web.api.entity.ProcessGroupReplaceRequestEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupUpdateStrategy;
import org.apache.nifi.web.api.entity.ProcessGroupUploadEntity;
import org.apache.nifi.web.api.entity.ProcessGroupsEntity;
import org.apache.nifi.web.api.entity.ProcessorEntity;
@@ -169,6 +170,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -480,7 +482,7 @@ public class ProcessGroupResource extends
FlowUpdateResource<ProcessGroupImportE
* @param httpServletRequest request
* @param id The id of the process group.
* @param requestProcessGroupEntity A processGroupEntity.
- * @return A processGroupEntity.
+ * @return A processGroupEntity or the parent processGroupEntity for
recursive requests.
*/
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@@ -536,6 +538,15 @@ public class ProcessGroupResource extends
FlowUpdateResource<ProcessGroupImportE
}
}
+ final String processGroupUpdateStrategy =
requestProcessGroupEntity.getProcessGroupUpdateStrategy();
+ final ProcessGroupUpdateStrategy updateStrategy;
+ if (processGroupUpdateStrategy == null) {
+ updateStrategy = ProcessGroupUpdateStrategy.CURRENT_GROUP;
+ } else {
+ updateStrategy =
ProcessGroupUpdateStrategy.valueOf(processGroupUpdateStrategy);
+ }
+
+
if (isReplicateRequest()) {
return replicate(HttpMethod.PUT, requestProcessGroupEntity);
} else if (isDisconnectedFromCluster()) {
@@ -543,68 +554,100 @@ public class ProcessGroupResource extends
FlowUpdateResource<ProcessGroupImportE
}
// handle expects request (usually from the cluster manager)
- final Revision requestRevision =
getRevision(requestProcessGroupEntity, id);
+ final ParameterContextReferenceEntity requestParamContext =
requestProcessGroupDTO.getParameterContext();
+ final String requestGroupId = requestProcessGroupDTO.getId();
+ final Map<ProcessGroupEntity, Revision> updatableProcessGroups = new
HashMap<>();
+
+ updatableProcessGroups.put(requestProcessGroupEntity,
getRevision(requestProcessGroupEntity, requestGroupId));
+
+ if (updateStrategy ==
ProcessGroupUpdateStrategy.CURRENT_GROUP_WITH_CHILDREN) {
+ for (ProcessGroupEntity processGroupEntity :
serviceFacade.getProcessGroups(requestGroupId, updateStrategy)) {
+ final ProcessGroupDTO processGroupDTO =
processGroupEntity.getComponent();
+ final String processGroupId = processGroupDTO == null ?
processGroupEntity.getId() : processGroupDTO.getId();
+ if (processGroupDTO != null) {
+ processGroupDTO.setParameterContext(requestParamContext);
+ }
+ updatableProcessGroups.put(processGroupEntity,
getRevision(processGroupEntity, processGroupId));
+ }
+ }
+
return withWriteLock(
serviceFacade,
requestProcessGroupEntity,
- requestRevision,
+ new HashSet<>(updatableProcessGroups.values()),
lookup -> {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
- Authorizable authorizable =
lookup.getProcessGroup(id).getAuthorizable();
- authorizable.authorize(authorizer, RequestAction.WRITE,
user);
-
- // Ensure that user has READ permission on current
Parameter Context (if any) because user is un-binding.
- final ParameterContextReferenceEntity
referencedParamContext = requestProcessGroupDTO.getParameterContext();
- if (referencedParamContext != null) {
- // Lookup the current Parameter Context and determine
whether or not the Parameter Context is changing
- final String groupId = requestProcessGroupDTO.getId();
- final ProcessGroupEntity currentGroupEntity =
serviceFacade.getProcessGroup(groupId);
- final ProcessGroupDTO groupDto =
currentGroupEntity.getComponent();
- final ParameterContextReferenceEntity
currentParamContext = groupDto.getParameterContext();
- final String currentParamContextId =
currentParamContext == null ? null : currentParamContext.getId();
- final boolean parameterContextChanging =
!Objects.equals(referencedParamContext.getId(), currentParamContextId);
-
- // If Parameter Context is changing...
- if (parameterContextChanging) {
- // In order to bind to a Parameter Context, the
user must have the READ policy to that Parameter Context.
- if (referencedParamContext.getId() != null) {
-
lookup.getParameterContext(referencedParamContext.getId()).authorize(authorizer,
RequestAction.READ, user);
- }
-
- // If currently referencing a Parameter Context,
we must authorize that the user has READ permissions on the Parameter Context
in order to un-bind to it.
- if (currentParamContextId != null) {
-
lookup.getParameterContext(currentParamContextId).authorize(authorizer,
RequestAction.READ, user);
- }
-
- // Because the user will be changing the behavior
of any component in this group that is currently referencing any Parameter, we
must ensure that the user has
- // both READ and WRITE policies for each of those
components.
- for (final AffectedComponentEntity
affectedComponentEntity :
serviceFacade.getProcessorsReferencingParameter(groupId)) {
- final Authorizable processorAuthorizable =
lookup.getProcessor(affectedComponentEntity.getId()).getAuthorizable();
- processorAuthorizable.authorize(authorizer,
RequestAction.READ, user);
- processorAuthorizable.authorize(authorizer,
RequestAction.WRITE, user);
- }
-
- for (final AffectedComponentEntity
affectedComponentEntity :
serviceFacade.getControllerServicesReferencingParameter(groupId)) {
- final Authorizable serviceAuthorizable =
lookup.getControllerService(affectedComponentEntity.getId()).getAuthorizable();
- serviceAuthorizable.authorize(authorizer,
RequestAction.READ, user);
- serviceAuthorizable.authorize(authorizer,
RequestAction.WRITE, user);
+ for (final ProcessGroupEntity updatableGroupEntity :
updatableProcessGroups.keySet()) {
+ final ProcessGroupDTO updatableGroupDto =
updatableGroupEntity.getComponent();
+ final String groupId = updatableGroupDto == null ?
updatableGroupEntity.getId() : updatableGroupDto.getId();
+
+ Authorizable authorizable =
lookup.getProcessGroup(groupId).getAuthorizable();
+ authorizable.authorize(authorizer,
RequestAction.WRITE, user);
+
+ // Ensure that user has READ permission on current
Parameter Context (if any) because user is un-binding.
+ final ParameterContextReferenceEntity
referencedParamContext = updatableGroupDto.getParameterContext();
+ if (referencedParamContext != null) {
+ // Lookup the current Parameter Context and
determine whether or not the Parameter Context is changing
+ final ProcessGroupEntity currentGroupEntity =
serviceFacade.getProcessGroup(groupId);
+ final ProcessGroupDTO groupDto =
currentGroupEntity.getComponent();
+ final ParameterContextReferenceEntity
currentParamContext = groupDto.getParameterContext();
+ final String currentParamContextId =
currentParamContext == null ? null : currentParamContext.getId();
+ final boolean parameterContextChanging =
!Objects.equals(referencedParamContext.getId(), currentParamContextId);
+
+ // If Parameter Context is changing...
+ if (parameterContextChanging) {
+ // In order to bind to a Parameter Context,
the user must have the READ policy to that Parameter Context.
+ if (referencedParamContext.getId() != null) {
+
lookup.getParameterContext(referencedParamContext.getId()).authorize(authorizer,
RequestAction.READ, user);
+ }
+
+ // If currently referencing a Parameter
Context, we must authorize that the user has READ permissions on the Parameter
Context in order to un-bind to it.
+ if (currentParamContextId != null) {
+
lookup.getParameterContext(currentParamContextId).authorize(authorizer,
RequestAction.READ, user);
+ }
+
+ // Because the user will be changing the
behavior of any component in this group that is currently referencing any
Parameter, we must ensure that the user has
+ // both READ and WRITE policies for each of
those components.
+ for (final AffectedComponentEntity
affectedComponentEntity :
serviceFacade.getProcessorsReferencingParameter(groupId)) {
+ final Authorizable processorAuthorizable =
lookup.getProcessor(affectedComponentEntity.getId()).getAuthorizable();
+
processorAuthorizable.authorize(authorizer, RequestAction.READ, user);
+
processorAuthorizable.authorize(authorizer, RequestAction.WRITE, user);
+ }
+
+ for (final AffectedComponentEntity
affectedComponentEntity :
serviceFacade.getControllerServicesReferencingParameter(groupId)) {
+ final Authorizable serviceAuthorizable =
lookup.getControllerService(affectedComponentEntity.getId()).getAuthorizable();
+ serviceAuthorizable.authorize(authorizer,
RequestAction.READ, user);
+ serviceAuthorizable.authorize(authorizer,
RequestAction.WRITE, user);
+ }
}
}
}
},
- () ->
serviceFacade.verifyUpdateProcessGroup(requestProcessGroupDTO),
- (revision, processGroupEntity) -> {
- // update the process group
- final ProcessGroupEntity entity =
serviceFacade.updateProcessGroup(revision, processGroupEntity.getComponent());
- populateRemainingProcessGroupEntityContent(entity);
-
- // prune response as necessary
- if (entity.getComponent() != null) {
- entity.getComponent().setContents(null);
+ () -> {
+ for (final ProcessGroupEntity entity :
updatableProcessGroups.keySet()) {
+
serviceFacade.verifyUpdateProcessGroup(entity.getComponent());
}
-
- return generateOkResponse(entity).build();
+ },
+ (revisions, entities) -> {
+ ProcessGroupEntity responseEntity = null;
+ for (Map.Entry<ProcessGroupEntity, Revision> entry :
updatableProcessGroups.entrySet()) {
+ // update the process group
+ final Revision revision = entry.getValue();
+ final ProcessGroupDTO groupDTO =
entry.getKey().getComponent();
+ final ProcessGroupEntity entity =
serviceFacade.updateProcessGroup(revision, groupDTO);
+
+ if (requestGroupId.equals(entity.getId())) {
+ responseEntity = entity;
+
populateRemainingProcessGroupEntityContent(responseEntity);
+
+ // prune response as necessary
+ if (responseEntity.getComponent() != null) {
+
responseEntity.getComponent().setContents(null);
+ }
+ }
+ }
+ return generateOkResponse(responseEntity).build();
}
);
}
@@ -2175,7 +2218,7 @@ public class ProcessGroupResource extends
FlowUpdateResource<ProcessGroupImportE
});
// get the process groups
- final Set<ProcessGroupEntity> entities =
serviceFacade.getProcessGroups(groupId);
+ final Set<ProcessGroupEntity> entities =
serviceFacade.getProcessGroups(groupId,
ProcessGroupUpdateStrategy.CURRENT_GROUP);
// always prune the contents
for (final ProcessGroupEntity entity : entities) {
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ProcessGroupDAO.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ProcessGroupDAO.java
index 47abf91b66..7b2db52019 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ProcessGroupDAO.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ProcessGroupDAO.java
@@ -24,6 +24,7 @@ import org.apache.nifi.groups.ProcessGroup;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.VariableRegistryDTO;
import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
+import org.apache.nifi.web.api.entity.ProcessGroupUpdateStrategy;
import java.util.Collection;
import java.util.Map;
@@ -59,9 +60,10 @@ public interface ProcessGroupDAO {
* Gets all of the process groups.
*
* @param parentGroupId The parent group id
+ * @param processGroupUpdateStrategy if process groups with its child
groups should be included
* @return The process groups
*/
- Set<ProcessGroup> getProcessGroups(String parentGroupId);
+ Set<ProcessGroup> getProcessGroups(String parentGroupId,
ProcessGroupUpdateStrategy processGroupUpdateStrategy);
/**
* Verifies the specified process group can be modified.
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/StandardProcessGroupDAO.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardProcessGroupDAO.java
index ecfe35e2a2..be93fa82ff 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardProcessGroupDAO.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardProcessGroupDAO.java
@@ -45,6 +45,7 @@ import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.VariableRegistryDTO;
import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
import org.apache.nifi.web.api.entity.ParameterContextReferenceEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupUpdateStrategy;
import org.apache.nifi.web.api.entity.VariableEntity;
import org.apache.nifi.web.dao.ProcessGroupDAO;
@@ -136,9 +137,13 @@ public class StandardProcessGroupDAO extends ComponentDAO
implements ProcessGrou
}
@Override
- public Set<ProcessGroup> getProcessGroups(String parentGroupId) {
+ public Set<ProcessGroup> getProcessGroups(final String parentGroupId,
final ProcessGroupUpdateStrategy processGroupUpdateStrategy) {
ProcessGroup group = locateProcessGroup(flowController, parentGroupId);
- return group.getProcessGroups();
+ if (processGroupUpdateStrategy ==
ProcessGroupUpdateStrategy.CURRENT_GROUP_WITH_CHILDREN) {
+ return new HashSet<>(group.findAllProcessGroups());
+ } else {
+ return group.getProcessGroups();
+ }
}
@Override
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestProcessGroupResource.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestProcessGroupResource.java
index f9dd7c5460..986c29234d 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestProcessGroupResource.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestProcessGroupResource.java
@@ -16,10 +16,16 @@
*/
package org.apache.nifi.web.api;
+import org.apache.nifi.authorization.AccessDeniedException;
+import org.apache.nifi.authorization.AuthorizeAccess;
import org.apache.nifi.flow.VersionedProcessGroup;
import org.apache.nifi.registry.flow.RegisteredFlowSnapshot;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.NiFiServiceFacade;
+import org.apache.nifi.web.api.dto.ProcessGroupDTO;
+import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.entity.ProcessGroupEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupUpdateStrategy;
import org.apache.nifi.web.api.dto.FlowSnippetDTO;
import org.apache.nifi.web.api.dto.TemplateDTO;
import org.apache.nifi.web.api.entity.TemplateEntity;
@@ -41,10 +47,14 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.junit.jupiter.api.Assertions.assertFalse;
@ExtendWith(MockitoExtension.class)
public class TestProcessGroupResource {
@@ -110,4 +120,33 @@ public class TestProcessGroupResource {
assertFalse(Pattern.compile("<script.*>").matcher(response.getEntity().toString()).find());
});
}
+ @Test
+ public void testUpdateProcessGroupNotExecuted_WhenUserNotAuthorized(@Mock
HttpServletRequest httpServletRequest, @Mock NiFiProperties properties) {
+ when(httpServletRequest.getHeader(any())).thenReturn(null);
+ when(properties.isNode()).thenReturn(Boolean.FALSE);
+
+ processGroupResource.properties = properties;
+ processGroupResource.serviceFacade = serviceFacade;
+ processGroupResource.httpServletRequest = httpServletRequest;
+
+ final ProcessGroupEntity processGroupEntity = new ProcessGroupEntity();
+ final ProcessGroupDTO groupDTO = new ProcessGroupDTO();
+ groupDTO.setId("id");
+ groupDTO.setName("name");
+ final RevisionDTO revisionDTO = new RevisionDTO();
+ revisionDTO.setClientId("clientId");
+ revisionDTO.setVersion(1L);
+
+ processGroupEntity.setRevision(revisionDTO);
+
processGroupEntity.setProcessGroupUpdateStrategy(ProcessGroupUpdateStrategy.CURRENT_GROUP.name());
+ processGroupEntity.setComponent(groupDTO);
+
+
doThrow(AccessDeniedException.class).when(serviceFacade).authorizeAccess(any(AuthorizeAccess.class));
+
+ assertThrows(AccessDeniedException.class, () ->
+ processGroupResource.updateProcessGroup(httpServletRequest,
"id", processGroupEntity));
+
+ verify(serviceFacade, never()).verifyUpdateProcessGroup(any());
+ verify(serviceFacade, never()).updateProcessGroup(any(), any());
+ }
}
\ No newline at end of file
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
index 73a4c67fb6..d4ffbc8d72 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
@@ -741,6 +741,7 @@
<include>${staging.dir}/css/processor-configuration.css</include>
<include>${staging.dir}/css/processor-details.css</include>
<include>${staging.dir}/css/process-group-configuration.css</include>
+
<include>${staging.dir}/css/new-process-group-dialog.css</include>
<include>${staging.dir}/css/policy-management.css</include>
<include>${staging.dir}/css/remote-process-group-configuration.css</include>
<include>${staging.dir}/css/port-configuration.css</include>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-process-group-dialog.jsp
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-process-group-dialog.jsp
index 4ae9bcc862..b0d2555823 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-process-group-dialog.jsp
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-process-group-dialog.jsp
@@ -28,6 +28,13 @@
</div>
<input id="new-process-group-name" type="text"
placeholder="Enter a name or select a file to upload"/>
</div>
+ </div>
+ <div class="setting">
+ <div class="setting-name">Parameter Context</div>
+ <div class="setting-field">
+ <div id="new-pg-parameter-context-combo"></div>
+ <div id="parameters-from-uploaded-flow">Parameters will be
imported from the uploaded Flow Definition.</div>
+ </div>
</div>
<div id="file-cancel-button-container">
<button class="icon" id="file-cancel-button" aria-hidden="true"
title="Cancel the selected file">
@@ -45,10 +52,4 @@
</div>
</div>
</div>
- <div class="setting">
- <span id="import-process-group-link" class="link" title="Import a flow
from a registry">
- <i class="fa fa-cloud-download" aria-hidden="true"
style="margin-left: 5px; margin-right: 5px;"></i>
- Import from Registry...
- </span>
- </div>
-</div>
\ No newline at end of file
+</div>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/process-group-configuration.jsp
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/process-group-configuration.jsp
index 509a3d9677..d3e5c25ee9 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/process-group-configuration.jsp
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/process-group-configuration.jsp
@@ -40,6 +40,12 @@
<div class="setting-name">Process group parameter
context</div>
<div class="editable setting-field">
<div
id="process-group-parameter-context-combo"></div>
+ <div id="parameter-contexts-recursive-container">
+ <div id="parameter-contexts-recursive"
class="nf-checkbox checkbox-unchecked"></div>
+ <div class="nf-checkbox-label">Apply
recursively</div>
+ <div class="fa fa-question-circle" alt="Info"
title="When checked Parameter Context will be applied to the Process Group and
all the embedded Process Groups recursively, if the user has the proper
permissions on all the respective components. If the user does not have the
proper permissions on any embedded Process Group, then the Parameter Context
will not be applied for any components."></div>
+ </div>
+ <div class="clear"></div>
</div>
<div class="read-only setting-field">
<span
id="read-only-process-group-parameter-context" class="unset">Unauthorized</span>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
index a9de76f303..ec148daec0 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
@@ -37,6 +37,7 @@
@import url(new-reporting-task-dialog.css);
@import url(new-parameter-provider-dialog.css);
@import url(new-parameter-context-dialog.css);
+@import url(new-process-group-dialog.css);
@import url(graph.css);
@import url(header.css);
@import url(main.css);
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/common-ui.css
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/common-ui.css
index ef56a9b454..f07bfd38d6 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/common-ui.css
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/common-ui.css
@@ -484,7 +484,7 @@ div.button-icon span {
div.button-icon {
float: left !important;
- margin-left: 20px;
+ margin-left: 0;
font-size: 18px !important;
}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css
index 8f0500fd85..8290d0a4f3 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css
@@ -385,32 +385,6 @@ span.details-title {
width: 300px;
}
-span#import-process-group-link.link:focus {
- outline: none;
-}
-
-span#import-process-group-link.link {
- position: relative;
- top: 164px;
- left: 20px;
- color: #004849; /*link-color*/
- font-weight: normal;
- display: inline-block;
- border-bottom: 1px solid #CCDADB;
- font-size: 13px;
- font-family: Roboto;
- z-index: 1;
-}
-
-span#import-process-group-link.link-over {
- border-bottom: 1px solid #004849;
-}
-
-span#import-process-group-link.link-bold {
- font-weight: bold;
- border-bottom: none;
-}
-
#file-cancel-button {
position: absolute;
width: 0px;
@@ -421,4 +395,4 @@ span#import-process-group-link.link-bold {
background-color: transparent;
padding: 0px;
margin-top: 16px;
-}
\ No newline at end of file
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-process-group-dialog.css
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-process-group-dialog.css
new file mode 100644
index 0000000000..a245922015
--- /dev/null
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-process-group-dialog.css
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+/*
+ New process group dialog.
+*/
+
+#new-process-group-dialog {
+ min-height:320px;
+ height: 320px;
+ width: 540px;
+ min-width: 500px;
+}
+
+div.fa-cloud-download.button-icon {
+ width: 160px;
+}
+
+#parameters-from-uploaded-flow {
+ color: #888;
+ font-weight: 400;
+ display: none;
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/process-group-configuration.css
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/process-group-configuration.css
index 20cfaec23e..c4566ea9a0 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/process-group-configuration.css
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/process-group-configuration.css
@@ -83,6 +83,21 @@
#process-group-parameter-context-combo {
width: 328px;
+ float: left;
+}
+
+#parameter-contexts-recursive-container {
+ float: left;
+ margin-left: 10px;
+}
+
+#parameter-contexts-recursive-container > div {
+ float: left;
+ line-height: 30px;
+}
+
+#parameter-contexts-recursive {
+ margin-top: 8px;
}
#process-group-flowfile-concurrency-combo {
@@ -119,8 +134,4 @@
#upload-process-group-link {
float: right;
-}
-
-#process-group-log-to-own-file-combo {
- width: 328px;
}
\ No newline at end of file
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.css
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.css
index 31c1d39714..4361d229f8 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.css
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.css
@@ -55,7 +55,7 @@
.combo-arrow {
float: right;
width: 10px;
- margin-top: 8px;
+ margin-top: 4px;
}
.combo-text {
@@ -111,4 +111,4 @@ div.combo-nifi-tooltip {
div.combo-button-normal {
background-color: #eaeef0;
-}
\ No newline at end of file
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-group-component.js
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-group-component.js
index bdf4952e93..42d90c6c48 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-group-component.js
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-group-component.js
@@ -26,10 +26,11 @@
'nf.Graph',
'nf.CanvasUtils',
'nf.ErrorHandler',
+ 'nf.FlowVersion',
'nf.Common',
'nf.Dialog'],
- function ($, nfClient, nfBirdseye, nfStorage, nfGraph,
nfCanvasUtils, nfErrorHandler, nfCommon, nfDialog) {
- return (nf.ng.GroupComponent = factory($, nfClient,
nfBirdseye, nfStorage, nfGraph, nfCanvasUtils, nfErrorHandler, nfCommon,
nfDialog));
+ function ($, nfClient, nfBirdseye, nfStorage, nfGraph,
nfCanvasUtils, nfErrorHandler, nfFlowVersion, nfCommon, nfDialog) {
+ return (nf.ng.GroupComponent = factory($, nfClient,
nfBirdseye, nfStorage, nfGraph, nfCanvasUtils, nfErrorHandler, nfFlowVersion,
nfCommon, nfDialog));
});
} else if (typeof exports === 'object' && typeof module === 'object') {
module.exports = (nf.ng.GroupComponent =
@@ -40,6 +41,7 @@
require('nf.Graph'),
require('nf.CanvasUtils'),
require('nf.ErrorHandler'),
+ require('nf.FlowVersion'),
require('nf.Common'),
require('nf.Dialog')));
} else {
@@ -50,10 +52,11 @@
root.nf.Graph,
root.nf.CanvasUtils,
root.nf.ErrorHandler,
+ root.nf.FlowVersion,
root.nf.Common,
root.nf.Dialog);
}
-}(this, function ($, nfClient, nfBirdseye, nfStorage, nfGraph, nfCanvasUtils,
nfErrorHandler, nfCommon, nfDialog) {
+}(this, function ($, nfClient, nfBirdseye, nfStorage, nfGraph, nfCanvasUtils,
nfErrorHandler, nfFlowVersion, nfCommon, nfDialog) {
'use strict';
return function (serviceProvider) {
@@ -63,13 +66,19 @@
var cancelFileBtn = $('#file-cancel-button');
var submitFileContainer = $('#submit-file-container');
+ var noParameterContext = {
+ text: 'No parameter context',
+ value: null
+ };
+
/**
* Create the group and add to the graph.
*
* @argument {string} groupName The name of the group.
* @argument {object} pt The point that the group was dropped.
+ * @argument {string} parameterContextId Option parameter context
reference
*/
- var createGroup = function (groupName, pt) {
+ var createGroup = function (groupName, pt, parameterContextId) {
var processGroupEntity = {
'revision': nfClient.getRevision({
'revision': {
@@ -86,6 +95,13 @@
}
};
+ // include the parameter context if specified
+ if (nf.Common.isDefinedAndNotNull(parameterContextId)) {
+ processGroupEntity.component.parameterContext = {
+ 'id': parameterContextId
+ };
+ }
+
// create a new processor of the defined type
return $.ajax({
type: 'POST',
@@ -127,6 +143,50 @@
return filepath.replace(/^.*[\\\/]/, '').replace(/\..*/, '');
};
+ var setParameterContextOptions = function () {
+ return new $.Deferred(function (deferred) {
+ $.ajax({
+ type: 'GET',
+ url: '../nifi-api/flow/parameter-contexts',
+ dataType: 'json'
+ }).done(function (response) {
+ var selectedOption = noParameterContext;
+ var parameterContextOptions = [noParameterContext];
+ var parentParameterContext =
nf.CanvasUtils.getParameterContext();
+
+ // prepare the options
+ var sortedParameterContexts =
nfCommon.sortParameterContextsAlphabeticallyBasedOnAuthorization(response.parameterContexts);
+ sortedParameterContexts.forEach(function
(parameterContext) {
+ if (parameterContext.permissions.canRead) {
+ var option = {
+ text: parameterContext.component.name,
+ value: parameterContext.id,
+ description:
parameterContext.component.description
+ };
+
+ if
(nfCommon.isDefinedAndNotNull(parentParameterContext) &&
parentParameterContext.id === parameterContext.id) {
+ selectedOption = option;
+ }
+
+ parameterContextOptions.push(option);
+ }
+ });
+
+ // set the combo options
+ $('#new-pg-parameter-context-combo').combo({
+ selectedOption: {
+ value: selectedOption.value
+ },
+ options: parameterContextOptions
+ });
+
+ deferred.resolve();
+ }).fail(function (xhr, status, error) {
+ deferred.reject(xhr, status, error);
+ }).fail(nfErrorHandler.handleAjaxError);
+ }).promise();
+ };
+
function GroupComponent() {
this.icon = 'icon icon-group';
@@ -170,8 +230,13 @@
selectedFilename.text('');
uploadFileField.val('');
self.fileToBeUploaded = null;
+
+ // reset the parameter context fields
+ $('#parameters-from-uploaded-flow').hide();
+ $('#new-pg-parameter-context-combo').show();
}
+
self.fileForm = $('#file-upload-form').ajaxForm({
url: '../nifi-api/process-groups/',
dataType: 'json',
@@ -235,6 +300,10 @@
processGroupDialog.modal('refreshButtons');
}
+ // update the parameter context
+ $('#parameters-from-uploaded-flow').show();
+ $('#new-pg-parameter-context-combo').hide();
+
cancelFileBtn.show();
});
@@ -354,6 +423,8 @@
// get the name of the group and clear the textfield
var groupName = $('#new-process-group-name').val();
+ var parameterContextId =
$('#new-pg-parameter-context-combo').combo('getSelectedOption').value
+
// ensure the group name is specified
if (nfCommon.isBlank(groupName)) {
nfDialog.showOkDialog({
@@ -437,7 +508,7 @@
self.modal.fileForm.submit();
} else {
// create the group and resolve the deferred
accordingly
- createGroup(groupName, pt).done(function
(response) {
+ createGroup(groupName, pt,
parameterContextId).done(function (response) {
deferred.resolve(response.component);
}).fail(function () {
deferred.reject();
@@ -449,74 +520,88 @@
}
};
- groupComponent.modal.update('setButtonModel', [{
- buttonText: 'Add',
- color: {
- base: '#728E9B',
- hover: '#004849',
- text: '#ffffff'
- },
- disabled: function () {
- if
(nfCommon.isBlank($('#new-process-group-name').val())) {
- return true;
- } else {
- return false;
- }
- },
- handler: {
- click: addGroup
- }
- },
- {
- buttonText: 'Cancel',
- color: {
- base: '#E3E8EB',
- hover: '#C7D2D7',
- text: '#004849'
+ // set the parameter context options and then proceed with
showing the new pg dialog
+ setParameterContextOptions().done(function () {
+ var buttonModel = [{
+ buttonText: 'Add',
+ color: {
+ base: '#728E9B',
+ hover: '#004849',
+ text: '#ffffff'
+ },
+ disabled: function () {
+ if
(nfCommon.isBlank($('#new-process-group-name').val())) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+ handler: {
+ click: addGroup
+ }
},
- handler: {
- click: function () {
- // reject the deferred
- deferred.reject();
-
- // close the dialog
- groupComponent.modal.hide();
+ {
+ buttonText: 'Cancel',
+ color: {
+ base: '#E3E8EB',
+ hover: '#C7D2D7',
+ text: '#004849'
+ },
+ handler: {
+ click: function () {
+ // reject the deferred
+ deferred.reject();
+
+ // close the dialog
+ groupComponent.modal.hide();
+ }
}
- }
- }]);
-
- // hide the selected file to upload title
- submitFileContainer.hide();
+ }];
+
+ if (showImportLink === true &&
nfCommon.canVersionFlows()) {
+ buttonModel.push({
+ buttonText: 'Import from Registry',
+ clazz: 'fa fa-cloud-download button-icon',
+ color: {
+ base: '#E3E8EB',
+ hover: '#C7D2D7',
+ text: '#004849'
+ },
+ handler: {
+ click: function () {
+ nfFlowVersion.showImportFlowDialog();
+ }
+ }
+ });
+ }
- // hide file cancel button
- cancelFileBtn.hide();
+ // set the button model
+ groupComponent.modal.update('setButtonModel',
buttonModel);
- // determine if import from registry link should show
- var importProcessGroupLink =
$('#import-process-group-link');
+ // hide the selected file to upload title
+ submitFileContainer.hide();
- if (showImportLink === true && nfCommon.canVersionFlows())
{
- importProcessGroupLink.show();
- } else {
- importProcessGroupLink.hide();
- }
+ // hide file cancel button
+ cancelFileBtn.hide();
- // determine if Upload File button should show
- if (showUploadFileButton === true) {
- uploadFileBtn.show();
- } else {
- uploadFileBtn.hide();
- }
+ // determine if Upload File button should show
+ if (showUploadFileButton === true) {
+ uploadFileBtn.show();
+ } else {
+ uploadFileBtn.hide();
+ }
- // show the dialog
- groupComponent.modal.storePt(pt);
- groupComponent.modal.show();
+ // show the dialog
+ groupComponent.modal.storePt(pt);
+ groupComponent.modal.show();
- // set up the focus and key handlers
-
$('#new-process-group-name').focus().off('keyup').on('keyup', function (e) {
- var code = e.keyCode ? e.keyCode : e.which;
- if (code === $.ui.keyCode.ENTER) {
- addGroup();
- }
+ // set up the focus and key handlers
+
$('#new-process-group-name').focus().off('keyup').on('keyup', function (e) {
+ var code = e.keyCode ? e.keyCode : e.which;
+ if (code === $.ui.keyCode.ENTER) {
+ addGroup();
+ }
+ });
});
}).promise();
}
@@ -525,4 +610,4 @@
var groupComponent = new GroupComponent();
return groupComponent;
};
-}));
\ No newline at end of file
+}));
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
index 9588722569..1bf82bf56f 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
@@ -1784,17 +1784,19 @@
}
});
- // handle the click for the process group import
- $('#import-process-group-link').on('click', function() {
- showImportFlowVersionDialog();
- });
-
// initialize the import flow version table
initImportFlowVersionTable();
initLocalChangesTable($('#revert-local-changes-table'),
$('#revert-local-changes-filter'),
$('#displayed-revert-local-changes-entries'),
$('#total-revert-local-changes-entries'));
initLocalChangesTable($('#show-local-changes-table'),
$('#show-local-changes-filter'), $('#displayed-show-local-changes-entries'),
$('#total-show-local-changes-entries'));
},
+ /**
+ * Shows the import flow dialog.
+ */
+ showImportFlowDialog: function () {
+ showImportFlowVersionDialog();
+ },
+
/**
* Shows the flow version dialog.
*
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group-configuration.js
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group-configuration.js
index d2c9fb289c..d5fa88ddfc 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group-configuration.js
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group-configuration.js
@@ -93,6 +93,13 @@
*/
var saveConfiguration = function (version, groupId) {
// build the entity
+ var updateStrategy;
+ if ($('#parameter-contexts-recursive').hasClass('checkbox-unchecked'))
{
+ updateStrategy = 'CURRENT_GROUP';
+ } else {
+ updateStrategy = 'CURRENT_GROUP_WITH_CHILDREN';
+ };
+
var entity = {
'revision': nfClient.getRevision({
'revision': {
@@ -100,6 +107,7 @@
}
}),
'disconnectedNodeAcknowledged':
nfStorage.isDisconnectionAcknowledged(),
+ 'processGroupUpdateStrategy': updateStrategy,
'component': {
'id': groupId,
'name': $('#process-group-name').val(),
@@ -375,37 +383,7 @@
value: null
}];
- var authorizedParameterContexts =
parameterContexts.filter(function (parameterContext) {
- return parameterContext.permissions.canRead;
- });
-
- var unauthorizedParameterContexts =
parameterContexts.filter(function (parameterContext) {
- return !parameterContext.permissions.canRead;
- });
-
- //sort alphabetically
- var sortedAuthorizedParameterContexts =
authorizedParameterContexts.sort(function (a, b) {
- if (a.component.name < b.component.name) {
- return -1;
- }
- if (a.component.name > b.component.name) {
- return 1;
- }
- return 0;
- });
-
- //sort alphabetically
- var sortedUnauthorizedParameterContexts =
unauthorizedParameterContexts.sort(function (a, b) {
- if (a.id < b.id) {
- return -1;
- }
- if (a.id > b.id) {
- return 1;
- }
- return 0;
- });
-
- var sortedParameterContexts =
sortedAuthorizedParameterContexts.concat(sortedUnauthorizedParameterContexts);
+ var sortedParameterContexts =
nfCommon.sortParameterContextsAlphabeticallyBasedOnAuthorization(parameterContexts);
sortedParameterContexts.forEach(function (parameterContext) {
var option;
@@ -517,6 +495,10 @@
// initialize the parameter context combo
$('#process-group-parameter-context-combo').combo('destroy').combo(comboOptions);
+
+ // initialize parameter context recursive checkbox
+
$('#parameter-contexts-recursive').removeClass().addClass('nf-checkbox
checkbox-unchecked');
+
}).fail(nfErrorHandler.handleAjaxError);
};
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
index 758a19f8e7..3c6d0b1115 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
@@ -1855,6 +1855,46 @@
return true;
}
return false;
+ },
+
+ /**
+ * Sorts Parameter Contexts alphabetically for authorized items first,
following unauthorized items.
+ *
+ * @param Array
+ * @returns {Array}
+ */
+ sortParameterContextsAlphabeticallyBasedOnAuthorization: function
(parameterContexts) {
+ var authorizedParameterContexts =
parameterContexts.filter(function (parameterContext) {
+ return parameterContext.permissions.canRead;
+ });
+
+ var unauthorizedParameterContexts =
parameterContexts.filter(function (parameterContext) {
+ return !parameterContext.permissions.canRead;
+ });
+
+ // sort alphabetically
+ var sortedAuthorizedParameterContexts =
authorizedParameterContexts.sort(function (a, b) {
+ if (a.component.name < b.component.name) {
+ return -1;
+ }
+ if (a.component.name > b.component.name) {
+ return 1;
+ }
+ return 0;
+ });
+
+ // sort alphabetically
+ var sortedUnauthorizedParameterContexts =
unauthorizedParameterContexts.sort(function (a, b) {
+ if (a.id < b.id) {
+ return -1;
+ }
+ if (a.id > b.id) {
+ return 1;
+ }
+ return 0;
+ });
+
+ return
sortedAuthorizedParameterContexts.concat(sortedUnauthorizedParameterContexts);
}
};