You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2020/02/08 16:59:21 UTC

[incubator-streampipes] branch new_dashboard updated: STREAMPIPES-58: Add websocket connector to new dashboard

This is an automated email from the ASF dual-hosted git repository.

riemer pushed a commit to branch new_dashboard
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git


The following commit(s) were added to refs/heads/new_dashboard by this push:
     new 75c48cf  STREAMPIPES-58: Add websocket connector to new dashboard
75c48cf is described below

commit 75c48cfa4fc205bb57f58d9da2aafe8c05689878
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Sat Feb 8 17:59:07 2020 +0100

    STREAMPIPES-58: Add websocket connector to new dashboard
---
 .../backend/StreamPipesResourceConfig.java         |  9 ++---
 ui/package.json                                    |  1 +
 .../connect/schema-editor/model/EventProperty.ts   |  2 ++
 .../static-mapping-unary.component.html            |  2 +-
 .../static-mapping-unary.component.ts              |  7 ++--
 .../widget/dashboard-widget.component.css          |  7 ++++
 .../widget/dashboard-widget.component.html         |  8 +++--
 .../components/widgets/base/base-widget.ts         | 28 +++++++++++++++
 .../widgets/number/number-config.component.ts      |  7 ++--
 .../widgets/number/number-viz.component.css        |  9 +++++
 .../widgets/number/number-viz.component.html       |  9 +++++
 .../widgets/number/number-viz.component.ts         | 42 +++++++++++++++++++++-
 ui/src/app/dashboard-v2/dashboard.component.html   |  1 +
 ui/src/app/dashboard-v2/dashboard.module.ts        | 19 +++++++---
 .../sdk/extractor/static-property-extractor.ts     | 32 +++++++++++++++++
 .../app/dashboard-v2/services/websocket.config.ts  | 18 ++++++++++
 .../dashboard-v2/services/websocket.settings.ts    | 14 ++++++++
 ui/src/assets/dashboards.json                      |  2 +-
 18 files changed, 197 insertions(+), 20 deletions(-)

diff --git a/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesResourceConfig.java b/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesResourceConfig.java
index aa14ee9..09e324e 100644
--- a/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesResourceConfig.java
+++ b/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesResourceConfig.java
@@ -18,12 +18,6 @@
 
 package org.apache.streampipes.backend;
 
-import org.apache.streampipes.rest.impl.dashboard.Dashboard;
-import org.apache.streampipes.rest.impl.dashboard.DashboardWidget;
-import org.apache.streampipes.rest.impl.dashboard.VisualizablePipeline;
-import org.glassfish.jersey.media.multipart.MultiPartFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.springframework.context.annotation.Configuration;
 import org.apache.streampipes.rest.impl.ApplicationLink;
 import org.apache.streampipes.rest.impl.AssetDashboard;
 import org.apache.streampipes.rest.impl.Authentication;
@@ -58,6 +52,9 @@ import org.apache.streampipes.rest.impl.User;
 import org.apache.streampipes.rest.impl.Version;
 import org.apache.streampipes.rest.impl.VirtualSensor;
 import org.apache.streampipes.rest.impl.Visualization;
+import org.apache.streampipes.rest.impl.dashboard.Dashboard;
+import org.apache.streampipes.rest.impl.dashboard.DashboardWidget;
+import org.apache.streampipes.rest.impl.dashboard.VisualizablePipeline;
 import org.apache.streampipes.rest.impl.datalake.DataLakeNoUserResourceV3;
 import org.apache.streampipes.rest.impl.datalake.DataLakeResourceV3;
 import org.apache.streampipes.rest.impl.nouser.FileServingResource;
diff --git a/ui/package.json b/ui/package.json
index 230a229..324941e 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -28,6 +28,7 @@
     "@angular/router": "7.2.9",
     "@angular/upgrade": "7.2.9",
     "@ngui/datetime-picker": "0.16.2",
+    "@stomp/ng2-stompjs": "^7.2.0",
     "@swimlane/ngx-charts": "10.1.0",
     "@uirouter/angular-hybrid": "7.0.0",
     "angular": "1.7.7",
diff --git a/ui/src/app/connect/schema-editor/model/EventProperty.ts b/ui/src/app/connect/schema-editor/model/EventProperty.ts
index 1b9d9bf..6323cd9 100644
--- a/ui/src/app/connect/schema-editor/model/EventProperty.ts
+++ b/ui/src/app/connect/schema-editor/model/EventProperty.ts
@@ -31,6 +31,8 @@ export abstract class EventProperty {
   parent: EventProperty;
   child?: EventProperty;
 
+  propertySelector:string;
+
   propertyNumber: number; // what the user sees in the UI
 
   @RdfId
diff --git a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.html b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.html
index 78cf07f..22e0325 100644
--- a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.html
+++ b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.html
@@ -27,7 +27,7 @@
             <mat-form-field class="example-full-width">
                 <!--<mat-form-field class="example-full-width">-->
                 <mat-select [placeholder]="staticProperty.label" [(value)]="staticProperty.selectedProperty">
-                    <mat-option *ngFor="let property of availableProperties " [value]="property.runtimeName">
+                    <mat-option *ngFor="let property of availableProperties " [value]="property.propertySelector">
                         {{getName(property)}}
                     </mat-option>
                 </mat-select>
diff --git a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts
index 72bbcd4..19b73ae 100644
--- a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts
+++ b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts
@@ -46,6 +46,8 @@ export class StaticMappingUnaryComponent implements OnInit {
     private errorMessage = "Please enter a value";
     private availableProperties: Array<EventProperty>;
 
+    private firstStreamPropertySelector: string = "s0::";
+
     constructor(private staticPropertyUtil: StaticPropertyUtilService,
                 private PropertySelectorService: PropertySelectorService){
 
@@ -54,6 +56,7 @@ export class StaticMappingUnaryComponent implements OnInit {
 
     ngOnInit() {
         this.availableProperties = this.extractPossibleSelections();
+        this.availableProperties.forEach(ep => ep.propertySelector = this.firstStreamPropertySelector + ep.runtimeName);
         this.unaryTextForm = new FormGroup({
             'unaryStaticText':new FormControl(this.inputValue, [
                 Validators.required,
@@ -66,12 +69,12 @@ export class StaticMappingUnaryComponent implements OnInit {
     }
 
     isInSelection(ep: EventProperty): boolean {
-        return this.staticProperty.mapsFromOptions.some(maps => maps === "s0::" + ep.runtimeName);
+        return this.staticProperty.mapsFromOptions.some(maps => maps === this.firstStreamPropertySelector + ep.runtimeName);
     }
 
     valueChange(inputValue) {
         this.inputValue = inputValue;
-        if(inputValue == "" || !inputValue) {
+        if (inputValue == "" || !inputValue) {
             this.hasInput = false;
         }
         else{
diff --git a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css
index e69de29..e94514f 100644
--- a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css
+++ b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css
@@ -0,0 +1,7 @@
+.h-100 {
+    height:100%;
+}
+
+.p-0 {
+    padding:0;
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html
index 838a042..b4c6d43 100644
--- a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html
+++ b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html
@@ -6,10 +6,12 @@
             </button>
         </div>
     </div>
-    <div class="sp-blue-border" style="height:100%;">
+    <div class="sp-blue-border h-100">
         <!--        <div *ngIf="widget."></div>-->
-        <div *ngIf="widgetLoaded">
-            {{configuredWidget.dashboardWidgetSettings.widgetName}}
+        <div *ngIf="widgetLoaded" class="h-100">
+            <div *ngIf="widget.widgetType === 'number'" class="h-100 p-0">
+                <number-viz [widget]="widget" [widgetConfig]="configuredWidget"></number-viz>
+            </div>
         </div>
     </div>
 </div>
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts b/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts
new file mode 100644
index 0000000..308a45c
--- /dev/null
+++ b/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts
@@ -0,0 +1,28 @@
+import {EventSchema} from "../../../../connect/schema-editor/model/EventSchema";
+import {StaticProperty} from "../../../../connect/model/StaticProperty";
+import {Input, OnInit} from "@angular/core";
+import {DashboardItem} from "../../../models/dashboard.model";
+import {DashboardWidget} from "../../../../core-model/dashboard/DashboardWidget";
+import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-extractor";
+import {RxStompService} from "@stomp/ng2-stompjs";
+import {Message} from "@stomp/stompjs";
+
+export abstract class BaseStreamPipesWidget {
+
+    @Input() widget: DashboardItem;
+    @Input() widgetConfig: DashboardWidget;
+
+    protected constructor(private rxStompService: RxStompService) {
+    }
+
+    ngOnInit(): void {
+        this.extractConfig(new StaticPropertyExtractor(this.widgetConfig.dashboardWidgetSettings.requiredSchema, this.widgetConfig.dashboardWidgetSettings.config));
+        this.rxStompService.watch("/topic/" +this.widgetConfig.dashboardWidgetDataConfig.topic).subscribe((message: Message) => {
+            this.onEvent(JSON.parse(message.body));
+        });
+    }
+
+    protected abstract extractConfig(extractor: StaticPropertyExtractor);
+
+    protected abstract onEvent(event: any);
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts b/ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts
index a167b8b..f07a85c 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts
@@ -5,6 +5,9 @@ import {DashboardWidgetSettings} from "../../../../core-model/dashboard/Dashboar
 
 export class NumberConfig {
 
+    static TITLE_KEY: string = "hi";
+    static NUMBER_MAPPING_KEY: string = "number-mapping";
+
     constructor() {
 
     }
@@ -13,9 +16,9 @@ export class NumberConfig {
         return WidgetConfigBuilder.create("number", "number")
             .requiredSchema(SchemaRequirementsBuilder
                 .create()
-                .requiredPropertyWithUnaryMapping("number-mapping", "Select property", "", EpRequirements.numberReq())
+                .requiredPropertyWithUnaryMapping(this.TITLE_KEY, "Select property", "", EpRequirements.numberReq())
                 .build())
-            .requiredTextParameter("hi", "hi", "hi")
+            .requiredTextParameter(this.NUMBER_MAPPING_KEY, "hi", "hi")
             .build();
     }
 
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css
new file mode 100644
index 0000000..e2f59c9
--- /dev/null
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css
@@ -0,0 +1,9 @@
+.circleNumber {
+    width:100%;
+    height: 100%;
+    font-size: 30px;
+    color: #fff;
+    line-height: 150px;
+    text-align: center;
+    left: 50%;
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html
index e69de29..23ed019 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html
@@ -0,0 +1,9 @@
+<div class="circleNumber" [ngStyle]="{'background-color': color}">
+    <div class="numberTitle">
+        {{title}}
+    </div>
+    <div class="numberItem">
+        <div *ngIf="isNumber(item)">{{item}}</div>
+        <div *ngIf="!isNumber(item)">{{item}}</div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts
index 7c9c514..91f7aa2 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts
@@ -1,3 +1,43 @@
-export class NumberVizComponent {
+import {Component, Input, OnInit} from "@angular/core";
+import {RxStompService} from "@stomp/ng2-stompjs";
+import {BaseStreamPipesWidget} from "../base/base-widget";
+import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-extractor";
+import {NumberConfig} from "./number-config.component";
+
+@Component({
+    selector: 'number-viz',
+    templateUrl: './number-viz.component.html',
+    styleUrls: ['./number-viz.component.css']
+})
+export class NumberVizComponent extends BaseStreamPipesWidget implements OnInit {
+
+    item: any;
+    title: string;
+    color: string = "green";
+
+    selectedProperty: string;
+
+    constructor(rxStompService: RxStompService) {
+        super(rxStompService);
+    }
+
+    ngOnInit(): void {
+        super.ngOnInit();
+    }
+
+    extractConfig(extractor: StaticPropertyExtractor) {
+        this.title = extractor.singleValueParameter(NumberConfig.TITLE_KEY);
+        this.selectedProperty = extractor.mappingPropertyValue(NumberConfig.NUMBER_MAPPING_KEY);
+    }
+
+    isNumber(item: any): boolean {
+        return false;
+    }
+
+    protected onEvent(event: any) {
+        console.log(event);
+        console.log(this.selectedProperty);
+        this.item = event[this.selectedProperty];
+    }
 
 }
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/dashboard.component.html b/ui/src/app/dashboard-v2/dashboard.component.html
index 4ea1fb7..56f8e2d 100644
--- a/ui/src/app/dashboard-v2/dashboard.component.html
+++ b/ui/src/app/dashboard-v2/dashboard.component.html
@@ -2,6 +2,7 @@
     <div fxLayout="row" style="padding:0px;background-color:#f6f6f6;">
         <div fxLayout="fill" style="line-height:24px;border-bottom:1px solid #ccc">
             <mat-tab-group [selectedIndex]="selectedIndex" (selectedIndexChange)="selectDashboard($event)">
+                <mat-tab label="Start"></mat-tab>
                 <mat-tab *ngFor="let dashboard of dashboards" label="{{dashboard.name}}"></mat-tab>
             </mat-tab-group>
         </div>
diff --git a/ui/src/app/dashboard-v2/dashboard.module.ts b/ui/src/app/dashboard-v2/dashboard.module.ts
index 629fb97..2cd4cbb 100644
--- a/ui/src/app/dashboard-v2/dashboard.module.ts
+++ b/ui/src/app/dashboard-v2/dashboard.module.ts
@@ -13,12 +13,14 @@ import {FormsModule} from "@angular/forms";
 import {ColorPickerModule} from "ngx-color-picker";
 import {AddVisualizationDialogComponent} from "./dialogs/add-visualization-dialog.component";
 import {MatGridListModule} from "@angular/material/grid-list";
-import {WebsocketService} from "../app-asset-monitoring/services/websocket.service";
 import {ShapeService} from "../app-asset-monitoring/services/shape.service";
 import {ElementIconText} from "../services/get-element-icon-text.service";
 import {DashboardService} from "./services/dashboard.service";
 import {ConnectModule} from "../connect/connect.module";
 import {PropertySelectorService} from "../services/property-selector.service";
+import {NumberVizComponent} from "./components/widgets/number/number-viz.component";
+import {streamPipesStompConfig} from "./services/websocket.config";
+import {InjectableRxStompConfig, RxStompService, rxStompServiceFactory} from "@stomp/ng2-stompjs";
 //import { DashboardWidgetsModule } from 'dashboard-widgets';
 //import { FunnelChartComponent, ParliamentChartComponent, PieChartComponent, TimelineComponent } from
 // 'dashboard-widgets';
@@ -49,17 +51,26 @@ const dashboardWidgets = [
         DashboardComponent,
         DashboardPanelComponent,
         DashboardWidgetComponent,
-        AddVisualizationDialogComponent
+        AddVisualizationDialogComponent,
+        NumberVizComponent
     ],
     providers: [
-        WebsocketService,
         DashboardService,
         {
             provide: 'RestApi',
             useFactory: ($injector: any) => $injector.get('RestApi'),
             deps: ['$injector'],
         },
-        ElementIconText
+        ElementIconText,
+        {
+            provide: InjectableRxStompConfig,
+            useValue: streamPipesStompConfig
+        },
+        {
+            provide: RxStompService,
+            useFactory: rxStompServiceFactory,
+            deps: [InjectableRxStompConfig]
+        }
     ],
     exports: [
         DashboardComponent
diff --git a/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts b/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts
new file mode 100644
index 0000000..3789712
--- /dev/null
+++ b/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts
@@ -0,0 +1,32 @@
+import {EventSchema} from "../../../connect/schema-editor/model/EventSchema";
+import {StaticProperty} from "../../../connect/model/StaticProperty";
+import {MappingPropertyUnary} from "../../../connect/model/MappingPropertyUnary";
+import {FreeTextStaticProperty} from "../../../connect/model/FreeTextStaticProperty";
+
+export class StaticPropertyExtractor {
+
+    constructor(private inputSchema: EventSchema,
+                private staticProperties: Array<StaticProperty>) {
+
+    }
+
+    mappingPropertyValue(internalId: string): string {
+        let sp: MappingPropertyUnary = this.getStaticPropertyByName(internalId) as MappingPropertyUnary;
+        return this.removePrefix(sp.selectedProperty);
+    }
+
+    singleValueParameter(internalId: string): any {
+        let sp: FreeTextStaticProperty = this.getStaticPropertyByName(internalId) as FreeTextStaticProperty;
+        return sp.value;
+    }
+
+    getStaticPropertyByName(internalId: string): StaticProperty {
+        return this.staticProperties.find(sp => sp.internalName == internalId);
+    }
+
+
+    removePrefix(propertyValue: string) {
+        return propertyValue.split("::")[1];
+    }
+
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/services/websocket.config.ts b/ui/src/app/dashboard-v2/services/websocket.config.ts
new file mode 100644
index 0000000..de16545
--- /dev/null
+++ b/ui/src/app/dashboard-v2/services/websocket.config.ts
@@ -0,0 +1,18 @@
+import {InjectableRxStompConfig} from "@stomp/ng2-stompjs";
+import {WebsocketSettings} from "./websocket.settings";
+
+export const streamPipesStompConfig: InjectableRxStompConfig = {
+
+    brokerURL: new WebsocketSettings().getBrokerUrl(),
+
+    connectHeaders: {
+        login: 'admin',
+        passcode: 'admin'
+    },
+
+    heartbeatIncoming: 0,
+    heartbeatOutgoing: 20000,
+
+    reconnectDelay: 200,
+
+};
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/services/websocket.settings.ts b/ui/src/app/dashboard-v2/services/websocket.settings.ts
new file mode 100644
index 0000000..e274279
--- /dev/null
+++ b/ui/src/app/dashboard-v2/services/websocket.settings.ts
@@ -0,0 +1,14 @@
+export class WebsocketSettings {
+
+    getBrokerUrl(): string {
+        return this.getWebsocketScheme() + "//" + location.host + "/streampipes/ws";
+    }
+
+    getWebsocketScheme(): string {
+        if (location.protocol === 'https:') {
+            return "wss:";
+        } else {
+            return "ws:";
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/src/assets/dashboards.json b/ui/src/assets/dashboards.json
index d0d16d8..5ee2728 100644
--- a/ui/src/assets/dashboards.json
+++ b/ui/src/assets/dashboards.json
@@ -5,7 +5,7 @@
     "name": "Sample Dashboard 4",
     "widgets": [
       {
-        "id": "0bca595df0654a058f71eb7069e79d98",
+        "id": "9efc42508b0348a78304a84bbfda3363",
         "name": "Timeline",
         "component": "timeline",
         "widgetType": "number",