mirror of https://github.com/apache/nifi.git
NIFI-11658 Streamline using single Parameter Context for nested PGs
This closes #7353 Co-authored-by: Matt Gilman <mcgilman@apache.org> Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
parent
a61add22c2
commit
42910e80d1
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
for (final ProcessGroupEntity updatableGroupEntity : updatableProcessGroups.keySet()) {
|
||||
final ProcessGroupDTO updatableGroupDto = updatableGroupEntity.getComponent();
|
||||
final String groupId = updatableGroupDto == null ? updatableGroupEntity.getId() : updatableGroupDto.getId();
|
||||
|
||||
// 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);
|
||||
Authorizable authorizable = lookup.getProcessGroup(groupId).getAuthorizable();
|
||||
authorizable.authorize(authorizer, RequestAction.WRITE, user);
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
// 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());
|
||||
}
|
||||
},
|
||||
(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);
|
||||
|
||||
return generateOkResponse(entity).build();
|
||||
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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
</div>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -484,7 +484,7 @@ div.button-icon span {
|
|||
|
||||
div.button-icon {
|
||||
float: left !important;
|
||||
margin-left: 20px;
|
||||
margin-left: 0;
|
||||
font-size: 18px !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
},
|
||||
handler: {
|
||||
click: function () {
|
||||
// reject the deferred
|
||||
deferred.reject();
|
||||
|
||||
// close the dialog
|
||||
groupComponent.modal.hide();
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}]);
|
||||
},
|
||||
{
|
||||
buttonText: 'Cancel',
|
||||
color: {
|
||||
base: '#E3E8EB',
|
||||
hover: '#C7D2D7',
|
||||
text: '#004849'
|
||||
},
|
||||
handler: {
|
||||
click: function () {
|
||||
// reject the deferred
|
||||
deferred.reject();
|
||||
|
||||
// hide the selected file to upload title
|
||||
submitFileContainer.hide();
|
||||
// close the dialog
|
||||
groupComponent.modal.hide();
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
// hide file cancel button
|
||||
cancelFileBtn.hide();
|
||||
|
||||
// determine if import from registry link should show
|
||||
var importProcessGroupLink = $('#import-process-group-link');
|
||||
|
||||
if (showImportLink === true && nfCommon.canVersionFlows()) {
|
||||
importProcessGroupLink.show();
|
||||
} else {
|
||||
importProcessGroupLink.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();
|
||||
|
||||
// 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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// set the button model
|
||||
groupComponent.modal.update('setButtonModel', buttonModel);
|
||||
|
||||
// hide the selected file to upload title
|
||||
submitFileContainer.hide();
|
||||
|
||||
// hide file cancel button
|
||||
cancelFileBtn.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();
|
||||
|
||||
// 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;
|
||||
};
|
||||
}));
|
||||
}));
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue