You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ze...@apache.org on 2021/06/15 09:52:32 UTC

[incubator-streampipes] 02/02: Create start adapter configuration component

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

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

commit 836573755c16ce348b50a7eaac0b0d83a98da4be
Author: Philipp Zehnder <ze...@fzi.de>
AuthorDate: Tue Jun 15 11:52:08 2021 +0200

    Create start adapter configuration component
---
 .../format-configuration.component.ts              |   2 +-
 .../new-adapter/new-adapter.component.html         |  13 ++-
 .../new-adapter/new-adapter.component.ts           |  73 ++----------
 .../event-schema/event-schema.component.ts         |   3 +-
 .../start-adapter-configuration.component.html     |  28 ++---
 .../start-adapter-configuration.component.ts       | 127 ++++++++++++++++++++-
 ui/src/app/connect/connect.module.ts               |   4 +-
 7 files changed, 165 insertions(+), 85 deletions(-)

diff --git a/ui/src/app/connect/components/format-configuration/format-configuration.component.ts b/ui/src/app/connect/components/format-configuration/format-configuration.component.ts
index 398b34a..6b7e014 100644
--- a/ui/src/app/connect/components/format-configuration/format-configuration.component.ts
+++ b/ui/src/app/connect/components/format-configuration/format-configuration.component.ts
@@ -36,7 +36,7 @@ export class FormatConfigurationComponent implements OnInit {
   allFormats: FormatDescription[] = [];
 
   /**
-   * The form group to validate the configuration for the foramt
+   * The form group to validate the configuration for the format
    */
   formatForm: FormGroup;
 
diff --git a/ui/src/app/connect/components/new-adapter/new-adapter.component.html b/ui/src/app/connect/components/new-adapter/new-adapter.component.html
index f1746da..4fc9934 100644
--- a/ui/src/app/connect/components/new-adapter/new-adapter.component.html
+++ b/ui/src/app/connect/components/new-adapter/new-adapter.component.html
@@ -26,8 +26,8 @@
                         <mat-icon *ngIf="isDataStreamDescription" class="real-time">lens
                         </mat-icon>
                         <div fxLayoutAlign="start center">
-                            <p *ngIf="isDataSetDescription">&nbsp;Data Set</p>
-                            <p *ngIf="isDataStreamDescription">&nbsp;Data Stream</p>
+                            <p *ngIf="isDataSetDescription">Data Set</p>
+                            <p *ngIf="isDataStreamDescription">Data Stream</p>
                         </div>
                     </div>
                 </div>
@@ -41,6 +41,7 @@
             </button>
         </div>
     </div>
+
     <mat-horizontal-stepper [linear]="true" #stepper>
 
         <mat-step *ngIf="!isGenericAdapter">
@@ -108,11 +109,13 @@
         </mat-step>
 
         <mat-step>
-
             <sp-start-adapter-configuration
-            >
+                    [adapterDescription]="adapter"
+                    [stepper]="stepper"
+                    (removeSelectionEmitter)="removeSelection()"
+                    (goBackEmitter)="goBack($event)"
+                    (adapterStartedEmitter)="adapterWasStarted()">
             </sp-start-adapter-configuration>
-
         </mat-step>
 
     </mat-horizontal-stepper>
diff --git a/ui/src/app/connect/components/new-adapter/new-adapter.component.ts b/ui/src/app/connect/components/new-adapter/new-adapter.component.ts
index 27274f5..a579b39 100644
--- a/ui/src/app/connect/components/new-adapter/new-adapter.component.ts
+++ b/ui/src/app/connect/components/new-adapter/new-adapter.component.ts
@@ -68,6 +68,8 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
     isDataStreamDescription = false;
 
 
+    dataLakeTimestampField: string;
+
     @Input()
     adapter: AdapterDescriptionUnion;
 
@@ -77,23 +79,15 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
     @Output()
     updateAdapterEmitter: EventEmitter<void> = new EventEmitter<void>();
 
+
     @ViewChild('stepper', { static: true }) myStepper: MatStepper;
 
 
     protocolConfigurationValid: boolean;
     formatConfigurationValid: boolean;
 
-    removeDuplicates = false;
-    removeDuplicatesTime: number;
-
-    eventRateReduction = false;
-    eventRateTime: number;
-    eventRateMode = 'none';
-
-    saveInDataLake = false;
-    dataLakeTimestampField: string;
 
-    startAdapterFormGroup: FormGroup;
+    // startAdapterFormGroup: FormGroup;
 
     eventSchema: EventSchema;
     oldEventSchema: EventSchema;
@@ -111,7 +105,6 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
     @ViewChild(EventSchemaComponent, { static: true })
     private eventSchemaComponent: EventSchemaComponent;
 
-    isSetAdapter = false;
 
     completedStaticProperty: ConfigurationInfo;
 
@@ -125,7 +118,6 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
         private logger: Logger,
         private restService: RestService,
         private transformationRuleService: TransformationRuleService,
-        private dialogService: DialogService,
         private shepherdService: ShepherdService,
         private connectService: ConnectService,
         private _formBuilder: FormBuilder,
@@ -157,9 +149,9 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
         this.formatConfigurationValid = false;
 
 
-        this.startAdapterFormGroup = this._formBuilder.group({
-            startAdapterFormCtrl: ['', Validators.required]
-        });
+        // this.startAdapterFormGroup = this._formBuilder.group({
+        //     startAdapterFormCtrl: ['', Validators.required]
+        // });
 
         this.protocolConfigurationValid = false;
 
@@ -168,7 +160,7 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
         if (this.eventSchema.eventProperties.length > 0) {
 
             // Timeout is needed for stepper to work correctly. Without the stepper is frozen when initializing with
-            // step 2. Can be removed when a better solution is founf.
+            // step 2. Can be removed when a better solution is found.
             setTimeout(() => {
                 this.goForward(this.myStepper);
                 this.goForward(this.myStepper);
@@ -194,48 +186,7 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
         this.isPreviewEnabled = isPreviewEnabled;
     }
 
-    public triggerDialog(storeAsTemplate: boolean) {
-        if (this.removeDuplicates) {
-            const removeDuplicates: RemoveDuplicatesTransformationRuleDescription = new RemoveDuplicatesTransformationRuleDescription();
-            removeDuplicates['@class'] = 'org.apache.streampipes.model.connect.rules.stream.RemoveDuplicatesTransformationRuleDescription';
-            removeDuplicates.filterTimeWindow = (this.removeDuplicatesTime) as any;
-            this.adapter.rules.push(removeDuplicates);
-        }
-        if (this.eventRateReduction) {
-            const eventRate: EventRateTransformationRuleDescription = new EventRateTransformationRuleDescription();
-            eventRate['@class'] = 'org.apache.streampipes.model.connect.rules.stream.EventRateTransformationRuleDescription';
-            eventRate.aggregationTimeWindow = this.eventRateMode as any;
-            eventRate.aggregationType = this.eventRateMode;
-            this.adapter.rules.push(eventRate);
-        }
 
-        const dialogRef = this.dialogService.open(AdapterStartedDialog, {
-            panelType: PanelType.STANDARD_PANEL,
-            title: 'Adapter generation',
-            width: '70vw',
-            data: {
-                'adapter': this.adapter,
-                'storeAsTemplate': storeAsTemplate,
-                'saveInDataLake': this.saveInDataLake,
-                'dataLakeTimestampField': this.dataLakeTimestampField
-            }
-        });
-
-        this.shepherdService.trigger('button-startAdapter');
-
-        dialogRef.afterClosed().subscribe(result => {
-            this.updateAdapterEmitter.emit();
-            this.removeSelectionEmitter.emit();
-        });
-    }
-
-    public saveTemplate() {
-        this.triggerDialog(true);
-    }
-
-    public startAdapter() {
-        this.triggerDialog(false);
-    }
 
     validateFormat(valid) {
         this.formatConfigurationValid = valid;
@@ -274,9 +225,6 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
         this.shepherdService.trigger('event-schema-next-button');
         this.goForward(stepper);
 
-        if (this.adapter instanceof GenericAdapterSetDescription || this.adapter instanceof SpecificAdapterSetDescription) {
-            this.isSetAdapter = true;
-        }
 
     }
 
@@ -348,7 +296,8 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
         this.myStepper.selectedIndex = this.myStepper.selectedIndex + 1;
     }
 
-    triggerUpdate(configurationInfo: ConfigurationInfo) {
-        this.completedStaticProperty = {...configurationInfo};
+    public adapterWasStarted() {
+        this.updateAdapterEmitter.emit();
+        this.removeSelectionEmitter.emit();
     }
 }
diff --git a/ui/src/app/connect/components/schema-editor/event-schema/event-schema.component.ts b/ui/src/app/connect/components/schema-editor/event-schema/event-schema.component.ts
index 2dc751a..beecff6 100644
--- a/ui/src/app/connect/components/schema-editor/event-schema/event-schema.component.ts
+++ b/ui/src/app/connect/components/schema-editor/event-schema/event-schema.component.ts
@@ -88,7 +88,6 @@ export class EventSchemaComponent implements OnChanges {
     this.isLoading = true;
     this.isError = false;
     this.restService.getGuessSchema(this.adapterDescription).subscribe(guessSchema => {
-      this.isLoading = false;
       this.eventSchema = guessSchema.eventSchema;
       this.eventSchema.eventProperties.sort((a, b) => {
         return a.runtimeName < b.runtimeName ? -1 : 1;
@@ -103,6 +102,7 @@ export class EventSchemaComponent implements OnChanges {
 
       this.isEditable = true;
       this.isEditableChange.emit(true);
+      this.isLoading = false;
     },
       errorMessage => {
         this.errorMessages = errorMessage.error.notifications;
@@ -186,4 +186,5 @@ export class EventSchemaComponent implements OnChanges {
   ngOnChanges(changes: SimpleChanges) {
     setTimeout(() => { this.refreshTree() }, 200);
   }
+
 }
diff --git a/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.html b/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.html
index 67cedd4..47df4ae 100644
--- a/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.html
+++ b/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.html
@@ -1,20 +1,21 @@
-<div [formGroup]="startAdapterFormGroup">
+<div [formGroup]="startAdapterForm">
     <ng-template matStepLabel>Start Adapter</ng-template>
     <div class="assemblyOptions sp-blue-bg">
         <h4>Adapter settings</h4>
     </div>
 
-    <div class="sp-blue-border padding">
+    <div class="sp-blue-border padding" style="padding: 15px; margin-bottom: 2%;">
         <div fxLayoutAlign="center" fxLayout="column" fxFlex="100">
             <mat-form-field>
-                <input matInput id="input-AdapterName" placeholder="Adapter Name"
-                       formControlName="startAdapterFormCtrl" [(ngModel)]="adapter.name">
+                <input matInput id="input-AdapterName"  [ngModelOptions]="{standalone: true}" placeholder="Adapter Name"
+                       [(ngModel)]="adapterDescription.name">
             </mat-form-field>
             <mat-form-field>
                 <input matInput id="input-AdapterDescription" [ngModelOptions]="{standalone: true}"
-                       placeholder="Adapter Description" [(ngModel)]="adapter.description">
+                       placeholder="Adapter Description" [(ngModel)]="adapterDescription.description">
             </mat-form-field>
 
+            <!-- Provide icon for adapter -->
             <!--                        <mat-form-field *ngIf="isEditable" style="width: 50%" (click)="fileInput.click();">-->
             <!--                            <input matInput placeholder="Icon" disabled (value)="fileName">-->
             <!--                            <input #fileInput type="file" style="display:none;"-->
@@ -26,20 +27,20 @@
             <!--                        </mat-form-field>-->
 
 
-            <mat-checkbox [disabled]="!isEditable" [(ngModel)]="removeDuplicates"
+            <mat-checkbox [(ngModel)]="removeDuplicates"
                           [ngModelOptions]="{standalone: true}">Remove Duplicates</mat-checkbox>
             <mat-form-field *ngIf="removeDuplicates">
-                <input [disabled]="!isEditable" matInput id="input-removeDuplicatesTime"
+                <input matInput id="input-removeDuplicatesTime"
                        [ngModelOptions]="{standalone: true}" placeholder="Remove Duplicates Time Window"
                        [(ngModel)]="removeDuplicatesTime">
             </mat-form-field>
 
-            <mat-checkbox [disabled]="!isEditable" [(ngModel)]="eventRateReduction"
+            <mat-checkbox [(ngModel)]="eventRateReduction"
                           [ngModelOptions]="{standalone: true}"
                           matTooltip="Send maximum one event in the specified time window">Reduce the event rate
             </mat-checkbox>
             <mat-form-field *ngIf="eventRateReduction">
-                <input [disabled]="!isEditable" type="number" matInput id="input-evenRateTime"
+                <input type="number" matInput id="input-evenRateTime"
                        [ngModelOptions]="{standalone: true}" [(ngModel)]="eventRateTime"
                        placeholder="Time Window (Milliseconds)" matTooltipPosition="above">
             </mat-form-field>
@@ -53,6 +54,7 @@
                 </mat-select>
             </mat-form-field>
 
+            <!-- Start pipeline template to store raw events in data lake -->
             <!--<mat-checkbox *ngIf="timestampPropertiesInSchema.length == 0"-->
             <!--[disabled]="timestampPropertiesInSchema.length == 0" [(ngModel)]="saveInDataLake"-->
             <!--[ngModelOptions]="{standalone: true}">Store in Datalake (Timestamp required)</mat-checkbox>-->
@@ -69,7 +71,7 @@
             <!--</mat-select>-->
             <!--</mat-form-field>-->
 
-            <mat-checkbox *ngIf="isSetAdapter" [(ngModel)]="adapter.stopPipeline"
+            <mat-checkbox *ngIf="isSetAdapter" [(ngModel)]="adapterDescription.stopPipeline"
                           [ngModelOptions]="{standalone: true}">Stop pipeline when replay is completed</mat-checkbox>
 
         </div>
@@ -77,13 +79,13 @@
 
     <div fxLayoutAlign="end">
         <button class="mat-basic" mat-raised-button (click)="removeSelection()">Cancel</button>
-        <button class="mat-basic stepper-button" mat-raised-button (click)="goBack(stepper)">Back</button>
-        <button [disabled]="startAdapterFormGroup.invalid || !isEditable" mat-raised-button
+        <button style="margin-left:10px;" class="mat-basic stepper-button" mat-raised-button (click)="goBack()">Back</button>
+        <button [disabled]="startAdapterSettingsFormValid" mat-raised-button
                 id="button-saveTemplate" color="primary" (click)="saveTemplate()" mat-button
                 style="margin-left:10px;">
             Save as Template
         </button>
-        <button [disabled]="startAdapterFormGroup.invalid" mat-raised-button id="button-startAdapter"
+        <button [disabled]="startAdapterSettingsFormValid" mat-raised-button id="button-startAdapter"
                 color="primary" (click)="startAdapter()" mat-button style="margin-left:10px;">
             Start Adapter
         </button>
diff --git a/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.ts b/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.ts
index 4cab09a..85e2f9e 100644
--- a/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.ts
+++ b/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.ts
@@ -1,4 +1,15 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import {
+  AdapterDescriptionUnion,
+  EventRateTransformationRuleDescription, GenericAdapterSetDescription,
+  RemoveDuplicatesTransformationRuleDescription, SpecificAdapterSetDescription
+} from '../../../core-model/gen/streampipes-model';
+import { FormBuilder, FormGroup } from '@angular/forms';
+import { MatStepper } from '@angular/material/stepper';
+import { AdapterStartedDialog } from '../../dialog/adapter-started/adapter-started-dialog.component';
+import { PanelType } from '../../../core-ui/dialog/base-dialog/base-dialog.model';
+import { ShepherdService } from '../../../services/tour/shepherd.service';
+import { DialogService } from '../../../core-ui/dialog/base-dialog/base-dialog.service';
 
 @Component({
   selector: 'sp-start-adapter-configuration',
@@ -7,9 +18,121 @@ import { Component, OnInit } from '@angular/core';
 })
 export class StartAdapterConfigurationComponent implements OnInit {
 
-  constructor() { }
+  /**
+   * Adapter description the selected format is added to
+   */
+  @Input() adapterDescription: AdapterDescriptionUnion;
+
+  /**
+   * Mat stepper to trigger next confifuration step when this is completed
+   */
+  @Input() stepper: MatStepper;
+
+  /**
+   * Cancels the adapter configuration process
+   */
+  @Output() removeSelectionEmitter: EventEmitter<boolean> = new EventEmitter();
+
+  /**
+   * Is called when the adapter was created
+   */
+  @Output() adapterStartedEmitter: EventEmitter<void> = new EventEmitter<void>();
+
+
+  /**
+   * Go to next configuration step when this is complete
+   */
+  @Output() goBackEmitter: EventEmitter<MatStepper> = new EventEmitter();
+
+  @Output() updateAdapterEmitter: EventEmitter<void> = new EventEmitter<void>();
+
+  /**
+   * The form group to validate the configuration for the format
+   */
+  startAdapterForm: FormGroup;
+
+  startAdapterSettingsFormValid = false;
+
+
+  // preprocessing rule variables
+  removeDuplicates = false;
+  removeDuplicatesTime: number;
+
+  eventRateReduction = false;
+  eventRateTime: number;
+  eventRateMode = 'none';
+
+  saveInDataLake = false;
+  dataLakeTimestampField: string;
+
+  isSetAdapter = false;
+
+
+  constructor(
+    private dialogService: DialogService,
+    private shepherdService: ShepherdService,
+    private _formBuilder: FormBuilder) { }
 
   ngOnInit(): void {
+    // initialize form for validation
+    this.startAdapterForm = this._formBuilder.group({});
+    this.startAdapterForm.statusChanges.subscribe((status) => {
+      this.startAdapterSettingsFormValid = this.startAdapterForm.valid;
+    });
+
+    if (this.adapterDescription instanceof GenericAdapterSetDescription ||
+                                              this.adapterDescription instanceof SpecificAdapterSetDescription) {
+      this.isSetAdapter = true;
+    }
+
+  }
+  public triggerDialog(storeAsTemplate: boolean) {
+    if (this.removeDuplicates) {
+      const removeDuplicates: RemoveDuplicatesTransformationRuleDescription = new RemoveDuplicatesTransformationRuleDescription();
+      removeDuplicates['@class'] = 'org.apache.streampipes.model.connect.rules.stream.RemoveDuplicatesTransformationRuleDescription';
+      removeDuplicates.filterTimeWindow = (this.removeDuplicatesTime) as any;
+      this.adapterDescription.rules.push(removeDuplicates);
+    }
+    if (this.eventRateReduction) {
+      const eventRate: EventRateTransformationRuleDescription = new EventRateTransformationRuleDescription();
+      eventRate['@class'] = 'org.apache.streampipes.model.connect.rules.stream.EventRateTransformationRuleDescription';
+      eventRate.aggregationTimeWindow = this.eventRateMode as any;
+      eventRate.aggregationType = this.eventRateMode;
+      this.adapterDescription.rules.push(eventRate);
+    }
+
+    const dialogRef = this.dialogService.open(AdapterStartedDialog, {
+      panelType: PanelType.STANDARD_PANEL,
+      title: 'Adapter generation',
+      width: '70vw',
+      data: {
+        'adapter': this.adapterDescription,
+        'storeAsTemplate': storeAsTemplate,
+        'saveInDataLake': this.saveInDataLake,
+        'dataLakeTimestampField': this.dataLakeTimestampField
+      }
+    });
+
+    this.shepherdService.trigger('button-startAdapter');
+
+    dialogRef.afterClosed().subscribe(result => {
+      this.adapterStartedEmitter.emit();
+    });
   }
 
+  public saveTemplate() {
+    this.triggerDialog(true);
+  }
+
+  public startAdapter() {
+    this.triggerDialog(false);
+  }
+
+  public removeSelection() {
+    this.removeSelectionEmitter.emit();
+  }
+
+  public goBack() {
+    this.goBackEmitter.emit(this.stepper);
+  }
 }
diff --git a/ui/src/app/connect/connect.module.ts b/ui/src/app/connect/connect.module.ts
index 47a4223..816b567 100644
--- a/ui/src/app/connect/connect.module.ts
+++ b/ui/src/app/connect/connect.module.ts
@@ -78,6 +78,7 @@ import { GenericAdapterConfigurationComponent } from './components/generic-adapt
 import { ErrorMessageComponent } from './components/schema-editor/error-message/error-message.component';
 import { LoadingMessageComponent } from './components/schema-editor/loading-message/loading-message.component';
 import { SchemaEditorHeaderComponent } from './components/schema-editor/schema-editor-header/schema-editor-header.component';
+import { StartAdapterConfigurationComponent } from './components/start-adapter-configuration/start-adapter-configuration.component';
 
 @NgModule({
     imports: [
@@ -129,7 +130,8 @@ import { SchemaEditorHeaderComponent } from './components/schema-editor/schema-e
         ConfigurationGroupComponent,
         ErrorMessageComponent,
         LoadingMessageComponent,
-        SchemaEditorHeaderComponent
+        SchemaEditorHeaderComponent,
+        StartAdapterConfigurationComponent
     ],
     providers: [
         RestService,