Skip to content

Commit

Permalink
Update extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
ck-c8y committed Mar 28, 2024
1 parent d71c02f commit 578b6ba
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 91 deletions.
2 changes: 1 addition & 1 deletion analytics-ui/src/manage/extension-card.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class ExtensionCardComponent {
// console.log("Confirmation delete result:", result);
if (result) {
try {
await this.analyticsService.deleteExtension(this.extension);
await this.analyticsService.deleteExtension(this.extension, true);
this.extensionChanged.emit();
} catch (ex) {
if (ex) {
Expand Down
39 changes: 24 additions & 15 deletions analytics-ui/src/manage/extension-grid.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@
<a
href="https://cumulocity.com/guides/streaming-analytics/troubleshooting/#safe-mode-on-startup"
target="'_blank'"
><i c8yIcon="warning" class="animated fadeIn infinite" style="animation-duration: 1.5s"></i><span class="text-warning p-r-8 p-l-4">{{ 'Safe Mode' }}</span
></a
><i
c8yIcon="warning"
class="animated fadeIn infinite"
style="animation-duration: 1.5s"
></i
><span class="text-warning p-r-8 p-l-4">{{ 'Safe Mode' }}</span></a
>
</c8y-action-bar-item>

Expand Down Expand Up @@ -76,7 +80,7 @@
class="btn btn-link"
title="{{ 'Refresh' | translate }}"
>
<i [ngClass]="{ 'icon-spin': loading }" c8yIcon="refresh"></i>
<i [ngClass]="{ 'icon-spin': (cepEngineStatus$ | async) === 'loading' }" c8yIcon="refresh"></i>
{{ 'Refresh' | translate }}
</button>
</c8y-action-bar-item>
Expand All @@ -88,7 +92,7 @@
></c8y-list-display-switch>
</c8y-action-bar-item>

<div *ngIf="!loadingError && (extensions$ | async)?.length === 0" class="row">
<div *ngIf="(cepEngineStatus$ | async) === 'empty'" class="row">
<div class="col-lg-4 col-lg-offset-5 text-center">
<c8y-ui-empty-state
[icon]="'plugin'"
Expand All @@ -107,18 +111,10 @@
</div>
</div>

<p class="text-center">
<c8y-progress-bar
message="Streaming Analytics Engine is restarting ..."
*ngIf="(cepOperationObject$ | async)?.c8y_Status?.status === 'Down'"
>
</c8y-progress-bar>
</p>

<div
[ngClass]="listClass"
class="card-group"
*ngIf="!loading && (cepOperationObject$ | async)?.c8y_Status?.status === 'Up'"
*ngIf="(cepEngineStatus$ | async) === 'up' || (cepEngineStatus$ | async) === 'loaded'"
>
<div
class="page-sticky-header hidden-xs d-flex"
Expand Down Expand Up @@ -155,7 +151,7 @@
<div
class="col-lg-8 col-lg-offset-2 m-b-48 text-center"
style="padding-top: 48px"
*ngIf="loadingError"
*ngIf="(cepEngineStatus$ | async) === 'loadingError'"
>
<h2>
<span class="label label-primary text-14">
Expand All @@ -168,7 +164,7 @@ <h2>
<div
class="col-lg-8 col-lg-offset-2 m-b-48 text-center"
style="padding-top: 48px"
*ngIf="loading"
*ngIf="(cepEngineStatus$ | async) === 'loading'"
>
<h2 class="p-b-24">
<span class="label label-primary text-14">
Expand All @@ -177,3 +173,16 @@ <h2 class="p-b-24">
</h2>
<c8y-loading></c8y-loading>
</div>

<div
class="col-lg-8 col-lg-offset-2 m-b-48 text-center"
style="padding-top: 48px"
*ngIf="(cepEngineStatus$ | async) === 'down'"
>
<h2 class="p-b-24">
<span class="label label-primary text-14">
Streaming Analytics Engine is restarting ...
</span>
</h2>
<c8y-loading></c8y-loading>
</div>
58 changes: 39 additions & 19 deletions analytics-ui/src/manage/extension-grid.component.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { IManagedObject } from '@c8y/client';
import { AlertService, WizardConfig, WizardModalService, gettext } from '@c8y/ngx-components';
import {
AlertService,
WizardConfig,
WizardModalService,
gettext
} from '@c8y/ngx-components';
import { ModalOptions } from 'ngx-bootstrap/modal';
import { BehaviorSubject, Observable, Subject, of } from 'rxjs';
import { catchError, shareReplay, switchMap, tap } from 'rxjs/operators';
import { AnalyticsService } from '../shared';
import { BehaviorSubject, Observable, Subject, Subscription, of } from 'rxjs';
import { catchError, shareReplay, switchMap, take, tap } from 'rxjs/operators';
import { AnalyticsService, CEPEngineStatus, CEPStatusObject } from '../shared';

@Component({
selector: 'a17t-extension',
templateUrl: './extension-grid.component.html',
styleUrls: ['./extension-grid.component.css']
})
export class ExtensionGridComponent implements OnInit {
loading: boolean = false;
cepOperationObject$: Subject<any>;
cepCtrlStatus: any;
export class ExtensionGridComponent implements OnInit, OnDestroy {
cepOperationObject$: Subject<IManagedObject>;
cepCtrlStatus: CEPStatusObject;
cepEngineStatus$: BehaviorSubject<CEPEngineStatus> =
new BehaviorSubject<CEPEngineStatus>('unknown');
cepId: string;
loadingError: boolean = false;
reload$: BehaviorSubject<boolean> = new BehaviorSubject(false);
extensions$: Observable<IManagedObject[]>;
sub1: Subscription;
listClass: string;
rescue: boolean = false;

constructor(
private analyticsService: AnalyticsService,
private alertService: AlertService,
private wizardModalService: WizardModalService
) {}
ngOnDestroy(): void {
this.sub1.unsubscribe();
}

ngOnInit() {
this.init();
Expand All @@ -38,21 +46,33 @@ export class ExtensionGridComponent implements OnInit {
this.cepId = microservice_application_id as string;
this.cepCtrlStatus = await this.analyticsService.getCEP_CtrlStatus();
this.cepOperationObject$ = this.analyticsService.getCEP_OperationObject();
this.sub1 = this.cepOperationObject$.subscribe((mo) => {
if (mo.c8y_Status?.status === 'Down') {
this.cepEngineStatus$.next('down');
} else if (mo.c8y_Status?.status === 'Up') {
this.cepEngineStatus$.next('up');
// this.alertService.clearAll();
}
});
this.extensions$ = this.reload$.pipe(
tap((clearCache) => {
if (clearCache) {
this.analyticsService.clearCaches();
}
this.loading = true;
this.loadingError = false;
this.cepEngineStatus$.next('loading');
}),
switchMap(() => this.analyticsService.getExtensionsMetadataEnriched()),
catchError(() => {
this.loadingError = true;
this.loading = false;
this.cepEngineStatus$.next('loadingError');
return of([]);
}),
tap(() => (this.loading = false)),
tap((res) => {
if (res && res.length > 0) {
this.cepEngineStatus$.next('loaded');
} else {
this.cepEngineStatus$.next('empty');
}
}),
shareReplay()
);

Expand All @@ -78,14 +98,14 @@ export class ExtensionGridComponent implements OnInit {
id: 'uploadAnalyticsExtension',
componentInitialState: {
mode: 'add',
headerText: 'Add extension',
},
headerText: 'Add extension'
}
};

const modalOptions: ModalOptions = { initialState };

const modalRef = this.wizardModalService.show(modalOptions);
modalRef.content.onClose.subscribe(() => {
modalRef.content.onClose.pipe(take(1)).subscribe(() => {
this.loadExtensions();
});
}
Expand Down
7 changes: 7 additions & 0 deletions analytics-ui/src/shared/analytics.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,10 @@ export const REPO_SAMPLES = [
enabled: false
}
] as Repository[];


export type CEPEngineStatus = 'loading' | 'loaded' | 'empty' |'loadingError' | 'started' | 'down' | 'up' | 'unknown';

export type CEPStatusObject = any;

export type UploadMode = 'add' | 'update';
50 changes: 29 additions & 21 deletions analytics-ui/src/shared/analytics.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import {
EXTENSION_ENDPOINT,
APPLICATION_ANALYTICS_BUILDER_SERVICE,
CEP_METADATA_FILE_EXTENSION,
CEP_ENDPOINT
CEP_ENDPOINT,
CEPStatusObject,
UploadMode
} from './analytics.model';
import { isCustomCEP_Block, removeFileExtension } from './utils';

Expand All @@ -36,13 +38,12 @@ export class AnalyticsService {
extensionChanged = new EventEmitter<IManagedObject>();
progress: BehaviorSubject<number> = new BehaviorSubject<number>(null);
private _cepOperationObjectId: Promise<string>;
private _cepCtrlStatus: Promise<any>;
private _cepCtrlStatus: Promise<CEPStatusObject>;
private _blocksDeployed: Promise<CEP_Block[]>;
private _extensionsDeployed: Promise<IManagedObject[]>;
private _isBackendDeployed: Promise<boolean>;
private cepOperationObject$: BehaviorSubject<any> = new BehaviorSubject<any>(
{}
);
private cepOperationObject$: Subject<IManagedObject> =
new Subject<IManagedObject>();
private realtime: Realtime;

constructor(
Expand Down Expand Up @@ -117,9 +118,13 @@ export class AnalyticsService {
return this._extensionsDeployed;
}

async deleteExtension(app: IManagedObject): Promise<void> {
async deleteExtension(
app: IManagedObject,
showSuccessMessage
): Promise<void> {
await this.inventoryBinaryService.delete(app.id);
this.alertService.success(gettext('Extension deleted.'));
if (showSuccessMessage)
this.alertService.success(gettext('Extension deleted.'));
this.extensionChanged.emit(app);
}

Expand Down Expand Up @@ -251,11 +256,11 @@ export class AnalyticsService {
return this._cepOperationObjectId;
}

getCEP_OperationObject(): Subject<string> {
getCEP_OperationObject(): Subject<IManagedObject> {
return this.cepOperationObject$;
}

async getCEP_CtrlStatus(): Promise<any> {
async getCEP_CtrlStatus(): Promise<CEPStatusObject> {
let response: IFetchResponse;
if (!this._cepCtrlStatus) {
if (await this.isBackendDeployed()) {
Expand Down Expand Up @@ -342,28 +347,31 @@ export class AnalyticsService {
const url = '/service/cep/restart';

try {
await this.fetchClient.fetch(url, fetchOptions);
await this.fetchClient.fetch(url, fetchOptions);
} catch (e) {
console.error(e);
console.error(e);
} finally {
console.log('We do cleanup here');
console.log('We do cleanup here');
}
this.clearCaches();
}

async uploadExtension(
archive: File,
newExtension: Partial<IManagedObject>,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
restart: boolean = false,
mode : string,
extensionToReplace: IManagedObject
file: File,
extension: IManagedObject,
mode: UploadMode
): Promise<IManagedObjectBinary> {
let extensionToCreate: Partial<IManagedObject> = extension;
if (mode === 'update') {
await this.deleteExtension(extensionToReplace);
await this.deleteExtension(extension, false);
extensionToCreate = {
name: extension.name,
pas_extension: extension.name
};
}
const result2 = (await this.inventoryBinaryService.create(archive, newExtension))
.data;
const result2 = (
await this.inventoryBinaryService.create(file, extensionToCreate)
).data;
return result2;
}

Expand Down
23 changes: 15 additions & 8 deletions analytics-ui/src/shared/wizard/extension-add-wizard.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
import { IManagedObject, IManagedObjectBinary } from '@c8y/client';
import { gettext } from '@c8y/ngx-components';
import { AnalyticsService } from '../analytics.service';
import { UploadMode } from '../analytics.model';

@Component({
selector: 'a17t-extension-add-wizard',
Expand All @@ -10,11 +11,11 @@ import { AnalyticsService } from '../analytics.service';
[headerIcon]="'upload'"
[successText]="successText"
[uploadExtensionHandler]="uploadExtensionHandler"
[canGoBack]="false"
[mode]="mode"
></a17t-extension-add>`
})
export class ExtensionAddWizardComponent implements OnInit {
@Input() mode: string;
@Input() mode: UploadMode;
@Input() extensionToReplace: IManagedObject;
@Input() headerText: string;
successText: string = gettext('Extension created');
Expand All @@ -26,15 +27,21 @@ export class ExtensionAddWizardComponent implements OnInit {

uploadExtensionHandler = (
file: File,
newExtension: IManagedObject,
restart: boolean
) => this.uploadExtension(file, newExtension, restart);
extension: IManagedObject,
mode: UploadMode
) => this.uploadExtension(file, extension, mode);

async uploadExtension(
file: File,
newExtension: IManagedObject,
restart: boolean
extension: IManagedObject,
mode: UploadMode
): Promise<IManagedObjectBinary> {
return this.analyticsService.uploadExtension(file, newExtension, restart, this.mode, this.extensionToReplace);
// eslint-disable-next-line no-param-reassign
if(!extension) extension = this.extensionToReplace;
return this.analyticsService.uploadExtension(
file,
extension,
mode
);
}
}
Loading

0 comments on commit 578b6ba

Please sign in to comment.