Skip to content

NIFI-15936: Fixing connector flow uri pattern in cluster response mer…#11244

Merged
rfellows merged 2 commits into
apache:mainfrom
mcgilman:NIFI-15936
May 15, 2026
Merged

NIFI-15936: Fixing connector flow uri pattern in cluster response mer…#11244
rfellows merged 2 commits into
apache:mainfrom
mcgilman:NIFI-15936

Conversation

@mcgilman
Copy link
Copy Markdown
Contributor

…ging.

Summary

NIFI-15936

ConnectorFlowEndpointMerger.canHandle was never returning true for the actual connector flow endpoint, so cluster responses for GET /nifi-api/connectors/{id}/flow/process-groups/{pgId} were not being merged through FlowMerger.mergeProcessGroupFlowDto. The result on a multi-node cluster: per-node bulletins/statuses on the connector's flow are not aggregated into the coordinator's response, so bulletins emitted on non-coordinator nodes are not visible on the connector canvas.

The endpoint URI declared by ConnectorResource is:

https://github.com/apache/nifi/blob/main/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java#L1755

i.e. /connectors/{connectorId}/flow/process-groups/{processGroupId}. The merger's pattern /nifi-api/connectors/[a-f0-9\-]{36}/flow was missing the trailing /process-groups/{pgId} segment, which under Matcher#matches() (whole-string match) meant canHandle always returned false.

Change

  • Updated CONNECTOR_FLOW_URI_PATTERN in ConnectorFlowEndpointMerger to /nifi-api/connectors/[a-f0-9\-]{36}/flow/process-groups/[a-f0-9\-]{36}, mirroring the shape of FlowMerger.FLOW_URI_PATTERN.
  • The mergeResponses body is unchanged; it already delegates to the package-private FlowMerger.mergeProcessGroupFlowDto, which was the intended reuse all along.
  • Added ConnectorFlowEndpointMergerTest covering canHandle for:
    • the real connector flow URI (with and without ?uiOnly=true),
    • non-GET methods on the same URI,
    • the previously-broken /connectors/{id}/flow shape (regression guard),
    • adjacent connector sub-paths (/controller-services, /parameter-context) that must keep being routed to their own mergers,
    • the standard /nifi-api/flow/process-groups/{pgId} URI (must remain owned by FlowMerger),
    • non-UUID connector and process group ids.

Scope

  • nifi-api: no changes.
  • DTO/entity surface: no changes.
  • Server-side flow / aggregation logic: no changes — getProcessGroupBulletins already walks findAllProcessGroups() for descendants on the connector flow path; the bug was strictly in cluster-mode response routing.
  • Standalone (non-clustered) NiFi: no behavior change.
  • Cluster-mode NiFi: connector flow responses now flow through FlowMerger.mergeProcessGroupFlowDto, so per-node bulletins/statuses on the connector's flow are merged into the coordinator's response.

@rfellows
Copy link
Copy Markdown
Contributor

reviewing...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses 8 separate @Test methods, each with a single assertion. The established convention in this exact test folder (AccessPolicyEndpointMergerTest, ClearBulletinsEndpointMergerTest, ClearBulletinsForGroupEndpointMergerTest) and the project rule .cursor/rules/testing-standards.mdc ("create the prerequisite objects, invoke the method we care about with appropriate arguments, make assertions, and then invoke again with a different set of arguments, make assertions") both point toward a single consolidated testCanHandle() method with multiple assertions. Suggested rewrite:

@Test
public void testCanHandle() {
    final ConnectorFlowEndpointMerger merger = new ConnectorFlowEndpointMerger();
    final String connectorId = "12345678-1234-1234-1234-123456789012";
    final String processGroupId = "abcdef01-2345-6789-abcd-ef0123456789";
    final String connectorFlowUri = "/nifi-api/connectors/" + connectorId + "/flow/process-groups/" + processGroupId;

    assertTrue(merger.canHandle(URI.create(connectorFlowUri), "GET"));
    assertTrue(merger.canHandle(URI.create(connectorFlowUri + "?uiOnly=true"), "GET"));

    assertFalse(merger.canHandle(URI.create(connectorFlowUri), "POST"));
    assertFalse(merger.canHandle(URI.create("/nifi-api/connectors/" + connectorId + "/flow"), "GET"));
    assertFalse(merger.canHandle(URI.create(connectorFlowUri + "/controller-services"), "GET"));
    assertFalse(merger.canHandle(URI.create("/nifi-api/flow/process-groups/" + processGroupId), "GET"));
    assertFalse(merger.canHandle(URI.create("/nifi-api/connectors/not-a-uuid/flow/process-groups/" + processGroupId), "GET"));
    assertFalse(merger.canHandle(URI.create("/nifi-api/connectors/" + connectorId + "/flow/process-groups/not-a-uuid"), "GET"));
}

Comment on lines +48 to +50
assertFalse(merger.canHandle(uri, "POST"));
assertFalse(merger.canHandle(uri, "PUT"));
assertFalse(merger.canHandle(uri, "DELETE"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testCannotHandleNonGetMethods exercises the same !"GET".equalsIgnoreCase(method) branch three times (POST/PUT/DELETE). Project guidance is to avoid "multiple tests whose differences are conditions that do not truly affect the behavior of the code." One non-GET method is enough. (Falls out naturally if the consolidation above is applied.)

Copy link
Copy Markdown
Contributor

@rfellows rfellows left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mcgilman 👍

@rfellows rfellows merged commit 1511774 into apache:main May 15, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants