rfellows commented on code in PR #10855:
URL: https://github.com/apache/nifi/pull/10855#discussion_r2769658344
##########
nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java:
##########
Review Comment:
The unit tests added in TestConnectorResource.java only test the REST
resource layer with mocked serviceFacade calls. There are no integration or
unit tests for the actual StandardNiFiServiceFacade implementation methods:
* getConnectorProcessorState
* clearConnectorProcessorState
* getConnectorControllerServiceState
* clearConnectorControllerServiceState
* locateConnectorProcessor
* locateConnectorControllerService
##########
nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java:
##########
@@ -2146,6 +2148,224 @@ public Response getAssetContent(
.build();
}
+ // -----------------
+ // Processor State
+ // -----------------
+
+ /**
+ * Gets the state for a processor within a connector.
+ *
+ * @param connectorId the connector id
+ * @param processorId the processor id
+ * @return a ComponentStateEntity
+ */
+ @GET
+ @Consumes(MediaType.WILDCARD)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("{id}/processors/{processorId}/state")
+ @Operation(
+ summary = "Gets the state for a processor within a connector",
+ responses = {
+ @ApiResponse(responseCode = "200", content =
@Content(schema = @Schema(implementation = ComponentStateEntity.class))),
+ @ApiResponse(responseCode = "400", description = "NiFi was
unable to complete the request because it was invalid. The request should not
be retried without modification."),
+ @ApiResponse(responseCode = "401", description = "Client
could not be authenticated."),
+ @ApiResponse(responseCode = "403", description = "Client
is not authorized to make this request."),
+ @ApiResponse(responseCode = "404", description = "The
specified resource could not be found."),
+ @ApiResponse(responseCode = "409", description = "The
request was valid but NiFi was not in the appropriate state to process it.")
+ },
+ security = {
+ @SecurityRequirement(name = "Write - /connectors/{uuid}")
+ }
+ )
+ public Response getConnectorProcessorState(
+ @Parameter(description = "The connector id.", required = true)
+ @PathParam("id") final String connectorId,
+ @Parameter(description = "The processor id.", required = true)
+ @PathParam("processorId") final String processorId) {
+
+ if (isReplicateRequest()) {
+ return replicate(HttpMethod.GET);
+ }
+
+ serviceFacade.authorizeAccess(lookup -> {
+ final Authorizable connector = lookup.getConnector(connectorId);
+ connector.authorize(authorizer, RequestAction.WRITE,
NiFiUserUtils.getNiFiUser());
+ });
+
+ final ComponentStateDTO state =
serviceFacade.getConnectorProcessorState(connectorId, processorId);
+
+ final ComponentStateEntity entity = new ComponentStateEntity();
+ entity.setComponentState(state);
+
+ return generateOkResponse(entity).build();
+ }
+
+ /**
+ * Clears the state for a processor within a connector.
+ *
+ * @param connectorId the connector id
+ * @param processorId the processor id
+ * @return a ComponentStateEntity
+ */
+ @POST
+ @Consumes({MediaType.APPLICATION_JSON, MediaType.WILDCARD})
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("{id}/processors/{processorId}/state/clear-requests")
+ @Operation(
+ summary = "Clears the state for a processor within a connector",
+ responses = {
+ @ApiResponse(responseCode = "200", content =
@Content(schema = @Schema(implementation = ComponentStateEntity.class))),
+ @ApiResponse(responseCode = "400", description = "NiFi was
unable to complete the request because it was invalid. The request should not
be retried without modification."),
+ @ApiResponse(responseCode = "401", description = "Client
could not be authenticated."),
+ @ApiResponse(responseCode = "403", description = "Client
is not authorized to make this request."),
+ @ApiResponse(responseCode = "404", description = "The
specified resource could not be found."),
+ @ApiResponse(responseCode = "409", description = "The
request was valid but NiFi was not in the appropriate state to process it.")
+ },
+ security = {
+ @SecurityRequirement(name = "Write - /connectors/{uuid}")
+ }
+ )
+ public Response clearConnectorProcessorState(
+ @Parameter(description = "The connector id.", required = true)
+ @PathParam("id") final String connectorId,
+ @Parameter(description = "The processor id.", required = true)
+ @PathParam("processorId") final String processorId,
+ @Parameter(description = "Optional component state to perform a
selective key removal. If omitted, clears all state.", required = false)
+ final ComponentStateEntity componentStateEntity) {
+
+ if (isReplicateRequest()) {
+ if (componentStateEntity == null) {
+ return replicate(HttpMethod.POST);
+ } else {
+ return replicate(HttpMethod.POST, componentStateEntity);
+ }
+ }
+
+ serviceFacade.authorizeAccess(lookup -> {
+ final Authorizable connector = lookup.getConnector(connectorId);
+ connector.authorize(authorizer, RequestAction.WRITE,
NiFiUserUtils.getNiFiUser());
+ });
Review Comment:
This should use `withWriteLock` pattern that is established in other
resources for state-modifying operations
##########
nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java:
##########
@@ -2146,6 +2148,224 @@ public Response getAssetContent(
.build();
}
+ // -----------------
+ // Processor State
+ // -----------------
+
+ /**
+ * Gets the state for a processor within a connector.
+ *
+ * @param connectorId the connector id
+ * @param processorId the processor id
+ * @return a ComponentStateEntity
+ */
+ @GET
+ @Consumes(MediaType.WILDCARD)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("{id}/processors/{processorId}/state")
+ @Operation(
+ summary = "Gets the state for a processor within a connector",
+ responses = {
+ @ApiResponse(responseCode = "200", content =
@Content(schema = @Schema(implementation = ComponentStateEntity.class))),
+ @ApiResponse(responseCode = "400", description = "NiFi was
unable to complete the request because it was invalid. The request should not
be retried without modification."),
+ @ApiResponse(responseCode = "401", description = "Client
could not be authenticated."),
+ @ApiResponse(responseCode = "403", description = "Client
is not authorized to make this request."),
+ @ApiResponse(responseCode = "404", description = "The
specified resource could not be found."),
+ @ApiResponse(responseCode = "409", description = "The
request was valid but NiFi was not in the appropriate state to process it.")
+ },
+ security = {
+ @SecurityRequirement(name = "Write - /connectors/{uuid}")
+ }
+ )
+ public Response getConnectorProcessorState(
+ @Parameter(description = "The connector id.", required = true)
+ @PathParam("id") final String connectorId,
+ @Parameter(description = "The processor id.", required = true)
+ @PathParam("processorId") final String processorId) {
+
+ if (isReplicateRequest()) {
+ return replicate(HttpMethod.GET);
+ }
+
+ serviceFacade.authorizeAccess(lookup -> {
+ final Authorizable connector = lookup.getConnector(connectorId);
+ connector.authorize(authorizer, RequestAction.WRITE,
NiFiUserUtils.getNiFiUser());
+ });
+
+ final ComponentStateDTO state =
serviceFacade.getConnectorProcessorState(connectorId, processorId);
+
+ final ComponentStateEntity entity = new ComponentStateEntity();
+ entity.setComponentState(state);
+
+ return generateOkResponse(entity).build();
+ }
+
+ /**
+ * Clears the state for a processor within a connector.
+ *
+ * @param connectorId the connector id
+ * @param processorId the processor id
+ * @return a ComponentStateEntity
+ */
+ @POST
+ @Consumes({MediaType.APPLICATION_JSON, MediaType.WILDCARD})
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("{id}/processors/{processorId}/state/clear-requests")
+ @Operation(
+ summary = "Clears the state for a processor within a connector",
+ responses = {
+ @ApiResponse(responseCode = "200", content =
@Content(schema = @Schema(implementation = ComponentStateEntity.class))),
+ @ApiResponse(responseCode = "400", description = "NiFi was
unable to complete the request because it was invalid. The request should not
be retried without modification."),
+ @ApiResponse(responseCode = "401", description = "Client
could not be authenticated."),
+ @ApiResponse(responseCode = "403", description = "Client
is not authorized to make this request."),
+ @ApiResponse(responseCode = "404", description = "The
specified resource could not be found."),
+ @ApiResponse(responseCode = "409", description = "The
request was valid but NiFi was not in the appropriate state to process it.")
+ },
+ security = {
+ @SecurityRequirement(name = "Write - /connectors/{uuid}")
+ }
+ )
+ public Response clearConnectorProcessorState(
+ @Parameter(description = "The connector id.", required = true)
+ @PathParam("id") final String connectorId,
+ @Parameter(description = "The processor id.", required = true)
+ @PathParam("processorId") final String processorId,
+ @Parameter(description = "Optional component state to perform a
selective key removal. If omitted, clears all state.", required = false)
+ final ComponentStateEntity componentStateEntity) {
+
+ if (isReplicateRequest()) {
+ if (componentStateEntity == null) {
+ return replicate(HttpMethod.POST);
+ } else {
+ return replicate(HttpMethod.POST, componentStateEntity);
+ }
+ }
+
+ serviceFacade.authorizeAccess(lookup -> {
+ final Authorizable connector = lookup.getConnector(connectorId);
+ connector.authorize(authorizer, RequestAction.WRITE,
NiFiUserUtils.getNiFiUser());
+ });
+
+ serviceFacade.verifyCanClearConnectorProcessorState(connectorId,
processorId);
+
+ final ComponentStateDTO expectedState = componentStateEntity == null ?
null : componentStateEntity.getComponentState();
+ final ComponentStateDTO state =
serviceFacade.clearConnectorProcessorState(connectorId, processorId,
expectedState);
+
+ final ComponentStateEntity entity = new ComponentStateEntity();
+ entity.setComponentState(state);
+
+ return generateOkResponse(entity).build();
+ }
+
+ // -----------------
+ // Controller Service State
+ // -----------------
+
+ /**
+ * Gets the state for a controller service within a connector.
+ *
+ * @param connectorId the connector id
+ * @param controllerServiceId the controller service id
+ * @return a ComponentStateEntity
+ */
+ @GET
+ @Consumes(MediaType.WILDCARD)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("{id}/controller-services/{controllerServiceId}/state")
+ @Operation(
+ summary = "Gets the state for a controller service within a
connector",
+ responses = {
+ @ApiResponse(responseCode = "200", content =
@Content(schema = @Schema(implementation = ComponentStateEntity.class))),
+ @ApiResponse(responseCode = "400", description = "NiFi was
unable to complete the request because it was invalid. The request should not
be retried without modification."),
+ @ApiResponse(responseCode = "401", description = "Client
could not be authenticated."),
+ @ApiResponse(responseCode = "403", description = "Client
is not authorized to make this request."),
+ @ApiResponse(responseCode = "404", description = "The
specified resource could not be found."),
+ @ApiResponse(responseCode = "409", description = "The
request was valid but NiFi was not in the appropriate state to process it.")
+ },
+ security = {
+ @SecurityRequirement(name = "Write - /connectors/{uuid}")
+ }
+ )
+ public Response getConnectorControllerServiceState(
+ @Parameter(description = "The connector id.", required = true)
+ @PathParam("id") final String connectorId,
+ @Parameter(description = "The controller service id.", required =
true)
+ @PathParam("controllerServiceId") final String
controllerServiceId) {
+
+ if (isReplicateRequest()) {
+ return replicate(HttpMethod.GET);
+ }
+
+ serviceFacade.authorizeAccess(lookup -> {
+ final Authorizable connector = lookup.getConnector(connectorId);
+ connector.authorize(authorizer, RequestAction.WRITE,
NiFiUserUtils.getNiFiUser());
+ });
+
+ final ComponentStateDTO state =
serviceFacade.getConnectorControllerServiceState(connectorId,
controllerServiceId);
+
+ final ComponentStateEntity entity = new ComponentStateEntity();
+ entity.setComponentState(state);
+
+ return generateOkResponse(entity).build();
+ }
+
+ /**
+ * Clears the state for a controller service within a connector.
+ *
+ * @param connectorId the connector id
+ * @param controllerServiceId the controller service id
+ * @return a ComponentStateEntity
+ */
+ @POST
+ @Consumes({MediaType.APPLICATION_JSON, MediaType.WILDCARD})
+ @Produces(MediaType.APPLICATION_JSON)
+
@Path("{id}/controller-services/{controllerServiceId}/state/clear-requests")
+ @Operation(
+ summary = "Clears the state for a controller service within a
connector",
+ responses = {
+ @ApiResponse(responseCode = "200", content =
@Content(schema = @Schema(implementation = ComponentStateEntity.class))),
+ @ApiResponse(responseCode = "400", description = "NiFi was
unable to complete the request because it was invalid. The request should not
be retried without modification."),
+ @ApiResponse(responseCode = "401", description = "Client
could not be authenticated."),
+ @ApiResponse(responseCode = "403", description = "Client
is not authorized to make this request."),
+ @ApiResponse(responseCode = "404", description = "The
specified resource could not be found."),
+ @ApiResponse(responseCode = "409", description = "The
request was valid but NiFi was not in the appropriate state to process it.")
+ },
+ security = {
+ @SecurityRequirement(name = "Write - /connectors/{uuid}")
+ }
+ )
+ public Response clearConnectorControllerServiceState(
+ @Parameter(description = "The connector id.", required = true)
+ @PathParam("id") final String connectorId,
+ @Parameter(description = "The controller service id.", required =
true)
+ @PathParam("controllerServiceId") final String controllerServiceId,
+ @Parameter(description = "Optional component state to perform a
selective key removal. If omitted, clears all state.", required = false)
+ final ComponentStateEntity componentStateEntity) {
+
+ if (isReplicateRequest()) {
+ if (componentStateEntity == null) {
+ return replicate(HttpMethod.POST);
+ } else {
+ return replicate(HttpMethod.POST, componentStateEntity);
+ }
+ }
+
+ serviceFacade.authorizeAccess(lookup -> {
+ final Authorizable connector = lookup.getConnector(connectorId);
+ connector.authorize(authorizer, RequestAction.WRITE,
NiFiUserUtils.getNiFiUser());
+ });
Review Comment:
This should use `withWriteLock` pattern that is established in other
resources for state-modifying operations
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]