You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@nifi.apache.org by "Mark Payne (Jira)" <ji...@apache.org> on 2026/10/16 20:54:00 UTC

[jira] [Resolved] (NIFI-16470) Implement nifi-api changes to enable evolve flow functionality

     [ https://issues.apache.org/jira/browse/NIFI-16470?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Mark Payne resolved NIFI-16470.
-------------------------------
    Fix Version/s: nifi-api-2.14.0
         Assignee: Bob Paulin
       Resolution: Fixed

> Implement nifi-api changes to enable evolve flow functionality
> --------------------------------------------------------------
>
>                 Key: NIFI-16470
>                 URL: https://issues.apache.org/jira/browse/NIFI-16470
>             Project: Apache NiFi
>          Issue Type: Improvement
>            Reporter: Bob Paulin
>            Assignee: Bob Paulin
>            Priority: Major
>             Fix For: nifi-api-2.14.0
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> h2. *Proposed nifi-api changes*
> All additions are backward compatible. Existing connectors compile and run unchanged.
> h3. *FlowEvolutionContext*
> {code:java}
> public interface FlowEvolutionContext {
>     /**
>      * The pre-upgrade Active flow. Its flow, parameters, and bundle are from the authoritative snapshot.
>      * Its configuration has already been migrated and filtered for the loaded Connector version.
>      */
>     FlowContext getPreUpgradeActiveFlowContext();
>     /** The bundle of the loaded Connector code, whether loaded at startup or changed at runtime. */
>     Bundle getPostUpgradeBundle();
> }
> {code}
> The context provides the pre-upgrade flow and the loaded Connector bundle. If flow evolution fails, the framework replaces the supplied context with a wrapper that rejects every method declared by {{{}FlowEvolutionContext{}}}, including {{getPreUpgradeActiveFlowContext()}} and {{{}getPostUpgradeBundle(){}}}. This covers timeout, cancellation, and any other evolution failure, so a connector that retained the context cannot continue using it.
> h3. *Connector.prepareForFlowEvolution*
> {code:java}
> default CompletableFuture<Void> prepareForFlowEvolution(FlowEvolutionContext context) throws FlowUpdateException {
>     return CompletableFuture.completedFuture(null);
> } {code}
> The framework invokes this hook while the pre-upgrade flow is still installed and before the upgraded flow removes connections. The method returns promptly with a non-null future that owns all preparation work. The hook empties pre-upgrade connections the upgraded flow no longer contains before that future completes. Synchronous setup can throw {{{}FlowUpdateException{}}}; asynchronous failures complete the future exceptionally. The hook is not called when the Connector leaves Troubleshooting; the managed flow must already be empty then.
> The framework cancels the future on evolution timeout, user drain cancellation or stop, coordinator interruption, and cluster monitoring failure. {{CompletableFuture.cancel(true)}} does not interrupt arbitrary executor tasks, so connector implementations must make delegated work cooperatively cancellable and must not complete the future while fire-and-forget work can still mutate the pre-upgrade flow. Connector-created asynchronous threads must preserve the Connector NAR classloader context.
> Only normal completion advances phase one. The framework then predicts the upgraded flow with {{getActiveFlow}} and the Working context, and fails evolution if a removed connection still holds FlowFiles.
> h3. *Connector.getActiveFlow*
> The method must remain idempotent and build the flow only from the supplied context's configuration. When called with the Working context, its result predicts what {{applyUpdate}} will install.
> h3. *VersionedConnector*
>  * managedProcessGroup, managedParameterContext, and managedFlowBundle persist the authoritative flow, its parameters, and the Connector version that built it.
>  * troubleshootingProcessGroup separately persists user edits made in troubleshooting.
>  * bundle identifies the Connector code to load and remains independent from managedFlowBundle.
> ConnectorInitializationContext is unchanged. It does not gain a bundle getter.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)