Skip to content

Commit

Permalink
update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ck-c8y committed Feb 28, 2024
1 parent 3f0ff77 commit 6c5e527
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 39 deletions.
40 changes: 22 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,19 @@

## Overview

This solution extends the standard Cumulocity Streaming Analytics application with a plugin to manage and add Analytics Builder extensions. Currently the standard UI does not offer the upload of custom blocks via .zip files. This extension enhances the standard Streaming-Analytics UI with these capabilities.
This solution extends the functionality of the standard Cumulocity Streaming Analytics application by incorporating a plugin to manage and add Analytics Builder extensions. The current standard user interface lacks the capability to upload custom blocks packaged as **.zip** files. This plugin enhances the Streaming-Analytics UI by introducing these capabilities.

You can mange the complete lifecycle off an extension:
* list, upload, download and delete Analytics Builder extensions
* list installed blocks
* manage github repositories, which serve as a source for building new extensions on the fly
* build new extensions from selected blocks and deploy the extensions to the Streaming Analytics engine
* monitor alarm status and events status send from the Analytics Builder engine, to analyze failures in the deployment process
The extension allows you to manage the complete lifecycle of an extension:
* List, upload, download, and delete Analytics Builder extensions.
* List installed blocks.
* Manage GitHub repositories, which act as a source for dynamically building new extensions.
* Build new extensions from selected blocks and deploy them in the Streaming Analytics engine.
* Monitor alarm status and events sent from the Analytics Builder engine to analyze deployment failures.

Analytics Builder blocks are build based on the [Analytics Builder Block SDK](https://github.com/SoftwareAG/apama-analytics-builder-block-sdk). Externally build extensions can as well be uploaded via the `Add extension` button.
Drop the .zip file to the modal dialog and the extension will be loaded. In order to use them you have to restart the streaming analytics engine. Click on the "Deploy extension (Restart)" button and wait for the notification that the engine was restarted.
Analytics Builder blocks are build using the [Analytics Builder Block SDK](https://github.com/SoftwareAG/apama-analytics-builder-block-sdk). Additionally, externally built extensions can be uploaded in the UI.

![Extension installation](resources/images/extension-installation-animated.gif)

<!-- ![Extension installation](resources/images/extension-installation.png) -->

In addition a table lists all installed analytics blocks with the following information: name, category, custom block, extension package name.

![Block list](resources/images/block-list.png)
Expand All @@ -42,7 +39,18 @@ For a deletion or upload to take effect you need to restart the analytics stream

### Upload custom extension

After the deployment (restart of streaming analytics) the Block will be available within the Steaming Analytics Application. Deleting a block will remove the block again. Keep in mind that no checking of any usage of that particular custom block is done an thus streaming flows might not work anymore.
An externally built extensions can be uploaded via the button **Add extension**.
Simply drop the **.zip** file to the modal dialog and the extension will be loaded to the repository, but not yet deployed. To use them, restart the Streaming Analytics engine by clicking on the button **Deploy extension (Restart)** and wait for the notification confirming the engine restart.

After the deployment (restart of streaming analytics) the block will be available within the Streaming Analytics Application.

When the deployment of the extension was not successful an indicator [Safe Mode](https://cumulocity.com/guides/streaming-analytics/troubleshooting/#safe-mode-on-startup) modus appears in the action bar of the **Manage extensions** tab, as on the image below.

![Monitoring](resources/images/safe-mode.png)

This usually happen when you try to deploy a faulty extension. In this case please check the logs of the microservice **apama-ctrl-Xc-Xg**, delete the extension and restart the Streaming Analytics engine.

Removing an extension will eliminate the block once more. It's important to note that when deleting an extension, there is no verification of whether the blocks within this extension are utilized in existing models. This could lead to models that are no longer deployable.

![Use Extension](resources/images/analytics-builder.png)

Expand All @@ -59,12 +67,8 @@ For a custom extension you have the following options:

![Build custom extension](resources/images/manage-extension.png)


## Samples repositories and building custom extensions
Block samples from github repositories can selected to build custom extension online.
In order to use this option first you have to configure your Github repository.
The configured repositories can be updated, deleted and de-/enabled. Only enabled repositories are shown in the list of block samples.
You can manage the github repositories using the following UI:
Block samples from GitHub repositories can be selected to build a custom extension online. To utilize this option, you must first configure your GitHub repository. Configured repositories can be updated, deleted, and enabled/disabled. Only enabled repositories will appear in the list of block samples. You can manage GitHub repositories using the provided user interface (UI):

![Manage repositories](resources/images/samples-manage-repository.png)

Expand Down Expand Up @@ -145,7 +149,7 @@ git clone https://github.com/SoftwareAG/cumulocity-analytics-management.git
The microservice downloads the sample blocks from the configured repositories and builds an analytics extension as a zip file. This this zip file is downloaded locally. In an additional step it needs to be uploaded through UI, see [Upload custom extension](#upload-custom-extension).
You can specify if the extension should be uploaded automatically or it should be downloaded by the browser UI.

The microservice is multi tenant ready
The microservice is multi tenant ready.

## Prerequisites to build/deploy the microservice
* Docker host/client
Expand Down
8 changes: 4 additions & 4 deletions analytics-ui/src/manage/extension-grid.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
<span
class="c8y-pulse animated pulse animation-slow"
[ngClass]="{
active: (cepOperationObject$ | async)?.c8y_Status.status === 'Up',
inactive: (cepOperationObject$ | async)?.c8y_Status.status === 'Down'
active: (cepOperationObject$ | async)?.c8y_Status?.status === 'Up',
inactive: (cepOperationObject$ | async)?.c8y_Status?.status === 'Down'
}"
></span>
<a
Expand Down Expand Up @@ -110,15 +110,15 @@
<p class="text-center">
<c8y-progress-bar
message="Streaming Analytics Engine is restarting ..."
*ngIf="(cepOperationObject$ | async)?.c8y_Status.status === 'Down'"
*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="!loading && (cepOperationObject$ | async)?.c8y_Status?.status === 'Up'"
>
<div
class="page-sticky-header hidden-xs d-flex"
Expand Down
4 changes: 3 additions & 1 deletion analytics-ui/src/manage/extension-grid.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { IManagedObject } from '@c8y/client';
import { WizardConfig, WizardModalService } 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';
Expand All @@ -24,6 +24,7 @@ export class ExtensionGridComponent implements OnInit {

constructor(
private analyticsService: AnalyticsService,
private alertService: AlertService,
private wizardModalService: WizardModalService
) {}

Expand Down Expand Up @@ -63,6 +64,7 @@ export class ExtensionGridComponent implements OnInit {
}

restartCEP() {
this.alertService.success(gettext('Deployment (restart) submitted ...'));
this.analyticsService.restartCEP();
}

Expand Down
27 changes: 13 additions & 14 deletions analytics-ui/src/sample/list/sample-grid.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
} from '../../shared';
import { EditorModalComponent } from '../editor/editor-modal.component';
import { RepositoriesModalComponent } from '../repository/repositories-modal.component';
import { LinkRendererComponent } from '../../shared/component/link-renderer.component';

@Component({
selector: 'a17t-sample-grid',
Expand Down Expand Up @@ -69,35 +70,33 @@ export class SampleGridComponent implements OnInit {
path: 'name',
dataType: ColumnDataType.TextLong,
filterable: true,
gridTrackSize: '10%',
visible: true
},
{
name: 'repositoryName',
header: 'Repository Name',
path: 'repositoryName',
dataType: ColumnDataType.TextLong,
filterable: true,
gridTrackSize: '15%',
visible: true
},
{
name: 'installed',
header: 'Installed',
path: 'installed',
dataType: ColumnDataType.TextLong,
dataType: ColumnDataType.Icon,
filterable: true,
gridTrackSize: '7.5%',
visible: true,
cellRendererComponent: BooleanRendererComponent
},
{
name: 'repositoryName',
header: 'Repository Name',
path: 'repositoryName',
dataType: ColumnDataType.TextLong,
filterable: true,
visible: true
},
{
name: 'url',
header: 'URL',
header: 'Link Github',
path: 'url',
dataType: ColumnDataType.TextLong,
filterable: true,
visible: true
visible: true,
cellRendererComponent: LinkRendererComponent
}
];

Expand Down
4 changes: 2 additions & 2 deletions analytics-ui/src/shared/analytics.service.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { EventEmitter, Injectable } from '@angular/core';
import {
ApplicationService,
Expand Down Expand Up @@ -334,7 +335,7 @@ export class AnalyticsService {

private updateStatusFromOperationObject(p: object): void {
const payload = p['data']['data'];
this.cepOperationObject$.next(payload?.c8y_Status);
this.cepOperationObject$.next(payload);
if (payload?.c8y_Status.status == 'Up') {
this._cepCtrlStatus = undefined;
// cache new cep status
Expand Down Expand Up @@ -362,7 +363,6 @@ export class AnalyticsService {
};
const url = '/service/cep/restart';
await this.fetchClient.fetch(url, fetchOptions);
// this.alertService.success(gettext("Deployment (restart) submitted ..."));
this.clearCaches();
}

Expand Down
33 changes: 33 additions & 0 deletions analytics-ui/src/shared/component/link-renderer.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2022 Software AG, Darmstadt, Germany and/or Software AG USA Inc., Reston, VA, USA,
* and/or its subsidiaries and/or its affiliates and/or their licensors.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed 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.
*
* @authors Christof Strack
*/
import { Component } from '@angular/core';
import { CellRendererContext } from '@c8y/ngx-components';

@Component({
template: `<a [href]="context.value" target="'_blank'"
><span>{{ 'Link ' + context.item.name }}</span></a
>`
})
export class LinkRendererComponent {
constructor(public context: CellRendererContext) {
// console.log("Renderer context:", context.value);
}
}
2 changes: 2 additions & 0 deletions analytics-ui/src/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { CustomSwitchField } from './component/custom-switch-field';
import { ConfirmationModalComponent } from './component/confirmation-modal.component';
import { BooleanRendererComponent } from './component/boolean-renderer.component';
import { ExtensionCreateComponent } from './component/extension-create-modal.component';
import { LinkRendererComponent } from './component/link-renderer.component';

@NgModule({
imports: [
Expand All @@ -22,6 +23,7 @@ import { ExtensionCreateComponent } from './component/extension-create-modal.com
declarations: [
ConfirmationModalComponent,
BooleanRendererComponent,
LinkRendererComponent,
ExtensionCreateComponent,
CustomSwitchField
],
Expand Down
Binary file modified resources/images/extension-installation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/monitoring.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/safe-mode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/samples-manage-repository.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/samples-view-code.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 6c5e527

Please sign in to comment.