Skip to content

Commit 47df567

Browse files
committed
NIFI-3785: Moved the logic for getting process group options to an API call. Moved move dialog to ui/controller-service.
1 parent 6491b39 commit 47df567

File tree

17 files changed

+747
-3833
lines changed

17 files changed

+747
-3833
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.nifi.web.api.entity;
18+
19+
import io.swagger.v3.oas.annotations.media.Schema;
20+
21+
import jakarta.xml.bind.annotation.XmlRootElement;
22+
23+
@XmlRootElement(name = "processGroupOptionEntity")
24+
public class ProcessGroupOptionEntity extends Entity {
25+
26+
private String text;
27+
private String value;
28+
private String description;
29+
private boolean disabled;
30+
31+
/**
32+
* The name for this ProcessGroup.
33+
*
34+
* @return The name
35+
*/
36+
@Schema(description = "The name of this ProcessGroup.")
37+
public String getText() {
38+
return text;
39+
}
40+
41+
public void setText(String id) {
42+
this.text = id;
43+
}
44+
45+
/**
46+
* The id for this ProcessGroup.
47+
*
48+
* @return The id
49+
*/
50+
@Schema(description = "The id of this ProcessGroup.")
51+
public String getValue() {
52+
return value;
53+
}
54+
55+
public void setValue(String value) {
56+
this.value = value;
57+
}
58+
59+
/**
60+
* Text containing any conflicts for this ProcessGroup.
61+
*
62+
* @return The text
63+
*/
64+
@Schema(description = "Text containing any conflicts for this ProcessGroup.")
65+
public String getDescription() {
66+
return description;
67+
}
68+
69+
public void setDescription(String description) {
70+
this.description = description;
71+
}
72+
73+
/**
74+
* Boolean showing whether this option is disabled.
75+
*
76+
* @return The disabled boolean
77+
*/
78+
@Schema(description = "Boolean showing whether this option is disabled.")
79+
public boolean isDisabled() {
80+
return disabled;
81+
}
82+
83+
public void setDisabled(boolean disabled) {
84+
this.disabled = disabled;
85+
}
86+
}

nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,15 +1127,6 @@ Set<DocumentedTypeDTO> getControllerServiceTypes(final String serviceType, final
11271127
*/
11281128
ProcessGroupEntity getProcessGroup(String groupId);
11291129

1130-
/**
1131-
* Returns the process group.
1132-
*
1133-
* @param groupId group
1134-
* @param recurse boolean
1135-
* @return ProcessGroup transfer object
1136-
*/
1137-
ProcessGroupEntity getProcessGroup(String groupId, boolean recurse);
1138-
11391130
/**
11401131
* Verifies that a Parameter Context matching the given DTO can be created
11411132
* @param parameterContext the DTO that represents the Parameter Context

nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4798,14 +4798,11 @@ public Set<PortEntity> getOutputPorts(final String groupId) {
47984798
}
47994799

48004800
private ProcessGroupEntity createProcessGroupEntity(final ProcessGroup group) {
4801-
return createProcessGroupEntity(group, false);
4802-
}
4803-
private ProcessGroupEntity createProcessGroupEntity(final ProcessGroup group, final boolean recurse) {
48044801
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(group.getIdentifier()));
48054802
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(group);
48064803
final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(group.getIdentifier()));
48074804
final List<BulletinEntity> bulletins = getProcessGroupBulletins(group);
4808-
return entityFactory.createProcessGroupEntity(dtoFactory.createProcessGroupDto(group, recurse), revision, permissions, status, bulletins);
4805+
return entityFactory.createProcessGroupEntity(dtoFactory.createProcessGroupDto(group), revision, permissions, status, bulletins);
48094806
}
48104807

48114808
private List<BulletinEntity> getProcessGroupBulletins(final ProcessGroup group) {
@@ -4985,13 +4982,8 @@ public FlowBreadcrumbEntity getProcessGroupBreadcrumbs(final String groupId) {
49854982

49864983
@Override
49874984
public ProcessGroupEntity getProcessGroup(final String groupId) {
4988-
return getProcessGroup(groupId, false);
4989-
}
4990-
4991-
@Override
4992-
public ProcessGroupEntity getProcessGroup(final String groupId, final boolean recurse) {
49934985
final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId);
4994-
return createProcessGroupEntity(processGroup, recurse);
4986+
return createProcessGroupEntity(processGroup);
49954987
}
49964988

49974989
private ControllerServiceEntity createControllerServiceEntity(final ControllerServiceNode serviceNode, final boolean includeReferencingComponents) {

nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
8888
import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity;
8989
import org.apache.nifi.web.api.entity.ControllerServiceRunStatusEntity;
90+
import org.apache.nifi.web.api.entity.ProcessGroupOptionEntity;
9091
import org.apache.nifi.web.api.entity.PropertyDescriptorEntity;
9192
import org.apache.nifi.web.api.entity.UpdateControllerServiceReferenceRequestEntity;
9293
import org.apache.nifi.web.api.entity.VerifyConfigRequestEntity;
@@ -685,6 +686,98 @@ public Response updateControllerService(
685686
);
686687
}
687688

689+
@GET
690+
@Consumes(MediaType.WILDCARD)
691+
@Produces(MediaType.APPLICATION_JSON)
692+
@Path("{id}/move-options")
693+
@Operation(
694+
summary = "Gets the move options for a controller service",
695+
responses = @ApiResponse(content = @Content(schema = @Schema(implementation = ProcessGroupOptionEntity.class))),
696+
security = {
697+
@SecurityRequirement(name = "Read - /flow")
698+
}
699+
)
700+
@ApiResponses(
701+
value = {
702+
@ApiResponse(responseCode = "400", description = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
703+
@ApiResponse(responseCode = "401", description = "Client could not be authenticated."),
704+
@ApiResponse(responseCode = "403", description = "Client is not authorized to make this request."),
705+
@ApiResponse(responseCode = "404", description = "The specified resource could not be found."),
706+
@ApiResponse(responseCode = "409", description = "The request was valid but NiFi was not in the appropriate state to process it.")
707+
}
708+
)
709+
public Response getProcessGroupOptions(
710+
@Parameter(description = "The controller service id.")
711+
@PathParam("id") final String controllerServiceId) {
712+
713+
if (controllerServiceId == null) {
714+
throw new IllegalArgumentException("Controller service id must be specified.");
715+
}
716+
717+
List<ProcessGroupOptionEntity> options = new ArrayList<>();
718+
serviceFacade.authorizeAccess(lookup -> {
719+
final NiFiUser user = NiFiUserUtils.getNiFiUser();
720+
721+
final ComponentAuthorizable authorizableControllerService = lookup.getControllerService(controllerServiceId);
722+
authorizableControllerService.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
723+
724+
final ControllerServiceDTO controllerServiceDTO = serviceFacade.getControllerService(controllerServiceId, true).getComponent();
725+
726+
final ProcessGroupAuthorizable authorizableProcessGroupCurrent = lookup.getProcessGroup(controllerServiceDTO.getParentGroupId());
727+
authorizableProcessGroupCurrent.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
728+
729+
if (authorizableProcessGroupCurrent.getProcessGroup().getParent() != null) {
730+
final ProcessGroupAuthorizable authorizableProcessGroupParent = lookup.getProcessGroup(authorizableProcessGroupCurrent.getProcessGroup().getParent().getIdentifier());
731+
authorizableProcessGroupParent.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
732+
733+
options.add(generateProcessGroupOption(controllerServiceDTO, authorizableProcessGroupParent));
734+
}
735+
736+
authorizableProcessGroupCurrent.getProcessGroup().getProcessGroups().forEach(processGroup -> {
737+
final ProcessGroupAuthorizable authorizableProcessGroup = lookup.getProcessGroup(processGroup.getIdentifier());
738+
authorizableProcessGroup.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
739+
options.add(generateProcessGroupOption(controllerServiceDTO, authorizableProcessGroup));
740+
});
741+
});
742+
743+
return generateOkResponse(options).build();
744+
}
745+
746+
private ProcessGroupOptionEntity generateProcessGroupOption(ControllerServiceDTO controllerServiceDTO, ProcessGroupAuthorizable processGroup) {
747+
List<String> conflictingComponents = new ArrayList<>();
748+
controllerServiceDTO.getReferencingComponents().forEach(e -> {
749+
if (processGroup.getProcessGroup().findProcessor(e.getId()) == null
750+
&& processGroup.getProcessGroup().findControllerService(e.getId(), true, false) == null) {
751+
conflictingComponents.add("[" + e.getComponent().getName() + "]");
752+
}
753+
});
754+
755+
controllerServiceDTO.getProperties().forEach((key, value) -> {
756+
try {
757+
ControllerServiceEntity refControllerService = serviceFacade.getControllerService(value, false);
758+
if (refControllerService != null) {
759+
if (processGroup.getProcessGroup().findControllerService(value, false, true) == null) {
760+
conflictingComponents.add("[" + refControllerService.getComponent().getName() + "]");
761+
}
762+
}
763+
} catch (Exception ignored) { }
764+
});
765+
766+
ProcessGroupOptionEntity option = new ProcessGroupOptionEntity();
767+
option.setText(processGroup.getProcessGroup().getName());
768+
option.setValue(processGroup.getProcessGroup().getIdentifier());
769+
option.setDisabled(false);
770+
771+
if (!conflictingComponents.isEmpty()) {
772+
String errorMessage = "Could not move controller service because the following components would be out of scope: ";
773+
errorMessage += String.join(" ", conflictingComponents);
774+
option.setDescription(errorMessage);
775+
option.setDisabled(true);
776+
}
777+
778+
return option;
779+
}
780+
688781
/**
689782
* Moves the specified Controller Service to parent/child process groups.
690783
*

nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,7 @@ private FlowDTO populateRemainingSnippetContent(FlowDTO flow) {
247247
)
248248
public Response getProcessGroup(
249249
@Parameter(description = "The process group id.")
250-
@PathParam("id") final String groupId,
251-
@QueryParam("includeContent") @DefaultValue("false")
252-
@Parameter(description = "Include content for process group") boolean includeContent) {
250+
@PathParam("id") final String groupId) {
253251

254252
if (isReplicateRequest()) {
255253
return replicate(HttpMethod.GET);
@@ -262,10 +260,10 @@ public Response getProcessGroup(
262260
});
263261

264262
// get this process group contents
265-
final ProcessGroupEntity entity = serviceFacade.getProcessGroup(groupId, includeContent);
263+
final ProcessGroupEntity entity = serviceFacade.getProcessGroup(groupId);
266264
populateRemainingProcessGroupEntityContent(entity);
267265

268-
if (entity.getComponent() != null && !includeContent) {
266+
if (entity.getComponent() != null) {
269267
entity.getComponent().setContents(null);
270268
}
271269

nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/controller-service.service.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,17 @@ export class ControllerServiceService implements ControllerServiceCreator, Prope
102102

103103
moveControllerService(moveControllerService: MoveControllerServiceRequest): Observable<any> {
104104
return this.httpClient.put(
105-
this.nifiCommon.stripProtocol(moveControllerService.controllerService.uri + '/move'),
105+
this.nifiCommon.stripProtocol(`${moveControllerService.controllerService.uri}/move`),
106106
moveControllerService.data
107107
);
108108
}
109109

110+
getMoveOptions(controllerServiceId: string): Observable<any> {
111+
return this.httpClient.get(
112+
`${ControllerServiceService.API}/controller-services/${controllerServiceId}/move-options`
113+
);
114+
}
115+
110116
deleteControllerService(deleteControllerService: DeleteControllerServiceRequest): Observable<any> {
111117
const entity: ControllerServiceEntity = deleteControllerService.controllerService;
112118
const params = new HttpParams({

nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/flow.service.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,6 @@ export class FlowService implements PropertyDescriptorRetriever {
118118
return this.httpClient.get(`${FlowService.API}/process-groups/${id}`);
119119
}
120120

121-
getProcessGroupWithContent(id: string): Observable<any> {
122-
const params = new HttpParams().set('includeContent', true);
123-
return this.httpClient.get(`${FlowService.API}/process-groups/${id}`, { params: params });
124-
}
125-
126121
createFunnel(processGroupId = 'root', createFunnel: CreateComponentRequest): Observable<any> {
127122
return this.httpClient.post(`${FlowService.API}/process-groups/${processGroupId}/funnels`, {
128123
revision: createFunnel.revision,

0 commit comments

Comments
 (0)