This is an automated email from the ASF dual-hosted git repository. markap14 pushed a commit to branch NIFI-15258 in repository https://gitbox.apache.org/repos/asf/nifi.git
commit f931e1497ec79287f887b848f8a64d943ea271d0 Author: Matt Gilman <[email protected]> AuthorDate: Wed Jan 7 11:22:25 2026 -0500 NIFI-15429: Adding an optional query parameter for specifying which p… (#10732) * NIFI-15429: Adding an optional query parameter for specifying which process group should be returned within the Connectors flow. * NIFI-15429: Including managed process group id in the ConnectorDTO. * NIFI-15429: Addressing review feedback. * NIFI-15429: Updating path for fetching a Connector flow to require the desired Process Group ID. * NIFI-15429: Fixing failing unit test. --- .../org/apache/nifi/web/api/dto/ConnectorDTO.java | 10 ++++++ .../org/apache/nifi/web/NiFiServiceFacade.java | 2 +- .../apache/nifi/web/StandardNiFiServiceFacade.java | 10 ++++-- .../org/apache/nifi/web/api/ConnectorResource.java | 32 +++++++++++------- .../org/apache/nifi/web/api/dto/DtoFactory.java | 5 ++- .../apache/nifi/web/api/TestConnectorResource.java | 39 ++++++++++++++++++++++ .../nifi/web/controller/ControllerFacadeTest.java | 3 ++ 7 files changed, 84 insertions(+), 17 deletions(-) diff --git a/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectorDTO.java b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectorDTO.java index 9aed99c62b..96849a58a0 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectorDTO.java +++ b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectorDTO.java @@ -30,6 +30,7 @@ public class ConnectorDTO extends ComponentDTO { private String type; private BundleDTO bundle; private String state; // RUNNING, STOPPED, DISABLED + private String managedProcessGroupId; private ConnectorConfigurationDTO activeConfiguration; private ConnectorConfigurationDTO workingConfiguration; @@ -76,6 +77,15 @@ public class ConnectorDTO extends ComponentDTO { this.state = state; } + @Schema(description = "The identifier of the root Process Group managed by this Connector.") + public String getManagedProcessGroupId() { + return managedProcessGroupId; + } + + public void setManagedProcessGroupId(final String managedProcessGroupId) { + this.managedProcessGroupId = managedProcessGroupId; + } + @Schema(description = "The active configuration of the Connector.") public ConnectorConfigurationDTO getActiveConfiguration() { return activeConfiguration; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java index 1928b17397..09761a5076 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java @@ -220,7 +220,7 @@ public interface NiFiServiceFacade { ConnectorEntity discardConnectorUpdate(Revision revision, String connectorId); - ProcessGroupFlowEntity getConnectorFlow(String id, boolean uiOnly); + ProcessGroupFlowEntity getConnectorFlow(String connectorId, String processGroupId, boolean uiOnly); ProcessGroupStatusEntity getConnectorProcessGroupStatus(String id, Boolean recursive); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index 3b2b7d1165..c540467b38 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -3690,10 +3690,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public ProcessGroupFlowEntity getConnectorFlow(final String id, final boolean uiOnly) { - final ConnectorNode connectorNode = connectorDAO.getConnector(id); + public ProcessGroupFlowEntity getConnectorFlow(final String connectorId, final String processGroupId, final boolean uiOnly) { + final ConnectorNode connectorNode = connectorDAO.getConnector(connectorId); final ProcessGroup managedProcessGroup = connectorNode.getActiveFlowContext().getManagedProcessGroup(); - return createProcessGroupFlowEntity(managedProcessGroup, uiOnly); + final ProcessGroup targetProcessGroup = managedProcessGroup.findProcessGroup(processGroupId); + if (targetProcessGroup == null) { + throw new ResourceNotFoundException("Process Group with ID " + processGroupId + " was not found within Connector " + connectorId); + } + return createProcessGroupFlowEntity(targetProcessGroup, uiOnly); } @Override diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java index 0112d7e61c..c2f7b4cddf 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java @@ -1348,18 +1348,19 @@ public class ConnectorResource extends ApplicationResource { } /** - * Retrieves the flow for the process group managed by the specified connector. + * Retrieves the flow for a process group within the specified connector. * - * @param id The id of the connector + * @param connectorId The id of the connector + * @param processGroupId The process group id within the connector's hierarchy * @param uiOnly Whether to return only UI-specific fields * @return A processGroupFlowEntity */ @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) - @Path("/{id}/flow") + @Path("/{connectorId}/flow/process-groups/{processGroupId}") @Operation( - summary = "Gets the flow for the process group managed by a connector", + summary = "Gets the flow for a process group within a connector", responses = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = ProcessGroupFlowEntity.class))), @ApiResponse(responseCode = "400", description = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), @@ -1371,17 +1372,24 @@ public class ConnectorResource extends ApplicationResource { security = { @SecurityRequirement(name = "Read - /connectors/{uuid}") }, - description = "Returns the flow for the process group managed by the specified connector. If the uiOnly query parameter is " + - "provided with a value of true, the returned entity may only contain fields that are necessary for rendering the NiFi User " + - "Interface. As such, the selected fields may change at any time, even during incremental releases, without warning. " + - "As a result, this parameter should not be provided by any client other than the UI." + description = "Returns the flow for the specified process group within the connector's hierarchy. The processGroupId can be " + + "obtained from the managedProcessGroupId field of the ConnectorDTO for the root process group, or from child process " + + "groups within the flow. If the uiOnly query parameter is provided with a value of true, the returned entity may only " + + "contain fields that are necessary for rendering the NiFi User Interface. As such, the selected fields may change at " + + "any time, even during incremental releases, without warning. As a result, this parameter should not be provided by " + + "any client other than the UI." ) public Response getFlow( @Parameter( description = "The connector id.", required = true ) - @PathParam("id") final String id, + @PathParam("connectorId") final String connectorId, + @Parameter( + description = "The process group id.", + required = true + ) + @PathParam("processGroupId") final String processGroupId, @Parameter( description = "Whether to return only UI-specific fields" ) @@ -1393,12 +1401,12 @@ public class ConnectorResource extends ApplicationResource { // authorize access to the connector serviceFacade.authorizeAccess(lookup -> { - final Authorizable connector = lookup.getConnector(id); + final Authorizable connector = lookup.getConnector(connectorId); connector.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); }); - // get the flow for the connector's managed process group - final ProcessGroupFlowEntity entity = serviceFacade.getConnectorFlow(id, uiOnly); + // get the flow for the specified process group within the connector's hierarchy + final ProcessGroupFlowEntity entity = serviceFacade.getConnectorFlow(connectorId, processGroupId, uiOnly); flowResource.populateRemainingFlowContent(entity.getProcessGroupFlow()); return generateOkResponse(entity).build(); } diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java index 72686f650c..1fa240ced1 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java @@ -5262,7 +5262,10 @@ public final class DtoFactory { dto.setBundle(createBundleDto(connector.getBundleCoordinate())); dto.setState(connector.getCurrentState().name()); - dto.setActiveConfiguration(createConnectorConfigurationDtoFromFlowContext(connector, connector.getActiveFlowContext())); + + final FrameworkFlowContext activeFlowContext = connector.getActiveFlowContext(); + dto.setManagedProcessGroupId(activeFlowContext.getManagedProcessGroup().getIdentifier()); + dto.setActiveConfiguration(createConnectorConfigurationDtoFromFlowContext(connector, activeFlowContext)); dto.setWorkingConfiguration(createConnectorConfigurationDtoFromFlowContext(connector, connector.getWorkingFlowContext())); return dto; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestConnectorResource.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestConnectorResource.java index df21a6935e..5c22f82fd1 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestConnectorResource.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestConnectorResource.java @@ -32,9 +32,11 @@ import org.apache.nifi.web.api.dto.AllowableValueDTO; import org.apache.nifi.web.api.dto.ConnectorDTO; import org.apache.nifi.web.api.dto.RevisionDTO; import org.apache.nifi.web.api.entity.AllowableValueEntity; +import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO; import org.apache.nifi.web.api.entity.ConnectorEntity; import org.apache.nifi.web.api.entity.ConnectorPropertyAllowableValuesEntity; import org.apache.nifi.web.api.entity.ConnectorRunStatusEntity; +import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; import org.apache.nifi.web.api.entity.SecretsEntity; import org.apache.nifi.web.api.request.ClientIdParameter; import org.apache.nifi.web.api.request.LongParameter; @@ -86,12 +88,16 @@ public class TestConnectorResource { @Mock private UriBuilder uriBuilder; + @Mock + private FlowResource flowResource; + private static final String CONNECTOR_ID = "test-connector-id"; private static final String CONNECTOR_NAME = "Test Connector"; private static final String CONNECTOR_TYPE = "TestConnectorType"; private static final String CONFIGURATION_STEP_NAME = "test-step"; private static final String PROPERTY_GROUP_NAME = "test-group"; private static final String PROPERTY_NAME = "test-property"; + private static final String PROCESS_GROUP_ID = "test-process-group-id"; @BeforeEach public void setUp() throws Exception { @@ -109,6 +115,7 @@ public class TestConnectorResource { lenient().when(uriBuilder.build()).thenReturn(new URI("http://localhost:8080/nifi-api/connectors/" + CONNECTOR_ID)); connectorResource.setServiceFacade(serviceFacade); + connectorResource.setFlowResource(flowResource); connectorResource.httpServletRequest = httpServletRequest; connectorResource.properties = properties; connectorResource.uriInfo = uriInfo; @@ -353,6 +360,30 @@ public class TestConnectorResource { verify(serviceFacade, never()).getSecrets(); } + @Test + public void testGetFlow() { + final ProcessGroupFlowEntity responseEntity = createProcessGroupFlowEntity(); + when(serviceFacade.getConnectorFlow(CONNECTOR_ID, PROCESS_GROUP_ID, false)).thenReturn(responseEntity); + + try (Response response = connectorResource.getFlow(CONNECTOR_ID, PROCESS_GROUP_ID, false)) { + assertEquals(200, response.getStatus()); + assertEquals(responseEntity, response.getEntity()); + } + + verify(serviceFacade).authorizeAccess(any(AuthorizeAccess.class)); + verify(serviceFacade).getConnectorFlow(CONNECTOR_ID, PROCESS_GROUP_ID, false); + } + + @Test + public void testGetFlowNotAuthorized() { + doThrow(AccessDeniedException.class).when(serviceFacade).authorizeAccess(any(AuthorizeAccess.class)); + + assertThrows(AccessDeniedException.class, () -> connectorResource.getFlow(CONNECTOR_ID, PROCESS_GROUP_ID, false)); + + verify(serviceFacade).authorizeAccess(any(AuthorizeAccess.class)); + verify(serviceFacade, never()).getConnectorFlow(anyString(), anyString(), eq(false)); + } + private ConnectorEntity createConnectorEntity() { final ConnectorEntity entity = new ConnectorEntity(); @@ -411,4 +442,12 @@ public class TestConnectorResource { return entity; } + + private ProcessGroupFlowEntity createProcessGroupFlowEntity() { + final ProcessGroupFlowEntity entity = new ProcessGroupFlowEntity(); + final ProcessGroupFlowDTO flowDTO = new ProcessGroupFlowDTO(); + flowDTO.setId("root-process-group-id"); + entity.setProcessGroupFlow(flowDTO); + return entity; + } } diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerFacadeTest.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerFacadeTest.java index 6374029cac..5dad329baf 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerFacadeTest.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerFacadeTest.java @@ -132,6 +132,9 @@ public class ControllerFacadeTest { @Test public void testGetConnectorDefinitionReturnsDefinitionWhenFound() { final ConnectorDefinition expectedDefinition = new ConnectorDefinition(); + expectedDefinition.setGroup(TEST_GROUP); + expectedDefinition.setArtifact(TEST_ARTIFACT); + expectedDefinition.setVersion(TEST_VERSION); expectedDefinition.setType(TEST_CONNECTOR_TYPE); when(runtimeManifestService.getManifestForBundle(TEST_GROUP, TEST_ARTIFACT, TEST_VERSION)).thenReturn(runtimeManifest);
