markap14 commented on code in PR #11677:
URL: https://github.com/apache/nifi/pull/11677#discussion_r4029453003
##########
nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java:
##########
@@ -5409,7 +5409,19 @@ public ConnectorDTO createConnectorDto(final
ConnectorNode connector) {
dto.setType(connector.getCanonicalClassName());
dto.setExtensionMissing(connector.isExtensionMissing());
- dto.setBundle(createBundleDto(connector.getBundleCoordinate()));
+ final BundleCoordinate bundleCoordinate =
connector.getBundleCoordinate();
+ final List<Bundle> availableBundles =
extensionManager.getBundles(connector.getCanonicalClassName());
+ int compatibleBundleCount = 0;
+ for (final Bundle bundle : availableBundles) {
+ final BundleCoordinate coordinate =
bundle.getBundleDetails().getCoordinate();
+ if (bundleCoordinate.getGroup().equals(coordinate.getGroup()) &&
bundleCoordinate.getId().equals(coordinate.getId())) {
+ compatibleBundleCount++;
+ }
+ }
+
+ dto.setMultipleVersionsAvailable(connector.isExtensionMissing() ?
compatibleBundleCount > 0 : compatibleBundleCount > 1);
Review Comment:
Addressed in 269a772c478. `ConnectorEntityMerger` now follows the processor
merger pattern and reports `multipleVersionsAvailable=false` when any node
reports false or null. The merger test covers false, null, and all-true node
results.
##########
nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/state/connectors-listing/connectors-listing.effects.ts:
##########
@@ -433,6 +440,82 @@ export class ConnectorsListingEffects {
)
);
+ openChangeConnectorVersionDialog$ = createEffect(
+ () =>
+ this.actions$.pipe(
+ ofType(openChangeConnectorVersionDialog),
+ map((action) => action.request),
+ switchMap((request) =>
+
from(this.extensionTypesService.getConnectorVersionsForType(request.type,
request.bundle)).pipe(
+ map(
+ (response) =>
+ ({
+ fetchRequest: request,
+ componentVersions: response.connectorTypes
+ }) as OpenChangeComponentVersionDialogRequest
+ ),
+ catchError((errorResponse: HttpErrorResponse) => {
+ this.store.dispatch(
+ ErrorActions.snackBarError({
+ error:
this.errorHelper.getErrorString(errorResponse)
+ })
+ );
+ return EMPTY;
+ })
+ )
+ ),
+ tap((request) => {
+ const dialogRequest =
this.dialog.open(ChangeComponentVersionDialog, {
+ ...LARGE_DIALOG,
+ data: request,
+ autoFocus: false
+ });
+
+
dialogRequest.componentInstance.changeVersion.pipe(take(1)).subscribe((newVersion)
=> {
+ this.store.dispatch(
+ changeConnectorVersion({
+ request: {
+ id: request.fetchRequest.id,
+ uri: request.fetchRequest.uri,
+ payload: {
+ component: {
+ bundle: newVersion.bundle,
+ id: request.fetchRequest.id
+ },
+ revision: request.fetchRequest.revision
+ }
+ }
+ })
+ );
+ dialogRequest.close();
+ });
+ })
+ ),
+ { dispatch: false }
+ );
+
+ changeConnectorVersion$ = createEffect(() =>
+ this.actions$.pipe(
+ ofType(changeConnectorVersion),
+ map((action) => action.request),
+ concatMap((request) =>
Review Comment:
Addressed in 269a772c478. The listing now passes its `saving` state to the
connector table, and Change Version is unavailable while that state is true.
The table test covers the pending-request case.
##########
nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/components/connector/StandardConnectorNode.java:
##########
@@ -1310,6 +1318,126 @@ public Connector getConnector() {
return connectorDetails.getConnector();
}
+ @Override
+ public void verifyCanReload() {
+ if (!isStopped()) {
+ throw new IllegalStateException("Cannot reload " + this + "
because its state is " + getCurrentState());
+ }
+ }
+
+ @Override
+ public void verifyCanUpdateBundle(final BundleCoordinate
incomingCoordinate) {
+ final BundleCoordinate currentCoordinate = getBundleCoordinate();
+ if
(!currentCoordinate.getGroup().equals(incomingCoordinate.getGroup()) ||
!currentCoordinate.getId().equals(incomingCoordinate.getId())) {
+ throw new IllegalArgumentException("Cannot update " + this + "
from " + currentCoordinate.getCoordinate() + " to "
+ + incomingCoordinate.getCoordinate() + " because the bundle
group and artifact must be unchanged");
+ }
+ }
+
+ @Override
+ public void replaceConnector(final Connector replacement, final
BundleCoordinate replacementCoordinate, final ComponentLog replacementLog)
throws FlowUpdateException {
+ verifyCanReload();
+
+ final FrameworkConnectorInitializationContext
replacementInitializationContext = new
StandardConnectorInitializationContext.Builder()
+ .identifier(identifier)
+ .name(name)
+ .componentLog(replacementLog)
+ .secretsManager(initializationContext.getSecretsManager())
+ .assetManager(initializationContext.getAssetManager())
+
.componentBundleLookup(initializationContext.getComponentBundleLookup())
+ .build();
+
+ try (final NarCloseable ignored =
NarCloseable.withComponentNarLoader(replacement.getClass().getClassLoader())) {
+ replacement.initialize(replacementInitializationContext);
+ }
+
+ final WorkingFlowContextState workingContextState =
acquireWorkingFlowContext();
+ final FrameworkFlowContext workingContext =
workingContextState.getContext();
+ boolean workingContextReleased = false;
+ try {
+ final Map<String, StepConfiguration> originalActiveConfiguration =
toConfigurationMap(activeFlowContext.getConfigurationContext().toConnectorConfiguration());
+ final Map<String, StepConfiguration> originalWorkingConfiguration
= workingContext == null ? originalActiveConfiguration
+ :
toConfigurationMap(workingContext.getConfigurationContext().toConnectorConfiguration());
+
+ final Map<String, StepConfiguration> activeConfiguration =
migrateProperties(replacement, originalActiveConfiguration);
+ final Map<String, StepConfiguration> workingConfiguration =
migrateProperties(replacement, originalWorkingConfiguration);
+ final Bundle bundle = new Bundle(replacementCoordinate.getGroup(),
replacementCoordinate.getId(), replacementCoordinate.getVersion());
+
+ replaceConfiguration(activeFlowContext.getConfigurationContext(),
activeConfiguration);
Review Comment:
Addressed in 269a772c478. Configuration migration is now staged in separate
contexts before either live context is changed. `StandardFlowContext` publishes
configuration, bundle, log, and root facade through one reload state, and
connector metadata is published only after both context reloads and callbacks
succeed. Failures restore the original working context. Tests cover
configuration resolution, working-context reload, callback, and active-context
reload failures.
##########
nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/ui/connector-table/connector-table.component.ts:
##########
@@ -157,6 +159,20 @@ export class ConnectorTable {
return isConnectorActionAllowed(entity, 'PURGE_FLOWFILES');
}
+ canChangeVersion(entity: ConnectorEntity): boolean {
+ const versionChangeEligibleStates = [
+ ConnectorState.STOPPED,
+ ConnectorState.UPDATED,
+ ConnectorState.UPDATE_FAILED
+ ];
+ return (
+ this.canRead(entity) &&
+ this.canModify(entity) &&
+ versionChangeEligibleStates.includes(entity.component.state as
ConnectorState) &&
Review Comment:
Addressed in 269a772c478. `UPDATED` and `UPDATE_FAILED` now require an
aggregate active-thread count of exactly zero; `STOPPED` retains its prior
behavior. Tests cover active and quiescent cases for both update states.
--
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]