diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/access-policies/feature/access-policies.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/access-policies/feature/access-policies.component.ts index 1e0a2a4315..150899f686 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/access-policies/feature/access-policies.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/access-policies/feature/access-policies.component.ts @@ -19,6 +19,11 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { NiFiState } from '../../../state'; import { startCurrentUserPolling, stopCurrentUserPolling } from '../../../state/current-user/current-user.actions'; +import { + loadClusterSummary, + startClusterSummaryPolling, + stopClusterSummaryPolling +} from '../../../state/cluster-summary/cluster-summary.actions'; @Component({ selector: 'access-policies', @@ -29,10 +34,13 @@ export class AccessPolicies implements OnInit, OnDestroy { constructor(private store: Store) {} ngOnInit(): void { + this.store.dispatch(loadClusterSummary()); this.store.dispatch(startCurrentUserPolling()); + this.store.dispatch(startClusterSummaryPolling()); } ngOnDestroy(): void { + this.store.dispatch(stopClusterSummaryPolling()); this.store.dispatch(stopCurrentUserPolling()); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/access-policies/service/access-policy.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/access-policies/service/access-policy.service.ts index dfd87351bc..fe8f95ec6f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/access-policies/service/access-policy.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/access-policies/service/access-policy.service.ts @@ -16,12 +16,13 @@ */ import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Client } from '../../../service/client.service'; import { Observable } from 'rxjs'; import { AccessPolicyEntity, ComponentResourceAction, ResourceAction } from '../state/shared'; import { NiFiCommon } from '../../../service/nifi-common.service'; import { TenantEntity } from '../../../state/shared'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class AccessPolicyService { @@ -30,7 +31,8 @@ export class AccessPolicyService { constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} createAccessPolicy( @@ -53,6 +55,7 @@ export class AccessPolicyService { version: 0, clientId: this.client.getClientId() }, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { action: resourceAction.action, resource, @@ -81,6 +84,7 @@ export class AccessPolicyService { updateAccessPolicy(accessPolicy: AccessPolicyEntity, users: TenantEntity[], userGroups: TenantEntity[]) { const payload: unknown = { revision: this.client.getRevision(accessPolicy), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: accessPolicy.id, userGroups, @@ -92,8 +96,13 @@ export class AccessPolicyService { } deleteAccessPolicy(accessPolicy: AccessPolicyEntity): Observable { - const revision: any = this.client.getRevision(accessPolicy); - return this.httpClient.delete(this.nifiCommon.stripProtocol(accessPolicy.uri), { params: revision }); + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(accessPolicy), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(accessPolicy.uri), { params }); } getUsers(): Observable { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts index 3160a762a0..8dc3082b45 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts @@ -28,6 +28,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MoveComponentRequest, UpdateComponentRequest } from '../../state/flow'; import { Position } from '../../state/shared'; import { ComponentType } from '../../../../state/shared'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' @@ -44,7 +45,8 @@ export class DraggableBehavior { constructor( private store: Store, private client: Client, - private canvasUtils: CanvasUtils + private canvasUtils: CanvasUtils, + private clusterConnectionService: ClusterConnectionService ) { const self: DraggableBehavior = this; @@ -247,7 +249,7 @@ export class DraggableBehavior { * * @param {selection} the destination group */ - private updateComponentsGroup(group: any) { + private updateComponentsGroup(group: any): void { // get the selection and deselect the components being moved const selection: any = d3.selectAll('g.component.selected, g.connection.selected').classed('selected', false); @@ -308,6 +310,7 @@ export class DraggableBehavior { uri: d.uri, payload: { revision: this.client.getRevision(d), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: d.id, position: newPosition @@ -346,6 +349,7 @@ export class DraggableBehavior { uri: connection.uri, payload: { revision: this.client.getRevision(connection), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: connection.id, bends: newBends diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/controller-service.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/controller-service.service.ts index d1f547c992..a533cc2360 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/controller-service.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/controller-service.service.ts @@ -17,7 +17,7 @@ import { Injectable } from '@angular/core'; import { EMPTY, Observable } from 'rxjs'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Client } from '../../../service/client.service'; import { NiFiCommon } from '../../../service/nifi-common.service'; import { @@ -27,6 +27,7 @@ import { PropertyDescriptorRetriever } from '../../../state/shared'; import { ConfigureControllerServiceRequest, DeleteControllerServiceRequest } from '../state/controller-services'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class ControllerServiceService implements ControllerServiceCreator, PropertyDescriptorRetriever { @@ -35,7 +36,8 @@ export class ControllerServiceService implements ControllerServiceCreator, Prope constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getControllerServices(processGroupId: string): Observable { @@ -66,6 +68,7 @@ export class ControllerServiceService implements ControllerServiceCreator, Prope `${ControllerServiceService.API}/process-groups/${processGroupId}/controller-services`, { revision: createControllerService.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { bundle: createControllerService.controllerServiceBundle, type: createControllerService.controllerServiceType @@ -95,7 +98,12 @@ export class ControllerServiceService implements ControllerServiceCreator, Prope deleteControllerService(deleteControllerService: DeleteControllerServiceRequest): Observable { const entity: ControllerServiceEntity = deleteControllerService.controllerService; - const revision: any = this.client.getRevision(entity); - return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params: revision }); + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params }); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/flow.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/flow.service.ts index 9133eee2ad..30c305b173 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/flow.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/flow.service.ts @@ -17,7 +17,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { ComponentRunStatusRequest, CreateComponentRequest, @@ -47,6 +47,7 @@ import { import { ComponentType, PropertyDescriptorRetriever } from '../../../state/shared'; import { Client } from '../../../service/client.service'; import { NiFiCommon } from '../../../service/nifi-common.service'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class FlowService implements PropertyDescriptorRetriever { @@ -55,7 +56,8 @@ export class FlowService implements PropertyDescriptorRetriever { constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getFlow(processGroupId = 'root'): Observable { @@ -112,6 +114,7 @@ export class FlowService implements PropertyDescriptorRetriever { createFunnel(processGroupId = 'root', createFunnel: CreateComponentRequest): Observable { return this.httpClient.post(`${FlowService.API}/process-groups/${processGroupId}/funnels`, { revision: createFunnel.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { position: createFunnel.position } @@ -121,6 +124,7 @@ export class FlowService implements PropertyDescriptorRetriever { createLabel(processGroupId = 'root', createLabel: CreateComponentRequest): Observable { return this.httpClient.post(`${FlowService.API}/process-groups/${processGroupId}/labels`, { revision: createLabel.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { position: createLabel.position } @@ -134,6 +138,7 @@ export class FlowService implements PropertyDescriptorRetriever { createProcessor(processGroupId = 'root', createProcessor: CreateProcessorRequest): Observable { return this.httpClient.post(`${FlowService.API}/process-groups/${processGroupId}/processors`, { revision: createProcessor.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { position: createProcessor.position, type: createProcessor.processorType, @@ -152,6 +157,7 @@ export class FlowService implements PropertyDescriptorRetriever { createProcessGroup(processGroupId = 'root', createProcessGroup: CreateProcessGroupRequest): Observable { const payload: any = { revision: createProcessGroup.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { position: createProcessGroup.position, name: createProcessGroup.name @@ -173,6 +179,7 @@ export class FlowService implements PropertyDescriptorRetriever { ): Observable { const payload: any = { revision: createRemoteProcessGroup.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { position: createRemoteProcessGroup.position, targetUris: createRemoteProcessGroup.targetUris, @@ -200,6 +207,10 @@ export class FlowService implements PropertyDescriptorRetriever { payload.append('positionX', uploadProcessGroup.position.x.toString()); payload.append('positionY', uploadProcessGroup.position.y.toString()); payload.append('clientId', uploadProcessGroup.revision.clientId); + payload.append( + 'disconnectedNodeAcknowledged', + String(this.clusterConnectionService.isDisconnectionAcknowledged()) + ); payload.append('file', uploadProcessGroup.flowDefinition); return this.httpClient.post( @@ -222,6 +233,7 @@ export class FlowService implements PropertyDescriptorRetriever { const portType: string = ComponentType.InputPort == createPort.type ? 'input-ports' : 'output-ports'; return this.httpClient.post(`${FlowService.API}/process-groups/${processGroupId}/${portType}`, { revision: createPort.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { position: createPort.position, name: createPort.name, @@ -235,17 +247,25 @@ export class FlowService implements PropertyDescriptorRetriever { } deleteComponent(deleteComponent: DeleteComponentRequest): Observable { - const revision: any = this.client.getRevision(deleteComponent.entity); - return this.httpClient.delete(this.nifiCommon.stripProtocol(deleteComponent.uri), { params: revision }); + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(deleteComponent.entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(deleteComponent.uri), { params }); } createSnippet(snippet: Snippet): Observable { - return this.httpClient.post(`${FlowService.API}/snippets`, { snippet }); + return this.httpClient.post(`${FlowService.API}/snippets`, { + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), + snippet + }); } moveSnippet(snippetId: string, groupId: string): Observable { const payload: any = { - // 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), snippet: { id: snippetId, parentGroupId: groupId @@ -255,7 +275,12 @@ export class FlowService implements PropertyDescriptorRetriever { } deleteSnippet(snippetId: string): Observable { - return this.httpClient.delete(`${FlowService.API}/snippets/${snippetId}`); + const params = new HttpParams({ + fromObject: { + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(`${FlowService.API}/snippets/${snippetId}`, { params }); } replayLastProvenanceEvent(request: ReplayLastProvenanceEventRequest): Observable { @@ -265,7 +290,7 @@ export class FlowService implements PropertyDescriptorRetriever { runOnce(request: RunOnceRequest): Observable { const startRequest: ComponentRunStatusRequest = { revision: request.revision, - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: 'RUN_ONCE' }; return this.httpClient.put(`${this.nifiCommon.stripProtocol(request.uri)}/run-status`, startRequest); @@ -274,7 +299,7 @@ export class FlowService implements PropertyDescriptorRetriever { startComponent(request: StartComponentRequest): Observable { const startRequest: ComponentRunStatusRequest = { revision: request.revision, - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: request.type === ComponentType.RemoteProcessGroup ? 'TRANSMITTING' : 'RUNNING' }; return this.httpClient.put(`${this.nifiCommon.stripProtocol(request.uri)}/run-status`, startRequest); @@ -283,7 +308,7 @@ export class FlowService implements PropertyDescriptorRetriever { stopComponent(request: StopComponentRequest): Observable { const stopRequest: ComponentRunStatusRequest = { revision: request.revision, - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: 'STOPPED' }; return this.httpClient.put(`${this.nifiCommon.stripProtocol(request.uri)}/run-status`, stopRequest); @@ -292,7 +317,7 @@ export class FlowService implements PropertyDescriptorRetriever { startProcessGroup(request: StartProcessGroupRequest): Observable { const startRequest: ProcessGroupRunStatusRequest = { id: request.id, - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: 'RUNNING' }; return this.httpClient.put(`${FlowService.API}/flow/process-groups/${request.id}`, startRequest); @@ -300,7 +325,7 @@ export class FlowService implements PropertyDescriptorRetriever { startRemoteProcessGroupsInProcessGroup(request: StartProcessGroupRequest): Observable { const startRequest = { - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: 'TRANSMITTING' }; return this.httpClient.put( @@ -312,7 +337,7 @@ export class FlowService implements PropertyDescriptorRetriever { stopProcessGroup(request: StopProcessGroupRequest): Observable { const stopRequest: ProcessGroupRunStatusRequest = { id: request.id, - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: 'STOPPED' }; return this.httpClient.put(`${FlowService.API}/flow/process-groups/${request.id}`, stopRequest); @@ -320,7 +345,7 @@ export class FlowService implements PropertyDescriptorRetriever { stopRemoteProcessGroupsInProcessGroup(request: StopProcessGroupRequest): Observable { const stopRequest = { - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: 'STOPPED' }; return this.httpClient.put( @@ -338,7 +363,7 @@ export class FlowService implements PropertyDescriptorRetriever { saveToFlowRegistry(request: SaveToVersionControlRequest): Observable { const saveRequest = { ...request, - disconnectedNodeAcknowledged: false + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() }; return this.httpClient.post( @@ -351,7 +376,7 @@ export class FlowService implements PropertyDescriptorRetriever { const params: any = { version: request.revision.version, clientId: request.revision.clientId, - disconnectedNodeAcknowledged: false + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() }; return this.httpClient.delete(`${FlowService.API}/versions/process-groups/${request.processGroupId}`, { params diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.spec.ts index f369a961d4..c334a35f86 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.spec.ts @@ -36,6 +36,7 @@ import { selectFlowConfiguration } from '../../../../state/flow-configuration/fl import * as fromFlowConfiguration from '../../../../state/flow-configuration/flow-configuration.reducer'; import { queueFeatureKey } from '../../../queue/state'; import * as fromQueue from '../../state/queue/queue.reducer'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; describe('ConnectionManager', () => { let service: ConnectionManager; @@ -71,7 +72,13 @@ describe('ConnectionManager', () => { value: fromFlowConfiguration.initialState.flowConfiguration } ] - }) + }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } ] }); service = TestBed.inject(ConnectionManager); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts index d73de8a2d8..5debbbc881 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts @@ -47,6 +47,7 @@ import { loadBalanceStrategies, UpdateComponentRequest } from '../../state/flow' import { filter, switchMap } from 'rxjs'; import { NiFiCommon } from '../../../../service/nifi-common.service'; import { QuickSelectBehavior } from '../behavior/quick-select-behavior.service'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; export class ConnectionRenderOptions { updatePath?: boolean; @@ -98,7 +99,8 @@ export class ConnectionManager { private client: Client, private selectableBehavior: SelectableBehavior, private transitionBehavior: TransitionBehavior, - private quickSelectBehavior: QuickSelectBehavior + private quickSelectBehavior: QuickSelectBehavior, + private clusterConnectionService: ClusterConnectionService ) {} /** @@ -350,6 +352,7 @@ export class ConnectionManager { uri: d.uri, payload: { revision: this.client.getRevision(d), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: connection }, restoreOnFailure: restoreOnFailure @@ -1974,7 +1977,7 @@ export class ConnectionManager { const payload: any = { revision: self.client.getRevision(connectionData), - // TODO - 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(), + disconnectedNodeAcknowledged: self.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: connectionData.id, destination: { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.spec.ts index 94d58725ef..517ae0dc3f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.spec.ts @@ -36,6 +36,7 @@ import { selectFlowConfiguration } from '../../../../state/flow-configuration/fl import * as fromFlowConfiguration from '../../../../state/flow-configuration/flow-configuration.reducer'; import { queueFeatureKey } from '../../../queue/state'; import * as fromQueue from '../../state/queue/queue.reducer'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; describe('LabelManager', () => { let service: LabelManager; @@ -71,7 +72,13 @@ describe('LabelManager', () => { value: fromFlowConfiguration.initialState.flowConfiguration } ] - }) + }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } ] }); service = TestBed.inject(LabelManager); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts index 973eb5802b..2aa98d4f85 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts @@ -37,6 +37,7 @@ import { ComponentType } from '../../../../state/shared'; import { UpdateComponentRequest } from '../../state/flow'; import { filter, switchMap } from 'rxjs'; import { NiFiCommon } from '../../../../service/nifi-common.service'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' @@ -62,6 +63,7 @@ export class LabelManager { private canvasUtils: CanvasUtils, private nifiCommon: NiFiCommon, private client: Client, + private clusterConnectionService: ClusterConnectionService, private positionBehavior: PositionBehavior, private selectableBehavior: SelectableBehavior, private quickSelectBehavior: QuickSelectBehavior, @@ -343,6 +345,7 @@ export class LabelManager { uri: labelData.uri, payload: { revision: self.client.getRevision(labelData), + disconnectedNodeAcknowledged: self.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: labelData.id, width: labelData.dimensions.width, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts index 881a59e608..08dc0af1c7 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts @@ -31,6 +31,7 @@ import * as ErrorActions from '../../../state/error/error.actions'; import * as ParameterActions from '../state/parameter/parameter.actions'; import { FlowService } from './flow.service'; import { MEDIUM_DIALOG } from '../../../index'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' @@ -41,6 +42,7 @@ export class ParameterHelperService { private store: Store, private flowService: FlowService, private parameterService: ParameterService, + private clusterConnectionService: ClusterConnectionService, private client: Client ) {} @@ -120,6 +122,8 @@ export class ParameterHelperService { id: parameterContextId, payload: { revision: this.client.getRevision(parameterContextEntity), + disconnectedNodeAcknowledged: + this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: parameterContextEntity.id, parameters: [{ parameter: dialogResponse.parameter }] diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter.service.ts index 9bdf082039..7572550a21 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter.service.ts @@ -17,9 +17,10 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { NiFiCommon } from '../../../service/nifi-common.service'; import { ParameterContextUpdateRequest, SubmitParameterContextUpdate } from '../../../state/shared'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class ParameterService { @@ -27,7 +28,8 @@ export class ParameterService { constructor( private httpClient: HttpClient, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getParameterContext(id: string, includeInheritedParameters: boolean): Observable { @@ -50,6 +52,11 @@ export class ParameterService { } deleteParameterContextUpdate(updateRequest: ParameterContextUpdateRequest): Observable { - return this.httpClient.delete(this.nifiCommon.stripProtocol(updateRequest.uri)); + const params = new HttpParams({ + fromObject: { + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(updateRequest.uri), { params }); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/resolver/controller-service-advanced-ui-params.resolver.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/resolver/controller-service-advanced-ui-params.resolver.ts index 7db25d3f98..9abc02c9af 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/resolver/controller-service-advanced-ui-params.resolver.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/resolver/controller-service-advanced-ui-params.resolver.ts @@ -26,6 +26,7 @@ import { selectService } from '../../state/controller-services/controller-servic import { ControllerServiceService } from '../controller-service.service'; import { HttpErrorResponse } from '@angular/common/http'; import { fullScreenError } from '../../../../state/error/error.actions'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; export const controllerServiceAdvancedUiParamsResolver: ResolveFn = ( route: ActivatedRouteSnapshot @@ -33,6 +34,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn = inject(Store); const controllerServiceService: ControllerServiceService = inject(ControllerServiceService); const client: Client = inject(Client); + const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService); // getting id parameter from activated route because ngrx router store // is not initialized when this resolver executes @@ -72,7 +74,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn = (route: ActivatedRouteSnapshot) => { const store: Store = inject(Store); const flowService: FlowService = inject(FlowService); const client: Client = inject(Client); + const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService); // getting id parameter from activated route because ngrx router store // is not initialized when this resolver executes @@ -73,7 +75,7 @@ export const processorAdvancedUiParamsResolver: ResolveFn = (r clientId: revision.clientId, revision: revision.version, editable, - disconnectedNodeAcknowledged: false // TODO + disconnectedNodeAcknowledged: clusterConnectionService.isDisconnectionAcknowledged() } as AdvancedUiParams; }), take(1) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/manage-remote-ports/manage-remote-ports.effects.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/manage-remote-ports/manage-remote-ports.effects.ts index c792b255eb..eb5c3e3479 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/manage-remote-ports/manage-remote-ports.effects.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/manage-remote-ports/manage-remote-ports.effects.ts @@ -35,6 +35,7 @@ import { ComponentType, isDefinedAndNotNull } from '../../../../state/shared'; import { selectTimeOffset } from '../../../../state/flow-configuration/flow-configuration.selectors'; import { selectAbout } from '../../../../state/about/about.selectors'; import { MEDIUM_DIALOG } from '../../../../index'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; @Injectable() export class ManageRemotePortsEffects { @@ -44,7 +45,8 @@ export class ManageRemotePortsEffects { private manageRemotePortService: ManageRemotePortService, private errorHelper: ErrorHelper, private dialog: MatDialog, - private router: Router + private router: Router, + private clusterConnectionService: ClusterConnectionService ) {} loadRemotePorts$ = createEffect(() => @@ -136,7 +138,7 @@ export class ManageRemotePortsEffects { .updateRemotePortTransmission({ portId: request.port.id, rpg: request.rpg, - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), type: request.port.type, state: 'TRANSMITTING' }) @@ -165,7 +167,7 @@ export class ManageRemotePortsEffects { .updateRemotePortTransmission({ portId: request.port.id, rpg: request.rpg, - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), type: request.port.type, state: 'STOPPED' }) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts index 2105d8cf21..f6b7c11b20 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts @@ -36,9 +36,17 @@ export class FlowStatus { @Input() controllerStatus: ControllerStatus = initialState.flowStatus.controllerStatus; @Input() lastRefreshed: string = initialState.flow.processGroupFlow.lastRefreshed; @Input() clusterSummary: ClusterSummary | null = null; - @Input() bulletins: BulletinEntity[] = initialState.controllerBulletins.bulletins; @Input() currentProcessGroupId: string = initialState.id; @Input() loadingStatus = false; + @Input() set bulletins(bulletins: BulletinEntity[]) { + if (bulletins) { + this.filteredBulletins = bulletins.filter((bulletin) => bulletin.canRead); + } else { + this.filteredBulletins = []; + } + } + + private filteredBulletins: BulletinEntity[] = initialState.controllerBulletins.bulletins; protected readonly BulletinsTip = BulletinsTip; @@ -112,12 +120,12 @@ export class FlowStatus { } hasBulletins(): boolean { - return this.bulletins.length > 0; + return this.filteredBulletins.length > 0; } getBulletins(): BulletinsTipInput { return { - bulletins: this.bulletins + bulletins: this.filteredBulletins }; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.spec.ts index 3497a880e8..49c6307e95 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.spec.ts @@ -25,6 +25,7 @@ import { CreateConnectionDialogRequest } from '../../../../../state/flow'; import { ComponentType, DocumentedType } from '../../../../../../../state/shared'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { of } from 'rxjs'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; describe('CreateConnection', () => { let component: CreateConnection; @@ -367,7 +368,16 @@ describe('CreateConnection', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [CreateConnection, NoopAnimationsModule], - providers: [{ provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState })] + providers: [ + { provide: MAT_DIALOG_DATA, useValue: data }, + provideMockStore({ initialState }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } + ] }); fixture = TestBed.createComponent(CreateConnection); component = fixture.componentInstance; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts index 1e34bf267f..669d8c5be8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts @@ -45,7 +45,6 @@ import { SourceProcessor } from '../source/source-processor/source-processor.com import { DestinationFunnel } from '../destination/destination-funnel/destination-funnel.component'; import { createConnection } from '../../../../../state/flow/flow.actions'; import { Client } from '../../../../../../../service/client.service'; -import { CanvasUtils } from '../../../../../service/canvas-utils.service'; import { SourceFunnel } from '../source/source-funnel/source-funnel.component'; import { DestinationProcessor } from '../destination/destination-processor/destination-processor.component'; import { DestinationOutputPort } from '../destination/destination-output-port/destination-output-port.component'; @@ -56,6 +55,8 @@ import { DestinationProcessGroup } from '../destination/destination-process-grou import { SourceRemoteProcessGroup } from '../source/source-remote-process-group/source-remote-process-group.component'; import { DestinationRemoteProcessGroup } from '../destination/destination-remote-process-group/destination-remote-process-group.component'; import { BreadcrumbEntity } from '../../../../../state/shared'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; +import { CanvasUtils } from '../../../../../service/canvas-utils.service'; @Component({ selector: 'create-connection', @@ -114,6 +115,8 @@ export class CreateConnection { } } + protected readonly loadBalanceStrategies = loadBalanceStrategies; + protected readonly loadBalanceCompressionStrategies = loadBalanceCompressionStrategies; protected readonly ComponentType = ComponentType; protected readonly TextTip = TextTip; @@ -136,6 +139,7 @@ export class CreateConnection { private formBuilder: FormBuilder, private store: Store, private canvasUtils: CanvasUtils, + private clusterConnectionService: ClusterConnectionService, private client: Client ) { this.source = dialogRequest.request.source; @@ -230,6 +234,7 @@ export class CreateConnection { version: 0, clientId: this.client.getClientId() }, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { backPressureDataSizeThreshold: this.createConnectionForm.get('backPressureDataSizeThreshold')?.value, backPressureObjectThreshold: this.createConnectionForm.get('backPressureObjectThreshold')?.value, @@ -299,7 +304,4 @@ export class CreateConnection { }) ); } - - protected readonly loadBalanceStrategies = loadBalanceStrategies; - protected readonly loadBalanceCompressionStrategies = loadBalanceCompressionStrategies; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.spec.ts index 29dddef2f1..1808624122 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.spec.ts @@ -25,6 +25,7 @@ import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY } from 'rxjs'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; describe('ImportFromRegistry', () => { let component: ImportFromRegistry; @@ -112,7 +113,16 @@ describe('ImportFromRegistry', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [ImportFromRegistry, NoopAnimationsModule], - providers: [{ provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState })] + providers: [ + { provide: MAT_DIALOG_DATA, useValue: data }, + provideMockStore({ initialState }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } + ] }); fixture = TestBed.createComponent(ImportFromRegistry); component = fixture.componentInstance; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.ts index f6935b4306..8dd2a3d14a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.ts @@ -53,6 +53,7 @@ import { selectTimeOffset } from '../../../../../../../state/flow-configuration/ import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Client } from '../../../../../../../service/client.service'; import { importFromRegistry } from '../../../../../state/flow/flow.actions'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; @Component({ selector: 'import-from-registry', @@ -117,7 +118,8 @@ export class ImportFromRegistry implements OnInit { private formBuilder: FormBuilder, private store: Store, private nifiCommon: NiFiCommon, - private client: Client + private client: Client, + private clusterConnectionService: ClusterConnectionService ) { this.store .select(selectTimeOffset) @@ -309,7 +311,7 @@ export class ImportFromRegistry implements OnInit { version: 0 } }), - // disconnectedNodeAcknowledged: nfStorage.isDisconnectionAcknowledged(), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { position: { x: this.dialogRequest.request.position.x, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.spec.ts index bff4f6b464..b77298bf16 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.spec.ts @@ -24,6 +24,7 @@ import { ComponentType } from '../../../../../../../state/shared'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; describe('EditPort', () => { let component: EditPort; @@ -96,7 +97,16 @@ describe('EditPort', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [EditPort, NoopAnimationsModule], - providers: [{ provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState })] + providers: [ + { provide: MAT_DIALOG_DATA, useValue: data }, + provideMockStore({ initialState }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } + ] }); fixture = TestBed.createComponent(EditPort); component = fixture.componentInstance; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts index 8b3247f265..b1a5e5a9ab 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts @@ -31,6 +31,7 @@ import { MatButtonModule } from '@angular/material/button'; import { AsyncPipe } from '@angular/common'; import { selectSaving } from '../../../../../state/flow/flow.selectors'; import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nifi-spinner.directive'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; @Component({ selector: 'edit-port', @@ -58,7 +59,8 @@ export class EditPort { @Inject(MAT_DIALOG_DATA) public request: EditComponentDialogRequest, private formBuilder: FormBuilder, private store: Store, - private client: Client + private client: Client, + private clusterConnectionService: ClusterConnectionService ) { // set the port type name if (ComponentType.InputPort == this.request.type) { @@ -82,6 +84,7 @@ export class EditPort { editPort() { const payload: any = { revision: this.client.getRevision(this.request.entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: this.request.entity.id, name: this.editPortForm.get('name')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.spec.ts index 7365b89420..2d4086c000 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.spec.ts @@ -20,6 +20,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { EditProcessGroup } from './edit-process-group.component'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; describe('EditProcessGroup', () => { let component: EditProcessGroup; @@ -107,7 +108,15 @@ describe('EditProcessGroup', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [EditProcessGroup, NoopAnimationsModule], - providers: [{ provide: MAT_DIALOG_DATA, useValue: data }] + providers: [ + { provide: MAT_DIALOG_DATA, useValue: data }, + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } + ] }); fixture = TestBed.createComponent(EditProcessGroup); component = fixture.componentInstance; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts index 9fbec0c927..c152c279bd 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts @@ -35,6 +35,7 @@ import { TextTip } from '../../../../../../../ui/common/tooltips/text-tip/text-t import { ParameterContextEntity } from '../../../../../../parameter-contexts/state/parameter-context-listing'; import { ControllerServiceTable } from '../../../../../../../ui/common/controller-service/controller-service-table/controller-service-table.component'; import { EditComponentDialogRequest } from '../../../../../state/flow'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; @Component({ selector: 'edit-process-group', @@ -151,7 +152,8 @@ export class EditProcessGroup { constructor( @Inject(MAT_DIALOG_DATA) public request: EditComponentDialogRequest, private formBuilder: FormBuilder, - private client: Client + private client: Client, + private clusterConnectionService: ClusterConnectionService ) { this.parameterContextsOptions.push({ text: 'No parameter context', @@ -199,6 +201,7 @@ export class EditProcessGroup { const payload: any = { revision: this.client.getRevision(this.request.entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), processGroupUpdateStrategy: updateStrategy, component: { id: this.request.entity.id, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.spec.ts index c811960007..1ba82720c0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.spec.ts @@ -25,6 +25,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Component } from '@angular/core'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../../../state/error/error.reducer'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; describe('EditProcessor', () => { let component: EditProcessor; @@ -736,7 +737,13 @@ describe('EditProcessor', () => { { provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState - }) + }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } ] }); fixture = TestBed.createComponent(EditProcessor); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts index 878b3e6d5c..09bee2d8e8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts @@ -48,6 +48,7 @@ import { RelationshipSettings } from './relationship-settings/relationship-settings.component'; import { ErrorBanner } from '../../../../../../../ui/common/error-banner/error-banner.component'; +import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; @Component({ selector: 'edit-processor', @@ -147,6 +148,7 @@ export class EditProcessor { @Inject(MAT_DIALOG_DATA) public request: EditComponentDialogRequest, private formBuilder: FormBuilder, private client: Client, + private clusterConnectionService: ClusterConnectionService, private nifiCommon: NiFiCommon ) { const processorProperties: any = request.entity.component.config.properties; @@ -291,6 +293,7 @@ export class EditProcessor { const payload: any = { revision: this.client.getRevision(this.request.entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: this.request.entity.id, name: this.editProcessorForm.get('name')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.spec.ts index 078fb0e334..9f8476be66 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.spec.ts @@ -24,6 +24,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EditComponentDialogRequest } from '../../../state/flow'; import { ComponentType } from '../../../../../state/shared'; import { initialState } from '../../../state/manage-remote-ports/manage-remote-ports.reducer'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; describe('EditRemotePortComponent', () => { let component: EditRemotePortComponent; @@ -50,7 +51,16 @@ describe('EditRemotePortComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [EditRemotePortComponent, NoopAnimationsModule], - providers: [{ provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState })] + providers: [ + { provide: MAT_DIALOG_DATA, useValue: data }, + provideMockStore({ initialState }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } + ] }); fixture = TestBed.createComponent(EditRemotePortComponent); component = fixture.componentInstance; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.ts index d07f664d0d..82d4b11b61 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.ts @@ -31,6 +31,7 @@ import { Client } from '../../../../../service/client.service'; import { ComponentType } from '../../../../../state/shared'; import { PortSummary } from '../../../state/manage-remote-ports'; import { configureRemotePort } from '../../../state/manage-remote-ports/manage-remote-ports.actions'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; @Component({ standalone: true, @@ -57,7 +58,8 @@ export class EditRemotePortComponent { @Inject(MAT_DIALOG_DATA) public request: EditRemotePortDialogRequest, private formBuilder: FormBuilder, private store: Store, - private client: Client + private client: Client, + private clusterConnectionService: ClusterConnectionService ) { // set the port type name if (ComponentType.InputPort == this.request.type) { @@ -79,7 +81,7 @@ export class EditRemotePortComponent { editRemotePort() { const payload: any = { revision: this.client.getRevision(this.request.rpg), - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), type: this.request.type, remoteProcessGroupPort: { concurrentlySchedulableTaskCount: this.editPortForm.get('concurrentTasks')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/feature/parameter-contexts.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/feature/parameter-contexts.component.ts index 4afc041cd3..b5c62fe996 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/feature/parameter-contexts.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/feature/parameter-contexts.component.ts @@ -19,6 +19,11 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { NiFiState } from '../../../state'; import { startCurrentUserPolling, stopCurrentUserPolling } from '../../../state/current-user/current-user.actions'; +import { + loadClusterSummary, + startClusterSummaryPolling, + stopClusterSummaryPolling +} from '../../../state/cluster-summary/cluster-summary.actions'; @Component({ selector: 'parameter-contexts', @@ -29,10 +34,13 @@ export class ParameterContexts implements OnInit, OnDestroy { constructor(private store: Store) {} ngOnInit(): void { + this.store.dispatch(loadClusterSummary()); this.store.dispatch(startCurrentUserPolling()); + this.store.dispatch(startClusterSummaryPolling()); } ngOnDestroy(): void { + this.store.dispatch(stopClusterSummaryPolling()); this.store.dispatch(stopCurrentUserPolling()); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/service/parameter-contexts.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/service/parameter-contexts.service.ts index b71a28752d..cc2dd0b567 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/service/parameter-contexts.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/service/parameter-contexts.service.ts @@ -17,7 +17,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Client } from '../../../service/client.service'; import { NiFiCommon } from '../../../service/nifi-common.service'; import { @@ -26,6 +26,7 @@ import { ParameterContextEntity } from '../state/parameter-context-listing'; import { ParameterContextUpdateRequest, SubmitParameterContextUpdate } from '../../../state/shared'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class ParameterContextService { @@ -34,7 +35,8 @@ export class ParameterContextService { constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getParameterContexts(): Observable { @@ -68,14 +70,22 @@ export class ParameterContextService { } deleteParameterContextUpdate(updateRequest: ParameterContextUpdateRequest): Observable { - return this.httpClient.delete(this.nifiCommon.stripProtocol(updateRequest.uri)); + const params = new HttpParams({ + fromObject: { + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(updateRequest.uri), { params }); } deleteParameterContext(deleteParameterContext: DeleteParameterContextRequest): Observable { const entity: ParameterContextEntity = deleteParameterContext.parameterContext; - const revision: any = this.client.getRevision(entity); - return this.httpClient.delete(`${ParameterContextService.API}/parameter-contexts/${entity.id}`, { - params: revision + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } }); + return this.httpClient.delete(`${ParameterContextService.API}/parameter-contexts/${entity.id}`, { params }); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.spec.ts index f0c8107822..6358da10e9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.spec.ts @@ -24,6 +24,7 @@ import { of } from 'rxjs'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../state/parameter-context-listing/parameter-context-listing.reducer'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; describe('EditParameterContext', () => { let component: EditParameterContext; @@ -235,7 +236,16 @@ describe('EditParameterContext', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [EditParameterContext, NoopAnimationsModule], - providers: [{ provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState })] + providers: [ + { provide: MAT_DIALOG_DATA, useValue: data }, + provideMockStore({ initialState }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } + ] }); fixture = TestBed.createComponent(EditParameterContext); component = fixture.componentInstance; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts index 123c703a87..068c91992f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts @@ -41,6 +41,7 @@ import { ParameterContextInheritance } from '../parameter-context-inheritance/pa import { ParameterReferences } from '../../../../../ui/common/parameter-references/parameter-references.component'; import { RouterLink } from '@angular/router'; import { ErrorBanner } from '../../../../../ui/common/error-banner/error-banner.component'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; @Component({ selector: 'edit-parameter-context', @@ -86,7 +87,8 @@ export class EditParameterContext { constructor( @Inject(MAT_DIALOG_DATA) public request: EditParameterContextRequest, private formBuilder: FormBuilder, - private client: Client + private client: Client, + private clusterConnectionService: ClusterConnectionService ) { if (request.parameterContext) { this.isNew = false; @@ -131,6 +133,7 @@ export class EditParameterContext { version: 0, clientId: this.client.getClientId() }, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { name: this.editParameterContextForm.get('name')?.value, description: this.editParameterContextForm.get('description')?.value, @@ -152,6 +155,7 @@ export class EditParameterContext { const payload: any = { revision: this.client.getRevision(pc), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: pc.id, name: this.editParameterContextForm.get('name')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/feature/settings.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/feature/settings.component.ts index ecacf6f38b..813bb1445e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/feature/settings.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/feature/settings.component.ts @@ -20,6 +20,11 @@ import { Store } from '@ngrx/store'; import { NiFiState } from '../../../state'; import { startCurrentUserPolling, stopCurrentUserPolling } from '../../../state/current-user/current-user.actions'; import { loadExtensionTypesForSettings } from '../../../state/extension-types/extension-types.actions'; +import { + loadClusterSummary, + startClusterSummaryPolling, + stopClusterSummaryPolling +} from '../../../state/cluster-summary/cluster-summary.actions'; @Component({ selector: 'settings', @@ -57,11 +62,14 @@ export class Settings implements OnInit, OnDestroy { constructor(private store: Store) {} ngOnInit(): void { + this.store.dispatch(loadClusterSummary()); this.store.dispatch(startCurrentUserPolling()); + this.store.dispatch(startClusterSummaryPolling()); this.store.dispatch(loadExtensionTypesForSettings()); } ngOnDestroy(): void { + this.store.dispatch(stopClusterSummaryPolling()); this.store.dispatch(stopCurrentUserPolling()); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/flow-analysis-rule.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/flow-analysis-rule.service.ts index c15ae5072c..3f3dc78df6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/flow-analysis-rule.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/flow-analysis-rule.service.ts @@ -17,7 +17,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Client } from '../../../service/client.service'; import { NiFiCommon } from '../../../service/nifi-common.service'; import { @@ -28,6 +28,7 @@ import { FlowAnalysisRuleEntity } from '../state/flow-analysis-rules'; import { PropertyDescriptorRetriever } from '../../../state/shared'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class FlowAnalysisRuleService implements PropertyDescriptorRetriever { @@ -36,7 +37,8 @@ export class FlowAnalysisRuleService implements PropertyDescriptorRetriever { constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getFlowAnalysisRule(): Observable { @@ -46,6 +48,7 @@ export class FlowAnalysisRuleService implements PropertyDescriptorRetriever { createFlowAnalysisRule(createFlowAnalysisRule: CreateFlowAnalysisRuleRequest): Observable { return this.httpClient.post(`${FlowAnalysisRuleService.API}/controller/flow-analysis-rules`, { revision: createFlowAnalysisRule.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { bundle: createFlowAnalysisRule.flowAnalysisRuleBundle, type: createFlowAnalysisRule.flowAnalysisRuleType @@ -55,8 +58,13 @@ export class FlowAnalysisRuleService implements PropertyDescriptorRetriever { deleteFlowAnalysisRule(deleteFlowAnalysisRule: DeleteFlowAnalysisRuleRequest): Observable { const entity: FlowAnalysisRuleEntity = deleteFlowAnalysisRule.flowAnalysisRule; - const revision: any = this.client.getRevision(entity); - return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params: revision }); + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params }); } getPropertyDescriptor(id: string, propertyName: string, sensitive: boolean): Observable { @@ -80,6 +88,7 @@ export class FlowAnalysisRuleService implements PropertyDescriptorRetriever { const entity: FlowAnalysisRuleEntity = flowAnalysisRule.flowAnalysisRule; return this.httpClient.put(`${this.nifiCommon.stripProtocol(entity.uri)}/run-status`, { revision: this.client.getRevision(entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: enabled ? 'ENABLED' : 'DISABLED', uiOnly: true }); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/management-controller-service.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/management-controller-service.service.ts index 9c0f3f968e..88bf49927f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/management-controller-service.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/management-controller-service.service.ts @@ -17,7 +17,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { ConfigureControllerServiceRequest, DeleteControllerServiceRequest @@ -30,6 +30,7 @@ import { CreateControllerServiceRequest, PropertyDescriptorRetriever } from '../../../state/shared'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class ManagementControllerServiceService implements ControllerServiceCreator, PropertyDescriptorRetriever { @@ -38,7 +39,8 @@ export class ManagementControllerServiceService implements ControllerServiceCrea constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getControllerServices(): Observable { @@ -51,6 +53,7 @@ export class ManagementControllerServiceService implements ControllerServiceCrea createControllerService(createControllerService: CreateControllerServiceRequest): Observable { return this.httpClient.post(`${ManagementControllerServiceService.API}/controller/controller-services`, { revision: createControllerService.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { bundle: createControllerService.controllerServiceBundle, type: createControllerService.controllerServiceType @@ -84,7 +87,12 @@ export class ManagementControllerServiceService implements ControllerServiceCrea deleteControllerService(deleteControllerService: DeleteControllerServiceRequest): Observable { const entity: ControllerServiceEntity = deleteControllerService.controllerService; - const revision: any = this.client.getRevision(entity); - return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params: revision }); + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params }); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/parameter-provider.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/parameter-provider.service.ts index 1aeba9a907..a3ab72e6a4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/parameter-provider.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/parameter-provider.service.ts @@ -16,7 +16,7 @@ */ import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Client } from '../../../service/client.service'; import { NiFiCommon } from '../../../service/nifi-common.service'; import { Observable } from 'rxjs'; @@ -30,6 +30,7 @@ import { ParameterProviderParameterApplicationEntity } from '../state/parameter-providers'; import { PropertyDescriptorRetriever } from '../../../state/shared'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class ParameterProviderService implements PropertyDescriptorRetriever { @@ -38,7 +39,8 @@ export class ParameterProviderService implements PropertyDescriptorRetriever { constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getParameterProviders(): Observable { @@ -52,6 +54,7 @@ export class ParameterProviderService implements PropertyDescriptorRetriever { createParameterProvider(request: CreateParameterProviderRequest) { return this.httpClient.post(`${ParameterProviderService.API}/controller/parameter-providers`, { revision: request.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { bundle: request.parameterProviderBundle, type: request.parameterProviderType @@ -61,11 +64,12 @@ export class ParameterProviderService implements PropertyDescriptorRetriever { deleteParameterProvider(request: DeleteParameterProviderRequest) { const entity: ParameterProviderEntity = request.parameterProvider; - const revision: any = this.client.getRevision(entity); - const params: any = { - ...revision, - disconnectedNodeAcknowledged: false - }; + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params }); } @@ -88,9 +92,10 @@ export class ParameterProviderService implements PropertyDescriptorRetriever { `${ParameterProviderService.API}/parameter-providers/${request.id}/parameters/fetch-requests`, { id: request.id, - revision: request.revision + revision: request.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() }, - { params: { disconnectedNodeAcknowledged: false } } + { params: { disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() } } ); } @@ -110,6 +115,11 @@ export class ParameterProviderService implements PropertyDescriptorRetriever { deleteParameterProviderParametersUpdateRequest( updateRequest: ParameterProviderApplyParametersRequest ): Observable { - return this.httpClient.delete(this.nifiCommon.stripProtocol(updateRequest.uri)); + const params = new HttpParams({ + fromObject: { + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(updateRequest.uri), { params }); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/registry-client.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/registry-client.service.ts index 514043c7a7..20aae30f10 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/registry-client.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/registry-client.service.ts @@ -17,7 +17,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Client } from '../../../service/client.service'; import { NiFiCommon } from '../../../service/nifi-common.service'; import { @@ -26,6 +26,7 @@ import { EditRegistryClientRequest } from '../state/registry-clients'; import { PropertyDescriptorRetriever, RegistryClientEntity } from '../../../state/shared'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class RegistryClientService implements PropertyDescriptorRetriever { @@ -34,7 +35,8 @@ export class RegistryClientService implements PropertyDescriptorRetriever { constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getRegistryClients(): Observable { @@ -61,7 +63,12 @@ export class RegistryClientService implements PropertyDescriptorRetriever { deleteRegistryClient(deleteRegistryClient: DeleteRegistryClientRequest): Observable { const entity: RegistryClientEntity = deleteRegistryClient.registryClient; - const revision: any = this.client.getRevision(entity); - return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params: revision }); + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params }); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/reporting-task.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/reporting-task.service.ts index 4a5d963e60..ccf32d9bd4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/reporting-task.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/reporting-task.service.ts @@ -17,7 +17,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Client } from '../../../service/client.service'; import { NiFiCommon } from '../../../service/nifi-common.service'; import { @@ -29,6 +29,7 @@ import { StopReportingTaskRequest } from '../state/reporting-tasks'; import { PropertyDescriptorRetriever } from '../../../state/shared'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class ReportingTaskService implements PropertyDescriptorRetriever { @@ -37,7 +38,8 @@ export class ReportingTaskService implements PropertyDescriptorRetriever { constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getReportingTasks(): Observable { @@ -51,6 +53,7 @@ export class ReportingTaskService implements PropertyDescriptorRetriever { createReportingTask(createReportingTask: CreateReportingTaskRequest): Observable { return this.httpClient.post(`${ReportingTaskService.API}/controller/reporting-tasks`, { revision: createReportingTask.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { bundle: createReportingTask.reportingTaskBundle, type: createReportingTask.reportingTaskType @@ -60,8 +63,13 @@ export class ReportingTaskService implements PropertyDescriptorRetriever { deleteReportingTask(deleteReportingTask: DeleteReportingTaskRequest): Observable { const entity: ReportingTaskEntity = deleteReportingTask.reportingTask; - const revision: any = this.client.getRevision(entity); - return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params: revision }); + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(entity), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(entity.uri), { params }); } startReportingTask(startReportingTask: StartReportingTaskRequest): Observable { @@ -69,6 +77,7 @@ export class ReportingTaskService implements PropertyDescriptorRetriever { const revision: any = this.client.getRevision(entity); const payload: any = { revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: 'RUNNING' }; return this.httpClient.put(`${this.nifiCommon.stripProtocol(entity.uri)}/run-status`, payload); @@ -79,6 +88,7 @@ export class ReportingTaskService implements PropertyDescriptorRetriever { const revision: any = this.client.getRevision(entity); const payload: any = { revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: 'STOPPED' }; return this.httpClient.put(`${this.nifiCommon.stripProtocol(entity.uri)}/run-status`, payload); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/resolver/controller-service-advanced-ui-params.resolver.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/resolver/controller-service-advanced-ui-params.resolver.ts index 3f738432c2..2d97fb6913 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/resolver/controller-service-advanced-ui-params.resolver.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/service/resolver/controller-service-advanced-ui-params.resolver.ts @@ -26,6 +26,7 @@ import { HttpErrorResponse } from '@angular/common/http'; import { fullScreenError } from '../../../../state/error/error.actions'; import { ManagementControllerServiceService } from '../management-controller-service.service'; import { selectService } from '../../state/management-controller-services/management-controller-services.selectors'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; export const controllerServiceAdvancedUiParamsResolver: ResolveFn = ( route: ActivatedRouteSnapshot @@ -35,6 +36,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn = ( route: ActivatedRouteSnapshot @@ -33,6 +34,7 @@ export const parameterProviderAdvancedUiParamsResolver: ResolveFn = inject(Store); const parameterProviderService: ParameterProviderService = inject(ParameterProviderService); const client: Client = inject(Client); + const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService); // getting id parameter from activated route because ngrx router store // is not initialized when this resolver executes @@ -70,7 +72,7 @@ export const parameterProviderAdvancedUiParamsResolver: ResolveFn = (route: ActivatedRouteSnapshot) => { const store: Store = inject(Store); const reportingTaskService: ReportingTaskService = inject(ReportingTaskService); const client: Client = inject(Client); + const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService); // getting id parameter from activated route because ngrx router store // is not initialized when this resolver executes @@ -70,7 +72,7 @@ export const reportingTaskAdvancedUiParamsResolver: ResolveFn clientId: revision.clientId, revision: revision.version, editable, - disconnectedNodeAcknowledged: false // TODO + disconnectedNodeAcknowledged: clusterConnectionService.isDisconnectionAcknowledged() } as AdvancedUiParams; }), take(1) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/general/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/general/index.ts index d66bb154be..e10364ef0c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/general/index.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/general/index.ts @@ -33,6 +33,7 @@ export interface Controller { export interface ControllerEntity { revision: Revision; + disconnectedNodeAcknowledged?: boolean; component: Controller; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/registry-clients/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/registry-clients/index.ts index 7d8ff8bdae..d4d7473855 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/registry-clients/index.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/registry-clients/index.ts @@ -30,6 +30,7 @@ export interface LoadRegistryClientsResponse { export interface CreateRegistryClientRequest { revision: Revision; + disconnectedNodeAcknowledged: boolean; component: { name: string; type: string; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.spec.ts index 231748eeb7..8eb895678d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.spec.ts @@ -24,6 +24,7 @@ import { EditFlowAnalysisRuleDialogRequest } from '../../../state/flow-analysis- import { Component } from '@angular/core'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/error/error.reducer'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; describe('EditFlowAnalysisRule', () => { let component: EditFlowAnalysisRule; @@ -106,7 +107,13 @@ describe('EditFlowAnalysisRule', () => { { provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState - }) + }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } ] }); fixture = TestBed.createComponent(EditFlowAnalysisRule); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.ts index 73ac3282b4..00d76b485b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.ts @@ -46,6 +46,7 @@ import { } from '../../../state/flow-analysis-rules'; import { FlowAnalysisRuleTable } from '../flow-analysis-rule-table/flow-analysis-rule-table.component'; import { ErrorBanner } from '../../../../../ui/common/error-banner/error-banner.component'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; @Component({ selector: 'edit-flow-analysis-rule', @@ -91,7 +92,8 @@ export class EditFlowAnalysisRule { @Inject(MAT_DIALOG_DATA) public request: EditFlowAnalysisRuleDialogRequest, private formBuilder: FormBuilder, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) { const serviceProperties: any = request.flowAnalysisRule.component.properties; const properties: Property[] = Object.entries(serviceProperties).map((entry: any) => { @@ -124,6 +126,7 @@ export class EditFlowAnalysisRule { submitForm(postUpdateNavigation?: string[]) { const payload: any = { revision: this.client.getRevision(this.request.flowAnalysisRule), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: this.request.flowAnalysisRule.id, name: this.editFlowAnalysisRuleForm.get('name')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/general/general-form/general-form.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/general/general-form/general-form.component.spec.ts index 82f05774ac..0c7a20b60c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/general/general-form/general-form.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/general/general-form/general-form.component.spec.ts @@ -24,6 +24,7 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatInputModule } from '@angular/material/input'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; describe('GeneralForm', () => { let component: GeneralForm; @@ -36,7 +37,13 @@ describe('GeneralForm', () => { providers: [ provideMockStore({ initialState - }) + }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } ] }); fixture = TestBed.createComponent(GeneralForm); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/general/general-form/general-form.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/general/general-form/general-form.component.ts index 47c169c8bc..190700e966 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/general/general-form/general-form.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/general/general-form/general-form.component.ts @@ -23,6 +23,7 @@ import { updateControllerConfig } from '../../../state/general/general.actions'; import { Client } from '../../../../../service/client.service'; import { selectCurrentUser } from '../../../../../state/current-user/current-user.selectors'; import { selectSaving } from '../../../state/general/general.selectors'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; @Component({ selector: 'general-form', @@ -44,6 +45,7 @@ export class GeneralForm { constructor( private formBuilder: FormBuilder, private client: Client, + private clusterConnectionService: ClusterConnectionService, private store: Store ) { // build the form @@ -56,6 +58,7 @@ export class GeneralForm { const payload: UpdateControllerConfigRequest = { controller: { revision: this.client.getRevision(this._controller), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { maxTimerDrivenThreadCount: this.controllerForm.get('timerDrivenThreadCount')?.value } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/edit-parameter-provider/edit-parameter-provider.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/edit-parameter-provider/edit-parameter-provider.component.ts index 4142246a49..2c3a3588c9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/edit-parameter-provider/edit-parameter-provider.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/edit-parameter-provider/edit-parameter-provider.component.ts @@ -43,6 +43,7 @@ import { ParameterProviderReferences } from '../parameter-context-references/par import { PropertyTable } from '../../../../../ui/common/property-table/property-table.component'; import { ErrorBanner } from '../../../../../ui/common/error-banner/error-banner.component'; import { CommonModule } from '@angular/common'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; @Component({ selector: 'edit-parameter-provider', @@ -80,7 +81,8 @@ export class EditParameterProvider { @Inject(MAT_DIALOG_DATA) public request: EditParameterProviderRequest, private formBuilder: FormBuilder, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) { const providerProperties = request.parameterProvider.component.properties; const properties: Property[] = Object.entries(providerProperties).map((entry: any) => { @@ -111,6 +113,7 @@ export class EditParameterProvider { submitForm(postUpdateNavigation?: string[]) { const payload: any = { revision: this.client.getRevision(this.request.parameterProvider), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: this.request.parameterProvider.id, name: this.editParameterProviderForm.get('name')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.spec.ts index 275f2a5b0c..330f08eddd 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.spec.ts @@ -23,6 +23,7 @@ import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { provideMockStore } from '@ngrx/store/testing'; import { initialParameterProvidersState } from '../../../state/parameter-providers/parameter-providers.reducer'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; describe('FetchParameterProviderParameters', () => { let component: FetchParameterProviderParameters; @@ -163,7 +164,13 @@ describe('FetchParameterProviderParameters', () => { }, provideMockStore({ initialState: initialParameterProvidersState - }) + }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } ] }); fixture = TestBed.createComponent(FetchParameterProviderParameters); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.ts index ee7388d315..cc844aa423 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.ts @@ -22,7 +22,6 @@ import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } import { ErrorBanner } from '../../../../../ui/common/error-banner/error-banner.component'; import { MatButtonModule } from '@angular/material/button'; import { NifiSpinnerDirective } from '../../../../../ui/common/spinner/nifi-spinner.directive'; -import { Client } from '../../../../../service/client.service'; import { NiFiCommon } from '../../../../../service/nifi-common.service'; import { FetchedParameterMapping, @@ -49,6 +48,7 @@ import * as ParameterProviderActions from '../../../state/parameter-providers/pa import { Store } from '@ngrx/store'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { PipesModule } from '../../../../../pipes/pipes.module'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; @Component({ selector: 'fetch-parameter-provider-parameters', @@ -107,7 +107,7 @@ export class FetchParameterProviderParameters implements OnInit { constructor( private formBuilder: FormBuilder, - private client: Client, + private clusterConnectionService: ClusterConnectionService, private nifiCommon: NiFiCommon, private store: Store, @Inject(MAT_DIALOG_DATA) public request: FetchParameterProviderDialogRequest @@ -596,7 +596,7 @@ export class FetchParameterProviderParameters implements OnInit { return { id: this.parameterProvider.id, revision: this.parameterProvider.revision, - disconnectedNodeAcknowledged: false, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), parameterGroupConfigurations: groupConfigs }; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/create-registry-client/create-registry-client.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/create-registry-client/create-registry-client.component.spec.ts index 42ac7739f6..6933635462 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/create-registry-client/create-registry-client.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/create-registry-client/create-registry-client.component.spec.ts @@ -21,6 +21,7 @@ import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { CreateRegistryClient } from './create-registry-client.component'; import { CreateRegistryClientDialogRequest } from '../../../state/registry-clients'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; describe('CreateRegistryClient', () => { let component: CreateRegistryClient; @@ -44,7 +45,15 @@ describe('CreateRegistryClient', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [CreateRegistryClient, NoopAnimationsModule], - providers: [{ provide: MAT_DIALOG_DATA, useValue: data }] + providers: [ + { provide: MAT_DIALOG_DATA, useValue: data }, + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } + ] }); fixture = TestBed.createComponent(CreateRegistryClient); component = fixture.componentInstance; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/create-registry-client/create-registry-client.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/create-registry-client/create-registry-client.component.ts index 1046f8bfa5..373c0e0252 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/create-registry-client/create-registry-client.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/create-registry-client/create-registry-client.component.ts @@ -31,6 +31,7 @@ import { MatSelectModule } from '@angular/material/select'; import { NifiTooltipDirective } from '../../../../../ui/common/tooltips/nifi-tooltip.directive'; import { TextTip } from '../../../../../ui/common/tooltips/text-tip/text-tip.component'; import { NiFiCommon } from '../../../../../service/nifi-common.service'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; @Component({ selector: 'create-registry-client', @@ -62,7 +63,8 @@ export class CreateRegistryClient { @Inject(MAT_DIALOG_DATA) public request: CreateRegistryClientDialogRequest, private formBuilder: FormBuilder, private nifiCommon: NiFiCommon, - private client: Client + private client: Client, + private clusterConnectionService: ClusterConnectionService ) { let type: string | null = null; if (request.registryClientTypes.length > 0) { @@ -94,6 +96,7 @@ export class CreateRegistryClient { clientId: this.client.getClientId(), version: 0 }, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { name: this.createRegistryClientForm.get('name')?.value, type: this.createRegistryClientForm.get('type')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.spec.ts index 42bb502fae..7eaeb44662 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.spec.ts @@ -24,6 +24,7 @@ import { EditRegistryClientDialogRequest } from '../../../state/registry-clients import { Component } from '@angular/core'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/error/error.reducer'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; describe('EditRegistryClient', () => { let component: EditRegistryClient; @@ -119,7 +120,13 @@ describe('EditRegistryClient', () => { { provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState - }) + }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } ] }); fixture = TestBed.createComponent(EditRegistryClient); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.ts index 10d302a62b..0711e907e5 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.ts @@ -41,6 +41,7 @@ import { NiFiCommon } from '../../../../../service/nifi-common.service'; import { MatTabsModule } from '@angular/material/tabs'; import { PropertyTable } from '../../../../../ui/common/property-table/property-table.component'; import { ErrorBanner } from '../../../../../ui/common/error-banner/error-banner.component'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; @Component({ selector: 'edit-registry-client', @@ -79,7 +80,8 @@ export class EditRegistryClient { @Inject(MAT_DIALOG_DATA) public request: EditRegistryClientDialogRequest, private formBuilder: FormBuilder, private nifiCommon: NiFiCommon, - private client: Client + private client: Client, + private clusterConnectionService: ClusterConnectionService ) { const serviceProperties: any = request.registryClient.component.properties; const properties: Property[] = Object.entries(serviceProperties).map((entry: any) => { @@ -113,6 +115,7 @@ export class EditRegistryClient { submitForm(postUpdateNavigation?: string[]) { const payload: any = { revision: this.client.getRevision(this.request.registryClient), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: this.request.registryClient.id, name: this.editRegistryClientForm.get('name')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.spec.ts index 4c9121135b..095096b8a9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.spec.ts @@ -24,6 +24,7 @@ import { EditReportingTaskDialogRequest } from '../../../state/reporting-tasks'; import { Component } from '@angular/core'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/error/error.reducer'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; describe('EditReportingTask', () => { let component: EditReportingTask; @@ -399,7 +400,13 @@ describe('EditReportingTask', () => { { provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState - }) + }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } ] }); fixture = TestBed.createComponent(EditReportingTask); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.ts index dd014742ae..7ca02cd592 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.ts @@ -48,6 +48,7 @@ import { ControllerServiceApi } from '../../../../../ui/common/controller-servic import { NifiTooltipDirective } from '../../../../../ui/common/tooltips/nifi-tooltip.directive'; import { TextTip } from '../../../../../ui/common/tooltips/text-tip/text-tip.component'; import { ErrorBanner } from '../../../../../ui/common/error-banner/error-banner.component'; +import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; @Component({ selector: 'edit-reporting-task', @@ -104,7 +105,8 @@ export class EditReportingTask { @Inject(MAT_DIALOG_DATA) public request: EditReportingTaskDialogRequest, private formBuilder: FormBuilder, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) { const serviceProperties: any = request.reportingTask.component.properties; const properties: Property[] = Object.entries(serviceProperties).map((entry: any) => { @@ -157,6 +159,7 @@ export class EditReportingTask { submitForm(postUpdateNavigation?: string[]) { const payload: any = { revision: this.client.getRevision(this.request.reportingTask), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: this.request.reportingTask.id, name: this.editReportingTaskForm.get('name')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/users/feature/users.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/users/feature/users.component.ts index d9c6568f08..90e10f52ca 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/users/feature/users.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/users/feature/users.component.ts @@ -20,6 +20,11 @@ import { Store } from '@ngrx/store'; import { NiFiState } from '../../../state'; import { startCurrentUserPolling, stopCurrentUserPolling } from '../../../state/current-user/current-user.actions'; import { resetUsersState } from '../state/user-listing/user-listing.actions'; +import { + loadClusterSummary, + startClusterSummaryPolling, + stopClusterSummaryPolling +} from '../../../state/cluster-summary/cluster-summary.actions'; @Component({ selector: 'users', @@ -30,11 +35,14 @@ export class Users implements OnInit, OnDestroy { constructor(private store: Store) {} ngOnInit(): void { + this.store.dispatch(loadClusterSummary()); this.store.dispatch(startCurrentUserPolling()); + this.store.dispatch(startClusterSummaryPolling()); } ngOnDestroy(): void { this.store.dispatch(resetUsersState()); + this.store.dispatch(stopClusterSummaryPolling()); this.store.dispatch(stopCurrentUserPolling()); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/users/service/users.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/users/service/users.service.ts index 950d05f2ac..b5f03b078b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/users/service/users.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/users/service/users.service.ts @@ -16,7 +16,7 @@ */ import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Client } from '../../../service/client.service'; import { Observable } from 'rxjs'; import { NiFiCommon } from '../../../service/nifi-common.service'; @@ -27,6 +27,7 @@ import { UpdateUserGroupRequest, UpdateUserRequest } from '../state/user-listing'; +import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class UsersService { @@ -35,7 +36,8 @@ export class UsersService { constructor( private httpClient: HttpClient, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) {} getUsers(): Observable { @@ -49,6 +51,7 @@ export class UsersService { createUser(request: CreateUserRequest): Observable { const payload: any = { revision: request.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: request.userPayload }; return this.httpClient.post(`${UsersService.API}/tenants/users`, payload); @@ -57,6 +60,7 @@ export class UsersService { createUserGroup(request: CreateUserGroupRequest): Observable { const payload: any = { revision: request.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: request.userGroupPayload }; return this.httpClient.post(`${UsersService.API}/tenants/user-groups`, payload); @@ -65,6 +69,7 @@ export class UsersService { updateUser(request: UpdateUserRequest): Observable { const payload: any = { revision: request.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: request.id, ...request.userPayload @@ -76,6 +81,7 @@ export class UsersService { updateUserGroup(request: UpdateUserGroupRequest): Observable { const payload: any = { revision: request.revision, + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: request.id, ...request.userGroupPayload @@ -85,12 +91,22 @@ export class UsersService { } deleteUser(user: UserEntity): Observable { - const revision: any = this.client.getRevision(user); - return this.httpClient.delete(this.nifiCommon.stripProtocol(user.uri), { params: revision }); + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(user), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(user.uri), { params }); } deleteUserGroup(userGroup: UserGroupEntity): Observable { - const revision: any = this.client.getRevision(userGroup); - return this.httpClient.delete(this.nifiCommon.stripProtocol(userGroup.uri), { params: revision }); + const params = new HttpParams({ + fromObject: { + ...this.client.getRevision(userGroup), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged() + } + }); + return this.httpClient.delete(this.nifiCommon.stripProtocol(userGroup.uri), { params }); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/cluster-connection.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/cluster-connection.service.ts new file mode 100644 index 0000000000..da4e4f2419 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/cluster-connection.service.ts @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { ClusterSummaryState } from '../state/cluster-summary'; +import { selectDisconnectionAcknowledged } from '../state/cluster-summary/cluster-summary.selectors'; + +@Injectable({ + providedIn: 'root' +}) +export class ClusterConnectionService { + private disconnectionAcknowledged = this.store.selectSignal(selectDisconnectionAcknowledged); + + constructor(private store: Store) {} + + isDisconnectionAcknowledged(): boolean { + return this.disconnectionAcknowledged(); + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/controller-service-state.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/controller-service-state.service.ts index 6e82893494..c86554d096 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/controller-service-state.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/controller-service-state.service.ts @@ -25,6 +25,7 @@ import { } from '../state/shared'; import { Client } from './client.service'; import { NiFiCommon } from './nifi-common.service'; +import { ClusterConnectionService } from './cluster-connection.service'; @Injectable({ providedIn: 'root' }) export class ControllerServiceStateService { @@ -33,7 +34,8 @@ export class ControllerServiceStateService { constructor( private httpClient: HttpClient, private nifiCommon: NiFiCommon, - private client: Client + private client: Client, + private clusterConnectionService: ClusterConnectionService ) {} getControllerService(id: string): Observable { @@ -46,6 +48,7 @@ export class ControllerServiceStateService { setEnable(controllerService: ControllerServiceEntity, enabled: boolean): Observable { return this.httpClient.put(`${this.nifiCommon.stripProtocol(controllerService.uri)}/run-status`, { revision: this.client.getRevision(controllerService), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), state: enabled ? 'ENABLED' : 'DISABLED', uiOnly: true }); @@ -63,7 +66,7 @@ export class ControllerServiceStateService { id: controllerService.id, state: enabled ? 'ENABLED' : 'DISABLED', referencingComponentRevisions: referencingComponentRevisions, - // 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), uiOnly: true }); } @@ -83,7 +86,7 @@ export class ControllerServiceStateService { id: controllerService.id, state: running ? 'RUNNING' : 'STOPPED', referencingComponentRevisions: referencingComponentRevisions, - // 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), uiOnly: true }); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.actions.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.actions.ts index 92256d16b7..1d0e6ffcb6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.actions.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.actions.ts @@ -31,6 +31,16 @@ export const loadClusterSummarySuccess = createAction( props<{ response: LoadClusterSummaryResponse }>() ); +export const acknowledgeClusterConnectionChange = createAction( + `${CLUSTER_SUMMARY_STATE_PREFIX} Acknowledge Cluster Connection Change`, + props<{ connectedToCluster: boolean }>() +); + +export const setDisconnectionAcknowledged = createAction( + `${CLUSTER_SUMMARY_STATE_PREFIX} Set Disconnection Acknowledged`, + props<{ disconnectionAcknowledged: boolean }>() +); + export const clusterSummaryApiError = createAction( `${CLUSTER_SUMMARY_STATE_PREFIX} Cluster Summary Api Error`, props<{ error: string }>() diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.effects.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.effects.ts index 4256ca868b..ac36cbd577 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.effects.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.effects.ts @@ -18,34 +18,53 @@ import { Injectable } from '@angular/core'; import { Actions, concatLatestFrom, createEffect, ofType } from '@ngrx/effects'; import * as ClusterSummaryActions from './cluster-summary.actions'; -import { asyncScheduler, catchError, filter, from, interval, map, of, switchMap, takeUntil } from 'rxjs'; +import { asyncScheduler, catchError, delay, filter, from, interval, map, of, switchMap, takeUntil, tap } from 'rxjs'; import { ClusterService } from '../../service/cluster.service'; import { selectClusterSummary } from './cluster-summary.selectors'; import { isDefinedAndNotNull } from '../shared'; import { Store } from '@ngrx/store'; -import { ClusterSummaryState } from './index'; +import { ClusterSummary, ClusterSummaryState } from './index'; import { HttpErrorResponse } from '@angular/common/http'; import * as ErrorActions from '../error/error.actions'; +import { acknowledgeClusterConnectionChange, setDisconnectionAcknowledged } from './cluster-summary.actions'; +import { OkDialog } from '../../ui/common/ok-dialog/ok-dialog.component'; +import { MEDIUM_DIALOG } from '../../index'; +import { MatDialog } from '@angular/material/dialog'; @Injectable() export class ClusterSummaryEffects { constructor( private actions$: Actions, private clusterService: ClusterService, - private store: Store + private store: Store, + private dialog: MatDialog ) {} loadClusterSummary$ = createEffect(() => this.actions$.pipe( ofType(ClusterSummaryActions.loadClusterSummary), - switchMap(() => { + concatLatestFrom(() => this.store.select(selectClusterSummary)), + switchMap(([, currentClusterSummary]) => { return from( this.clusterService.getClusterSummary().pipe( - map((response) => - ClusterSummaryActions.loadClusterSummarySuccess({ + map((response) => { + const clusterSummary: ClusterSummary = response.clusterSummary; + const connectedToCluster = clusterSummary.connectedToCluster; + + if (currentClusterSummary) { + if (currentClusterSummary.connectedToCluster !== clusterSummary.connectedToCluster) { + this.store.dispatch(acknowledgeClusterConnectionChange({ connectedToCluster })); + } + } else { + if (clusterSummary.clustered && !clusterSummary.connectedToCluster) { + this.store.dispatch(acknowledgeClusterConnectionChange({ connectedToCluster })); + } + } + + return ClusterSummaryActions.loadClusterSummarySuccess({ response - }) - ), + }); + }), catchError((error) => of(ClusterSummaryActions.clusterSummaryApiError({ error: error.error }))) ) ); @@ -65,6 +84,41 @@ export class ClusterSummaryEffects { ) ); + acknowledgeClusterConnectionChange$ = createEffect( + () => + this.actions$.pipe( + ofType(ClusterSummaryActions.acknowledgeClusterConnectionChange), + delay(2000), // minor delay to allow component at the desired route to act first + tap(({ connectedToCluster }) => { + const message = connectedToCluster + ? 'This node just joined the cluster. Any modifications to the data flow made here will replicate across the cluster.' + : 'This node is currently not connected to the cluster. Any modifications to the data flow made here will not replicate across the cluster.'; + + const dialogReference = this.dialog.open(OkDialog, { + ...MEDIUM_DIALOG, + disableClose: true, + data: { + title: 'Cluster Connection', + message + } + }); + + dialogReference.componentInstance.ok + .pipe(takeUntil(dialogReference.afterClosed())) + .subscribe(() => { + if (connectedToCluster) { + // this node has rejoined the cluster and any previous acknowledged disconnection can be reset + this.store.dispatch(setDisconnectionAcknowledged({ disconnectionAcknowledged: false })); + } else { + // this node is not currently connected so the user has acknowledged the disconnection + this.store.dispatch(setDisconnectionAcknowledged({ disconnectionAcknowledged: true })); + } + }); + }) + ), + { dispatch: false } + ); + searchCluster$ = createEffect(() => this.actions$.pipe( ofType(ClusterSummaryActions.searchCluster), diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.reducer.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.reducer.ts index d6fa003f09..926ee842e8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.reducer.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.reducer.ts @@ -22,10 +22,12 @@ import { clusterSummaryApiError, loadClusterSummary, loadClusterSummarySuccess, - searchClusterSuccess + searchClusterSuccess, + setDisconnectionAcknowledged } from './cluster-summary.actions'; export const initialState: ClusterSummaryState = { + disconnectionAcknowledged: false, clusterSummary: null, searchResults: null, error: null, @@ -57,5 +59,9 @@ export const clusterSummaryReducer = createReducer( on(searchClusterSuccess, (state, { response }) => ({ ...state, searchResults: response + })), + on(setDisconnectionAcknowledged, (state, { disconnectionAcknowledged }) => ({ + ...state, + disconnectionAcknowledged })) ); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.selectors.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.selectors.ts index 58afb3a3d7..fc52da67fe 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.selectors.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/cluster-summary.selectors.ts @@ -20,6 +20,11 @@ import { clusterSummaryFeatureKey, ClusterSummaryState } from './index'; export const selectClusterSummaryState = createFeatureSelector(clusterSummaryFeatureKey); +export const selectDisconnectionAcknowledged = createSelector( + selectClusterSummaryState, + (state: ClusterSummaryState) => state.disconnectionAcknowledged +); + export const selectClusterSummary = createSelector( selectClusterSummaryState, (state: ClusterSummaryState) => state.clusterSummary diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/index.ts index 7e90e99ae2..2d314c0eac 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/index.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/cluster-summary/index.ts @@ -34,17 +34,18 @@ export interface NodeSearchResult { address: string; } +export interface ClusterSearchRequest { + q?: string; +} + export interface ClusterSearchResults { nodeResults: NodeSearchResult[]; } export interface ClusterSummaryState { + disconnectionAcknowledged: boolean; clusterSummary: ClusterSummary | null; searchResults: ClusterSearchResults | null; error: string | null; status: 'pending' | 'loading' | 'error' | 'success'; } - -export interface ClusterSearchRequest { - q?: string; -} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/advanced-ui/advanced-ui.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/advanced-ui/advanced-ui.component.ts index 0899343b78..eb59bdadae 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/advanced-ui/advanced-ui.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/advanced-ui/advanced-ui.component.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Component, SecurityContext } from '@angular/core'; +import { Component, OnDestroy, OnInit, SecurityContext } from '@angular/core'; import { NiFiState } from '../../../state'; import { Store } from '@ngrx/store'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; @@ -24,6 +24,12 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Navigation } from '../navigation/navigation.component'; import { selectRouteData } from '../../../state/router/router.selectors'; import { AdvancedUiParams, isDefinedAndNotNull } from '../../../state/shared'; +import { + loadClusterSummary, + startClusterSummaryPolling, + stopClusterSummaryPolling +} from '../../../state/cluster-summary/cluster-summary.actions'; +import { selectDisconnectionAcknowledged } from '../../../state/cluster-summary/cluster-summary.selectors'; @Component({ selector: 'advanced-ui', @@ -32,9 +38,11 @@ import { AdvancedUiParams, isDefinedAndNotNull } from '../../../state/shared'; imports: [Navigation], styleUrls: ['./advanced-ui.component.scss'] }) -export class AdvancedUi { +export class AdvancedUi implements OnInit, OnDestroy { frameSource!: SafeResourceUrl | null; + private params: AdvancedUiParams | null = null; + constructor( private store: Store, private domSanitizer: DomSanitizer @@ -44,9 +52,38 @@ export class AdvancedUi { .pipe(takeUntilDestroyed(), isDefinedAndNotNull()) .subscribe((data) => { if (data['advancedUiParams']) { + // clone the params to handle reloading based on cluster connection state changes + this.params = { + ...data['advancedUiParams'] + }; this.frameSource = this.getFrameSource(data['advancedUiParams']); } }); + + this.store + .select(selectDisconnectionAcknowledged) + .pipe(takeUntilDestroyed()) + .subscribe((disconnectionAcknowledged) => { + if (this.params) { + // limit reloading advanced ui to only when necessary (when the user has acknowledged disconnection) + if ( + disconnectionAcknowledged && + this.params.disconnectedNodeAcknowledged != disconnectionAcknowledged + ) { + this.params.disconnectedNodeAcknowledged = disconnectionAcknowledged; + this.frameSource = this.getFrameSource(this.params); + } + } + }); + } + + ngOnInit(): void { + this.store.dispatch(loadClusterSummary()); + this.store.dispatch(startClusterSummaryPolling()); + } + + ngOnDestroy(): void { + this.store.dispatch(stopClusterSummaryPolling()); } private getFrameSource(params: AdvancedUiParams): SafeResourceUrl | null { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.spec.ts index 08ed04ffad..004be53f3a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.spec.ts @@ -24,6 +24,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Component } from '@angular/core'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../state/error/error.reducer'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; describe('EditControllerService', () => { let component: EditControllerService; @@ -558,7 +559,13 @@ describe('EditControllerService', () => { { provide: MAT_DIALOG_DATA, useValue: data }, provideMockStore({ initialState - }) + }), + { + provide: ClusterConnectionService, + useValue: { + isDisconnectionAcknowledged: jest.fn() + } + } ] }); fixture = TestBed.createComponent(EditControllerService); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.ts index e2960048d3..d523067267 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.ts @@ -44,6 +44,7 @@ import { Observable } from 'rxjs'; import { ControllerServiceReferences } from '../controller-service-references/controller-service-references.component'; import { NifiSpinnerDirective } from '../../spinner/nifi-spinner.directive'; import { ErrorBanner } from '../../error-banner/error-banner.component'; +import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; @Component({ selector: 'edit-controller-service', @@ -109,7 +110,8 @@ export class EditControllerService { @Inject(MAT_DIALOG_DATA) public request: EditControllerServiceDialogRequest, private formBuilder: FormBuilder, private client: Client, - private nifiCommon: NiFiCommon + private nifiCommon: NiFiCommon, + private clusterConnectionService: ClusterConnectionService ) { const serviceProperties: any = request.controllerService.component.properties; const properties: Property[] = Object.entries(serviceProperties).map((entry: any) => { @@ -141,6 +143,7 @@ export class EditControllerService { submitForm(postUpdateNavigation?: string[]) { const payload: any = { revision: this.client.getRevision(this.request.controllerService), + disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: { id: this.request.controllerService.id, name: this.editControllerServiceForm.get('name')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/ok-dialog/ok-dialog.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/ok-dialog/ok-dialog.component.html index 6d89b13a19..1c920b9320 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/ok-dialog/ok-dialog.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/ok-dialog/ok-dialog.component.html @@ -20,5 +20,5 @@
{{ request.message }}
- + diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/ok-dialog/ok-dialog.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/ok-dialog/ok-dialog.component.ts index 273142a8df..79dbd25b9d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/ok-dialog/ok-dialog.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/ok-dialog/ok-dialog.component.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Component, Inject } from '@angular/core'; +import { Component, EventEmitter, Inject, Output } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import { OkDialogRequest } from '../../../state/shared'; import { MatButtonModule } from '@angular/material/button'; @@ -28,5 +28,11 @@ import { MatButtonModule } from '@angular/material/button'; styleUrls: ['./ok-dialog.component.scss'] }) export class OkDialog { + @Output() ok: EventEmitter = new EventEmitter(); + constructor(@Inject(MAT_DIALOG_DATA) public request: OkDialogRequest) {} + + okClicked(): void { + this.ok.next(); + } }