From 62a4ece55d08d5488e42819f27bbecd864e9e7dc Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Fri, 12 Apr 2024 12:06:38 -0400 Subject: [PATCH] NIFI-13005: (#8609) - Adding support for showing cluster state in the component state dialog. This closes #8609 --- .../src/app/state/component-state/index.ts | 6 ++ .../component-state.component.html | 10 ++++ .../component-state.component.ts | 55 ++++++++++++++----- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/component-state/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/component-state/index.ts index d6013e9f0d..86047add7a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/component-state/index.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/component-state/index.ts @@ -42,6 +42,12 @@ export interface StateEntry { clusterNodeAddress?: string; } +export interface StateItem { + key: string; + value: string; + scope?: string; +} + export interface StateMap { scope: string; state: StateEntry[]; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/component-state/component-state.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/component-state/component-state.component.html index 3ec36528de..f091aac161 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/component-state/component-state.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/component-state/component-state.component.html @@ -73,6 +73,16 @@ + + @if (displayedColumns.includes('scope')) { + + Scope + + {{ item.scope }} + + + } + = this.store.select(selectComponentName).pipe(isDefinedAndNotNull()); canClear$: Observable = this.store.select(selectCanClear).pipe(isDefinedAndNotNull()); - // TODO - need to include scope column when clustered displayedColumns: string[] = ['key', 'value']; - dataSource: MatTableDataSource = new MatTableDataSource(); + dataSource: MatTableDataSource = new MatTableDataSource(); filterForm: FormGroup; @@ -89,17 +89,17 @@ export class ComponentStateDialog implements AfterViewInit { .subscribe((componentState) => { this.stateDescription = componentState.stateDescription; - const stateItems: StateEntry[] = []; + const stateItems: StateItem[] = []; if (componentState.localState) { - const localStateItems: StateEntry[] = this.processStateMap(componentState.localState); + const localStateItems: StateItem[] = this.processStateMap(componentState.localState, false); stateItems.push(...localStateItems); } if (componentState.clusterState) { - const clusterStateItems: StateEntry[] = this.processStateMap(componentState.clusterState); + const clusterStateItems: StateItem[] = this.processStateMap(componentState.clusterState, true); stateItems.push(...clusterStateItems); } - this.dataSource.data = this.sortStateEntries(stateItems, { + this.dataSource.data = this.sortStateItems(stateItems, { active: this.initialSortColumn, direction: this.initialSortDirection }); @@ -111,6 +111,24 @@ export class ComponentStateDialog implements AfterViewInit { this.applyFilter(filterTerm); } }); + + this.store + .select(selectClusterSummary) + .pipe(isDefinedAndNotNull(), takeUntilDestroyed()) + .subscribe((clusterSummary) => { + if (clusterSummary.connectedToCluster) { + // if we're connected to the cluster add a scope column if it's not already present + if (!this.displayedColumns.includes('scope')) { + this.displayedColumns.splice(this.displayedColumns.length, 0, 'scope'); + } + } else { + // if we're not connected to the cluster remove the scope column if it is present + const nodeIndex = this.displayedColumns.indexOf('scope'); + if (nodeIndex > -1) { + this.displayedColumns.splice(nodeIndex, 1); + } + } + }); } ngAfterViewInit(): void { @@ -122,16 +140,22 @@ export class ComponentStateDialog implements AfterViewInit { }); } - processStateMap(stateMap: StateMap): StateEntry[] { - const stateItems: StateEntry[] = stateMap.state ? stateMap.state : []; + processStateMap(stateMap: StateMap, clusterState: boolean): StateItem[] { + const stateEntries: StateEntry[] = stateMap.state ? stateMap.state : []; - if (stateItems.length !== stateMap.totalEntryCount) { + if (stateEntries.length !== stateMap.totalEntryCount) { this.partialResults = true; } this.totalEntries += stateMap.totalEntryCount; - return stateItems; + return stateEntries.map((stateEntry) => { + return { + key: stateEntry.key, + value: stateEntry.value, + scope: clusterState ? 'Cluster' : stateEntry.clusterNodeAddress + }; + }); } applyFilter(filterTerm: string) { @@ -140,10 +164,10 @@ export class ComponentStateDialog implements AfterViewInit { } sortData(sort: Sort) { - this.dataSource.data = this.sortStateEntries(this.dataSource.data, sort); + this.dataSource.data = this.sortStateItems(this.dataSource.data, sort); } - private sortStateEntries(data: StateEntry[], sort: Sort): StateEntry[] { + private sortStateItems(data: StateItem[], sort: Sort): StateItem[] { if (!data) { return []; } @@ -158,6 +182,11 @@ export class ComponentStateDialog implements AfterViewInit { case 'value': retVal = this.nifiCommon.compareString(a.value, b.value); break; + case 'scope': + if (a.scope && b.scope) { + retVal = this.nifiCommon.compareString(a.scope, b.scope); + } + break; } return retVal * (isAsc ? 1 : -1); });