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/06/05 14:10:06 UTC

[incubator-streampipes] branch STREAMPIPES-145 updated: [STREAMPIPES-145] Add pipeline assembly component, move pipeline services to editor module

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

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


The following commit(s) were added to refs/heads/STREAMPIPES-145 by this push:
     new 1da937d  [STREAMPIPES-145] Add pipeline assembly component, move pipeline services to editor module
1da937d is described below

commit 1da937de23647f7823b3b9897430af8e5788bcc1
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Fri Jun 5 16:09:45 2020 +0200

    [STREAMPIPES-145] Add pipeline assembly component, move pipeline services to editor module
---
 ui/package.json                                    |   1 +
 ui/src/app/core-model/gen/streampipes-model.ts     |  33 +++-
 .../pipeline-assembly.component.html               | 115 ++++++++++++
 .../pipeline-assembly.component.ts                 | 203 ++++++++++++++++++++-
 .../pipeline-element-icon-stand.component.html     |   8 +-
 .../pipeline-element-icon-stand.component.ts       |  39 +++-
 ui/src/app/editor-v2/editor.component.html         |   4 +-
 ui/src/app/editor-v2/editor.component.ts           |  93 ++++++----
 ui/src/app/editor-v2/editor.module.ts              |  21 ++-
 ui/src/app/editor-v2/model/editor.model.ts         |   9 +
 .../services/editor-dialog-manager.service.ts      |  32 ++--
 ui/src/app/editor-v2/services/editor.service.ts    |  49 +----
 .../services/jsplumb-bridge.service.ts             |   3 +
 .../services/jsplumb-config.service.ts             |   3 +
 .../{ => editor-v2}/services/jsplumb.service.ts    |  19 +-
 .../services/pipeline-editor.service.ts            |   5 +-
 .../services/pipeline-positioning.service.ts       |  15 +-
 .../services/pipeline-validation.service.ts        |  12 +-
 .../pipeline-assembly.controller.ts                |   2 +-
 .../pipeline-element-icon-stand.controller.ts      |   2 +-
 .../pipeline-element-options.controller.ts         |   6 +-
 .../components/pipeline/pipeline.controller.ts     |   2 +-
 ui/src/app/editor/editor.controller.ts             |   4 +-
 ui/src/app/editor/editor.module.ts                 |   4 +-
 .../apis/pipeline-element.service.ts               |  69 +++++++
 .../contants/pipeline-element-constants.ts}        |  17 --
 ui/src/app/platform-services/platform.module.ts    |  19 +-
 ui/src/app/services/services.module.ts             |  18 +-
 ui/src/app/services/transition.service.ts          |   3 +
 ui/src/scss/sp/main.scss                           |   1 +
 30 files changed, 616 insertions(+), 195 deletions(-)

diff --git a/ui/package.json b/ui/package.json
index 195fcba..176c836 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -44,6 +44,7 @@
     "angular-clipboard": "1.4.2",
     "angular-cookies": "1.7.7",
     "angular-datatables": "0.6.2",
+    "angular-draggable-droppable": "4.4.6",
     "angular-gridster2": "8.3.0",
     "angular-loading-bar": "0.8.0",
     "angular-markdown-directive": "0.3.1",
diff --git a/ui/src/app/core-model/gen/streampipes-model.ts b/ui/src/app/core-model/gen/streampipes-model.ts
index 36cadc9..d13d799 100644
--- a/ui/src/app/core-model/gen/streampipes-model.ts
+++ b/ui/src/app/core-model/gen/streampipes-model.ts
@@ -1,10 +1,10 @@
 /* tslint:disable */
 /* eslint-disable */
 // @ts-nocheck
-// Generated using typescript-generator version 2.23.603 on 2020-06-02 23:02:02.
+// Generated using typescript-generator version 2.23.603 on 2020-06-04 13:25:46.
 
 export class AbstractStreamPipesEntity {
-    "@class": "org.apache.streampipes.model.base.NamedStreamPipesEntity" | "org.apache.streampipes.model.connect.grounding.ProtocolDescription" | "org.apache.streampipes.model.connect.adapter.AdapterDescription" | "org.apache.streampipes.model.connect.adapter.AdapterSetDescription" | "org.apache.streampipes.model.connect.adapter.GenericAdapterSetDescription" | "org.apache.streampipes.model.connect.adapter.SpecificAdapterSetDescription" | "org.apache.streampipes.model.connect.adapter.Adap [...]
+    "@class": "org.apache.streampipes.model.base.NamedStreamPipesEntity" | "org.apache.streampipes.model.graph.DataSourceDescription" | "org.apache.streampipes.model.SpDataStream" | "org.apache.streampipes.model.SpDataSet" | "org.apache.streampipes.model.connect.grounding.ProtocolDescription" | "org.apache.streampipes.model.connect.adapter.AdapterDescription" | "org.apache.streampipes.model.connect.adapter.AdapterSetDescription" | "org.apache.streampipes.model.connect.adapter.GenericAdap [...]
 
     static fromData(data: AbstractStreamPipesEntity, target?: AbstractStreamPipesEntity): AbstractStreamPipesEntity {
         if (!data) {
@@ -29,7 +29,7 @@ export class AbstractStreamPipesEntity {
 }
 
 export class UnnamedStreamPipesEntity extends AbstractStreamPipesEntity {
-    "@class": "org.apache.streampipes.model.base.UnnamedStreamPipesEntity" | "org.apache.streampipes.model.staticproperty.StaticProperty" | "org.apache.streampipes.model.staticproperty.CodeInputStaticProperty" | "org.apache.streampipes.model.staticproperty.CollectionStaticProperty" | "org.apache.streampipes.model.staticproperty.ColorPickerStaticProperty" | "org.apache.streampipes.model.staticproperty.DomainStaticProperty" | "org.apache.streampipes.model.staticproperty.FileStaticProperty" [...]
+    "@class": "org.apache.streampipes.model.base.UnnamedStreamPipesEntity" | "org.apache.streampipes.model.staticproperty.StaticProperty" | "org.apache.streampipes.model.staticproperty.CodeInputStaticProperty" | "org.apache.streampipes.model.staticproperty.CollectionStaticProperty" | "org.apache.streampipes.model.staticproperty.ColorPickerStaticProperty" | "org.apache.streampipes.model.staticproperty.DomainStaticProperty" | "org.apache.streampipes.model.staticproperty.FileStaticProperty" [...]
     elementId: string;
 
     static fromData(data: UnnamedStreamPipesEntity, target?: UnnamedStreamPipesEntity): UnnamedStreamPipesEntity {
@@ -120,7 +120,7 @@ export class UnnamedStreamPipesEntity extends AbstractStreamPipesEntity {
 }
 
 export class MeasurementProperty extends UnnamedStreamPipesEntity {
-    "@class": "org.apache.streampipes.model.quality.MeasurementProperty" | "org.apache.streampipes.model.quality.EventPropertyQualityDefinition" | "org.apache.streampipes.model.quality.Accuracy" | "org.apache.streampipes.model.quality.MeasurementRange" | "org.apache.streampipes.model.quality.Precision" | "org.apache.streampipes.model.quality.Resolution" | "org.apache.streampipes.model.quality.EventStreamQualityDefinition" | "org.apache.streampipes.model.quality.Frequency" | "org.apache.s [...]
+    "@class": "org.apache.streampipes.model.quality.MeasurementProperty" | "org.apache.streampipes.model.quality.EventStreamQualityDefinition" | "org.apache.streampipes.model.quality.Frequency" | "org.apache.streampipes.model.quality.Latency" | "org.apache.streampipes.model.quality.EventPropertyQualityDefinition" | "org.apache.streampipes.model.quality.Accuracy" | "org.apache.streampipes.model.quality.MeasurementRange" | "org.apache.streampipes.model.quality.Precision" | "org.apache.stre [...]
 
     static fromData(data: MeasurementProperty, target?: MeasurementProperty): MeasurementProperty {
         if (!data) {
@@ -189,7 +189,7 @@ export class Accuracy extends EventPropertyQualityDefinition {
 }
 
 export class NamedStreamPipesEntity extends AbstractStreamPipesEntity {
-    "@class": "org.apache.streampipes.model.base.NamedStreamPipesEntity" | "org.apache.streampipes.model.connect.grounding.ProtocolDescription" | "org.apache.streampipes.model.connect.adapter.AdapterDescription" | "org.apache.streampipes.model.connect.adapter.AdapterSetDescription" | "org.apache.streampipes.model.connect.adapter.GenericAdapterSetDescription" | "org.apache.streampipes.model.connect.adapter.SpecificAdapterSetDescription" | "org.apache.streampipes.model.connect.adapter.Adap [...]
+    "@class": "org.apache.streampipes.model.base.NamedStreamPipesEntity" | "org.apache.streampipes.model.graph.DataSourceDescription" | "org.apache.streampipes.model.SpDataStream" | "org.apache.streampipes.model.SpDataSet" | "org.apache.streampipes.model.connect.grounding.ProtocolDescription" | "org.apache.streampipes.model.connect.adapter.AdapterDescription" | "org.apache.streampipes.model.connect.adapter.AdapterSetDescription" | "org.apache.streampipes.model.connect.adapter.GenericAdap [...]
     appId: string;
     applicationLinks: ApplicationLink[];
     connectedTo: string[];
@@ -259,9 +259,9 @@ export class AdapterDescription extends NamedStreamPipesEntity {
         instance.config = __getCopyArrayFn(StaticProperty.fromDataUnion)(data.config);
         instance.rules = __getCopyArrayFn(TransformationRuleDescription.fromDataUnion)(data.rules);
         instance.category = __getCopyArrayFn(__identity<string>())(data.category);
+        instance.valueRules = __getCopyArrayFn(__identity<any>())(data.valueRules);
         instance.streamRules = __getCopyArrayFn(__identity<any>())(data.streamRules);
         instance.schemaRules = __getCopyArrayFn(__identity<any>())(data.schemaRules);
-        instance.valueRules = __getCopyArrayFn(__identity<any>())(data.valueRules);
         return instance;
     }
 
@@ -1031,6 +1031,23 @@ export class DataSinkType {
     }
 }
 
+export class DataSourceDescription extends NamedStreamPipesEntity {
+    "@class": "org.apache.streampipes.model.graph.DataSourceDescription";
+    correspondingSourceId: string;
+    spDataStreams: SpDataStreamUnion[];
+
+    static fromData(data: DataSourceDescription, target?: DataSourceDescription): DataSourceDescription {
+        if (!data) {
+            return data;
+        }
+        const instance = target || new DataSourceDescription();
+        super.fromData(data, instance);
+        instance.spDataStreams = __getCopyArrayFn(SpDataStream.fromDataUnion)(data.spDataStreams);
+        instance.correspondingSourceId = data.correspondingSourceId;
+        return instance;
+    }
+}
+
 export class DeleteRuleDescription extends SchemaTransformationRuleDescription {
     "@class": "org.apache.streampipes.model.connect.rules.schema.DeleteRuleDescription";
     runtimeKey: string;
@@ -1505,9 +1522,9 @@ export class GenericAdapterSetDescription extends AdapterSetDescription implemen
         }
         const instance = target || new GenericAdapterSetDescription();
         super.fromData(data, instance);
+        instance.eventSchema = EventSchema.fromData(data.eventSchema);
         instance.protocolDescription = ProtocolDescription.fromData(data.protocolDescription);
         instance.formatDescription = FormatDescription.fromData(data.formatDescription);
-        instance.eventSchema = EventSchema.fromData(data.eventSchema);
         return instance;
     }
 }
@@ -2213,8 +2230,8 @@ export class SpDataSet extends SpDataStream {
         instance.supportedGrounding = EventGrounding.fromData(data.supportedGrounding);
         instance.datasetInvocationId = data.datasetInvocationId;
         instance.correspondingPipeline = data.correspondingPipeline;
-        instance.brokerHostname = data.brokerHostname;
         instance.actualTopicName = data.actualTopicName;
+        instance.brokerHostname = data.brokerHostname;
         return instance;
     }
 }
diff --git a/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.html b/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.html
index e69de29..8f0545a 100644
--- a/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.html
+++ b/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.html
@@ -0,0 +1,115 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  ~
+  -->
+
+<div>
+    <div class="assemblyOptions sp-blue-bg">
+        <div fxFlex="100" fxLayout="row" fxLayoutAlign="start center">
+            <button mat-button style="display:flex;align-items:center;" class="md-button settings-bar-icon-button"
+                       ng-disabled="!pipelineValid"
+                       (click)="submit()" type="submit">
+<!--                <md-tooltip md-direction="top">-->
+<!--                    Save Pipeline-->
+<!--                </md-tooltip>-->
+                <mat-icon>save</mat-icon>&nbsp;Save pipeline
+            </button>
+            <button mat-button class="md-icon-button settings-bar-icon-button"
+                       ng-disabled="!selectMode"
+                       (click)="toggleSelectMode()">
+<!--                <md-tooltip md-direction="top">-->
+<!--                    Pan-->
+<!--                </md-tooltip>-->
+                <i class="material-icons">open_with</i>
+            </button>
+            <button mat-button class="md-icon-button settings-bar-icon-button" ng-disabled="selectMode"
+                       (click)="toggleSelectMode()">
+                <i class="material-icons">mode_edit</i>
+<!--                <md-tooltip md-direction="top">-->
+<!--                    Select-->
+<!--                </md-tooltip>-->
+            </button>
+            <button mat-button class="md-icon-button settings-bar-icon-button" ng-disabled="currentZoomLevel == 1"
+                       (click)="zoomIn()">
+                <i class="material-icons">zoom_in</i>
+<!--                <md-tooltip md-direction="top">-->
+<!--                    Zoom In-->
+<!--                </md-tooltip>-->
+            </button>
+            <button mat-button class="md-icon-button settings-bar-icon-button" ng-disabled="currentZoomLevel == 0.5"
+                       (click)="zoomOut()">
+                <i class="material-icons">zoom_out</i>
+<!--                <md-tooltip md-direction="top">-->
+<!--                    Zoom Out-->
+<!--                </md-tooltip>-->
+            </button>
+            <button mat-button class="md-icon-button settings-bar-icon-button" (click)="autoLayout()">
+                <i class="material-icons">settings_overscan</i>
+<!--                <md-tooltip md-direction="top">-->
+<!--                    Auto Layout-->
+<!--                </md-tooltip>-->
+            </button>
+            <div class="pipeline-cache-block">
+                <div ng-if="pipelineCached">All pipeline modifications saved.</div>
+<!--                <div ng-if="pipelineCacheRunning"><md-progress-circular-->
+<!--                        md-mode="indeterminate" class="pipeline-cache-progress"-->
+<!--                        md-diameter="10"></md-progress-circular>&nbsp;Saving pipeline-->
+<!--                    modifications</div>-->
+            </div>
+            <span fxFlex></span>
+            <div style="position:relative;">
+                <div *ngIf="!isPipelineAssemblyEmpty()" class="pipeline-validation-summary {{PipelineValidationService.errorMessages.length > 0 ? 'pipeline-validation-summary-error' : ''}}" ng-click="toggleErrorMessagesDisplayed()">
+                    <div fxLayout="row" fxLayoutAlign="center center">
+                        <div fxLayout="row" fxLayoutAlign="start center">
+                            <i class="material-icons" ng-if="PipelineValidationService.errorMessages.length > 0">notifications</i>
+                            <i class="material-icons" ng-if="PipelineValidationService.errorMessages.length === 0">done</i>
+                        </div>
+                        <div>
+                            <span *ngIf="PipelineValidationService.errorMessages.length === 0">Pipeline ok</span>
+                            <span *ngIf="PipelineValidationService.errorMessages.length > 0">{{PipelineValidationService.errorMessages.length}} {{PipelineValidationService.errorMessages.length > 1 ? 'hints' : 'hint'}}</span>
+                        </div>
+                    </div>
+                </div>
+                <div class="editor-error-notifications" *ngIf="PipelineValidationService.errorMessages.length > 0 && errorMessagesDisplayed">
+                    <h5 style="color:darkred"><b>{{PipelineValidationService.errorMessages.length}} {{PipelineValidationService.errorMessages.length == 1 ? "error" : "errors"}} found.</b></h5>
+                    <hr/>
+                    <div *ngFor="let errorMessage of PipelineValidationService.errorMessages">
+                            <b>{{errorMessage.title}}</b>
+                        <div>{{errorMessage.content}}</div>
+                        <hr/>
+                    </div>
+                </div>
+            </div>
+            <button mat-button class="md-icon-button" ng-click="showClearAssemblyConfirmDialog($event)">
+                <i class="material-icons">clear</i>
+<!--                <md-tooltip md-direction="top">-->
+<!--                    Clear Assembly Area-->
+<!--                </md-tooltip>-->
+            </button>
+        </div>
+    </div>
+    <div id="outerAssemblyArea" class="outerAssembly sp-blue-border-nopadding">
+        <div mwlDroppable id="assembly" class="canvas" (drop)="elementDropped($event)">
+<!--            <pipeline pipeline-valid="ctrl.pipelineValid"-->
+<!--                      canvas-id="assembly"-->
+<!--                      raw-pipeline-model="ctrl.rawPipelineModel"-->
+<!--                      all-elements="ctrl.allElements"-->
+<!--                      preview="false"-->
+<!--                      pipeline-cached="ctrl.pipelineCached"-->
+<!--                      pipeline-cache-running="ctrl.pipelineCacheRunning"></pipeline>-->
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.ts b/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.ts
index 3a31d2c..b4fccc4 100644
--- a/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.ts
+++ b/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.ts
@@ -17,9 +17,17 @@
  */
 
 import {
-    Component,
+    Component, Input,
     OnInit,
 } from "@angular/core";
+import {JsplumbBridge} from "../../services/jsplumb-bridge.service";
+import {PipelinePositioningService} from "../../services/pipeline-positioning.service";
+import {EditorDialogManager} from "../../services/editor-dialog-manager.service";
+import {PipelineValidationService} from "../../services/pipeline-validation.service";
+import {JsplumbService} from "../../services/jsplumb.service";
+import {RestApi} from "../../../services/rest-api.service";
+import {TransitionService} from "../../../services/transition.service";
+import {ShepherdService} from "../../../services/tour/shepherd.service";
 
 
 @Component({
@@ -29,7 +37,200 @@ import {
 })
 export class PipelineAssemblyComponent implements OnInit {
 
+    PipelineEditorService: any;
+    ObjectProvider: any;
+    DialogBuilder: any;
+    currentMouseOverElement: any;
+    currentZoomLevel: any;
+    preview: any;
+
+    @Input()
+    rawPipelineModel: any;
+    selectMode: any;
+    currentPipelineName: any;
+    currentPipelineDescription: any;
+
+    @Input()
+    currentModifiedPipelineId: any;
+
+    @Input()
+    allElements: any;
+
+    errorMessagesDisplayed: any = false;
+
+    pipelineValid: boolean = false;
+
+    pipelineCacheRunning: boolean = false;
+    pipelineCached: boolean = false;
+
+    // Remove later
+    EditorDialogManager: any;
+    TransitionService: any;
+
+    constructor(private JsplumbBridge: JsplumbBridge,
+                private PipelinePositioningService: PipelinePositioningService,
+                //private EditorDialogManager: EditorDialogManager,
+                public PipelineValidationService: PipelineValidationService,
+                private RestApi: RestApi,
+                private JsplumbService: JsplumbService,
+                //private TransitionService: TransitionService,
+                private ShepherdService: ShepherdService) {
+
+        this.selectMode = true;
+        this.currentZoomLevel = 1;
+
+
+    }
+
     ngOnInit(): void {
+        if (this.currentModifiedPipelineId) {
+            //this.displayPipelineById();
+        } else {
+            //this.checkAndDisplayCachedPipeline();
+        }
+
+        // this.$rootScope.$on("pipeline.validate", () => {
+        //     this.pipelineValid = this.PipelineValidationService.isValidPipeline(this.rawPipelineModel);
+        // });
+    }
+
+    ngAfterViewInit() {
+        ($("#assembly") as any).panzoom({
+            disablePan: true,
+            increment: 0.25,
+            minScale: 0.5,
+            maxScale: 1.5,
+            contain: 'invert'
+        });
+
+        $("#assembly").on('panzoomzoom', (e, panzoom, scale) => {
+            this.currentZoomLevel = scale;
+            this.JsplumbBridge.setZoom(scale);
+            this.JsplumbBridge.repaintEverything();
+        });
+    }
+
+    autoLayout() {
+        this.PipelinePositioningService.layoutGraph("#assembly", "span[id^='jsplumb']", 110, false);
+        this.JsplumbBridge.repaintEverything();
+    }
+
+    toggleSelectMode() {
+        if (this.selectMode) {
+            ($("#assembly") as any).panzoom("option", "disablePan", false);
+            ($("#assembly") as any).selectable("disable");
+            this.selectMode = false;
+        }
+        else {
+            ($("#assembly") as any).panzoom("option", "disablePan", true);
+            ($("#assembly") as any).selectable("enable");
+            this.selectMode = true;
+        }
+    }
+
+    zoomOut() {
+        this.doZoom(true);
+    }
+
+    zoomIn() {
+        this.doZoom(false);
+    }
+
+    doZoom(zoomOut) {
+        ($("#assembly") as any).panzoom("zoom", zoomOut);
+    }
+
+    showClearAssemblyConfirmDialog(ev) {
+        this.EditorDialogManager.showClearAssemblyDialog(ev).then(() => {
+            if (this.currentModifiedPipelineId) {
+                this.currentModifiedPipelineId = undefined;
+            }
+            this.clearAssembly();
+            this.TransitionService.makePipelineAssemblyEmpty(true);
+
+        }, function () {
+        });
+    };
+
+    /**
+     * clears the Assembly of all elements
+     */
+    clearAssembly() {
+        //$('#assembly').children().not('#clear, #submit').remove();
+        this.JsplumbBridge.deleteEveryEndpoint();
+        this.rawPipelineModel = [];
+        ($("#assembly") as any).panzoom("reset", {
+            disablePan: true,
+            increment: 0.25,
+            minScale: 0.5,
+            maxScale: 1.5,
+            contain: 'invert'
+        });
+        this.currentZoomLevel = 1;
+        this.JsplumbBridge.setZoom(this.currentZoomLevel);
+        this.JsplumbBridge.repaintEverything();
+        this.RestApi.removePipelineFromCache().then(msg => {
+            this.pipelineCached = false;
+            this.pipelineCacheRunning = false;
+        });
+    };
+
+    /**
+     * Sends the pipeline to the server
+     */
+    submit() {
+        var pipeline = this.ObjectProvider.makeFinalPipeline(this.rawPipelineModel);
+
+        pipeline.name = this.currentPipelineName;
+        pipeline.description = this.currentPipelineDescription;
+        if (this.currentModifiedPipelineId) {
+            pipeline._id = this.currentModifiedPipelineId;
+        }
+
+        this.openPipelineNameModal(pipeline, (!!this.currentModifiedPipelineId));
+    }
+
+
+    openPipelineNameModal(pipeline, modificationMode) {
+        this.EditorDialogManager.showSavePipelineDialog(pipeline, modificationMode);
+    }
+
+    checkAndDisplayCachedPipeline() {
+        this.RestApi.getCachedPipeline().then(msg => {
+            if (msg.data !== "") {
+                this.rawPipelineModel = msg.data;
+                this.displayPipelineInEditor(true);
+            }
+        });
+    }
+
+    displayPipelineById() {
+        this.RestApi.getPipelineById(this.currentModifiedPipelineId)
+            .then((msg) => {
+                let pipeline = msg.data;
+                this.currentPipelineName = pipeline.name;
+                this.currentPipelineDescription = pipeline.description;
+                this.rawPipelineModel = this.JsplumbService.makeRawPipeline(pipeline, false);
+                this.displayPipelineInEditor(true);
+            });
+    };
+
+    displayPipelineInEditor(autoLayout) {
+        this.PipelinePositioningService.displayPipeline(this.rawPipelineModel, "#assembly", false, autoLayout);
+        this.TransitionService.makePipelineAssemblyEmpty(false);
+        this.pipelineValid = this.PipelineValidationService.isValidPipeline(this.rawPipelineModel);
+    }
+
+    toggleErrorMessagesDisplayed() {
+        this.errorMessagesDisplayed = !(this.errorMessagesDisplayed);
+    }
+
+    isPipelineAssemblyEmpty() {
+        return this.rawPipelineModel.length === 0 || this.rawPipelineModel.every(pe => pe.settings.disabled);
+    }
+
+    elementDropped($event) {
+        console.log($event);
     }
 
 }
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.html b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.html
index 67b171a..f797a9d 100644
--- a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.html
+++ b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.html
@@ -74,16 +74,16 @@
     </div>
 </div>
 <div flex id="editor-icon-stand" class="icon-stand" *ngIf="currentElements">
-    <span id="{{ element.name }}" (mouseenter)="updateMouseOver(element.name)"
+    <span mwlDraggable id="{{ element.name }}" (mouseenter)="updateMouseOver(element.name)"
           (mouseleave)="updateMouseOver('')"
           *ngFor="let element of currentElements"
-          my-data-bind class="draggable-icon tt"
-          [ngClass]="element.type">
+          class="draggable-icon tt" [dropData]="element"
+          [ngClass]="activeCssClass">
         <span id="container" style="position:relative;display:block;width:80px;height:80px;">
         <pipeline-element id="pe-icon-stand-{{ element.appId }}" style="margin-left:-3%" [iconStandSize]="true" [pipelineElement]="element"
                           [preview]="false"></pipeline-element>
             <span style="display:block;width:100%;height:100%;position:absolute; top:0; left:0;"
-                  ng-if="currentElementName==element.name">
+                  *ngIf="currentElementName===element.name">
                 <span class="help-button-icon-stand" style="z-index:10"><md-button
                         ng-click="openHelpDialog(element)"
                         class="md-icon-button"
diff --git a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.ts b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.ts
index cc6bc5c..784f89e 100644
--- a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.ts
+++ b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.ts
@@ -22,6 +22,12 @@ import {
 } from "@angular/core";
 import * as angular from "angular";
 import {RestApi} from "../../../services/rest-api.service";
+import {
+    DataProcessorInvocation, DataSinkInvocation,
+    SpDataSet,
+    SpDataStream
+} from "../../../core-model/gen/streampipes-model";
+import {EditorComponent} from "../../editor.component";
 
 
 @Component({
@@ -32,20 +38,23 @@ import {RestApi} from "../../../services/rest-api.service";
 export class PipelineElementIconStandComponent implements OnInit {
 
     @Input()
-    activeType: string;
-
-    @Input()
-    currentElements: Array<any>;
+    currentElements: (SpDataSet | SpDataStream | DataProcessorInvocation | DataSinkInvocation)[];
 
     elementFilter: string;
     availableOptions: any = [];
     selectedOptions: any = [];
 
+    _activeType: string;
+    activeCssClass: string;
+
+    currentElementName: string;
+
     constructor(private RestApi: RestApi) {
 
     }
 
     ngOnInit(): void {
+        console.log(this.activeType);
         this.loadOptions(this.activeType);
     }
 
@@ -53,8 +62,8 @@ export class PipelineElementIconStandComponent implements OnInit {
         //this.EditorDialogManager.openHelpDialog(pipelineElement);
     }
 
-    updateMouseOver(elementName) {
-        //this.currentElementName = elementName;
+    updateMouseOver(elementAppId: string) {
+        this.currentElementName = elementAppId;
     }
 
     loadOptions(type?) {
@@ -104,4 +113,22 @@ export class PipelineElementIconStandComponent implements OnInit {
         this.selectedOptions = [];
     }
 
+    @Input()
+    set activeType(value: string) {
+        this._activeType = value;
+        this.activeCssClass = this.makeActiveCssClass(value);
+    };
+
+    makeActiveCssClass(elementType: string) {
+        if (EditorComponent.DATA_STREAM_IDENTIFIER === elementType) {
+            return "stream";
+        } else if (EditorComponent.DATA_SET_IDENTIFIER === elementType) {
+            return "set";
+        } else if (EditorComponent.DATA_PROCESSOR_IDENTIFIER === elementType) {
+            return "sepa";
+        } else {
+            return "action";
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/editor.component.html b/ui/src/app/editor-v2/editor.component.html
index 152ea70..4fd7ad4 100644
--- a/ui/src/app/editor-v2/editor.component.html
+++ b/ui/src/app/editor-v2/editor.component.html
@@ -37,7 +37,7 @@
                                          element-filter="ctrl.elementFilter">
             </pipeline-element-icon-stand>
         </div>
-<!--        <pipeline-assembly raw-pipeline-model="ctrl.rawPipelineModel" all-elements="ctrl.allElements"-->
-<!--                           current-modified-pipeline-id="ctrl.currentModifiedPipelineId"></pipeline-assembly>-->
+        <pipeline-assembly [rawPipelineModel]="rawPipelineModel" [allElements]="allElements"
+                           [currentModifiedPipelineId]="currentModifiedPipelineId"></pipeline-assembly>
     </div>
 </div>
diff --git a/ui/src/app/editor-v2/editor.component.ts b/ui/src/app/editor-v2/editor.component.ts
index 68a54ea..4a8fb91 100644
--- a/ui/src/app/editor-v2/editor.component.ts
+++ b/ui/src/app/editor-v2/editor.component.ts
@@ -18,10 +18,14 @@
 
 import {Component, OnInit} from "@angular/core";
 import {EditorService} from "./services/editor.service";
-import {DataStreamDescription} from "../connect/model/DataStreamDescription";
-import {DataSinkInvocation} from "../connect/model/DataSinkInvocation";
-import {DataSourceDescription} from "../connect/model/DataSourceDescription";
-import {DataProcessorInvocation} from "../core-model/gen/streampipes-model";
+import {
+    DataProcessorInvocation,
+    DataSinkInvocation,
+    DataSourceDescription, SpDataSet,
+    SpDataStream
+} from "../core-model/gen/streampipes-model";
+import {PipelineElementService} from "../platform-services/apis/pipeline-element.service";
+import {PipelineElementHolder} from "./model/editor.model";
 
 @Component({
     selector: 'editor',
@@ -30,75 +34,98 @@ import {DataProcessorInvocation} from "../core-model/gen/streampipes-model";
 })
 export class EditorComponent implements OnInit {
 
+    static readonly DATA_STREAM_IDENTIFIER = "org.apache.streampipes.model.SpDataStream";
+    static readonly DATA_SET_IDENTIFIER = "org.apache.streampipes.model.SpDataSet";
+    static readonly DATA_PROCESSOR_IDENTIFIER = "org.apache.streampipes.model.graph.DataProcessorInvocation";
+    static readonly DATA_SINK_IDENTIFIER = "org.apache.streampipes.model.graph.DataSinkInvoation";
+
     selectedIndex: number = 1;
-    activeType: string = "stream";
+    activeType: string = EditorComponent.DATA_STREAM_IDENTIFIER;
 
-    availableDataStreams: DataStreamDescription[] = [];
+    availableDataStreams: SpDataStream[] = [];
     availableDataProcessors: DataProcessorInvocation[] = [];
     availableDataSinks: DataSinkInvocation[] = [];
 
-    allElements: any = [];
-    currentElements: any = [];
+    allElements: PipelineElementHolder[] = [];
+    currentElements: (SpDataStream | DataProcessorInvocation | DataSinkInvocation)[] = [];
+
+    rawPipelineModel: any = [];
+    currentModifiedPipelineId: any;
 
     tabs = [
         {
             title: 'Data Sets',
-            type: 'set',
+            type: EditorComponent.DATA_SET_IDENTIFIER
         },
         {
             title: 'Data Streams',
-            type: 'stream',
+            type: EditorComponent.DATA_STREAM_IDENTIFIER
         },
         {
             title: 'Data Processors',
-            type: 'processor',
+            type: EditorComponent.DATA_PROCESSOR_IDENTIFIER
         },
         {
             title: 'Data Sinks',
-            type: 'sink',
+            type: EditorComponent.DATA_SINK_IDENTIFIER
         }
     ];
 
-    constructor(private editorService: EditorService) {
+    constructor(private editorService: EditorService,
+                private pipelineElementService: PipelineElementService) {
     }
 
-    public ngOnInit() {
-        this.editorService.getDataProcessors().subscribe(processors => {
-            //processors.forEach(processor => processor.type = "processor");
+    ngOnInit() {
+        this.pipelineElementService.getDataProcessors().subscribe(processors => {
             this.availableDataProcessors = processors;
-            console.log(processors);
-            this.allElements["processor"] = this.availableDataProcessors;
+            this.allElements[EditorComponent.DATA_PROCESSOR_IDENTIFIER] = this.availableDataProcessors;
+        });
+        this.pipelineElementService.getDataSources().subscribe(sources => {
+            this.availableDataStreams = this.collectStreams(sources);
+            this.allElements[EditorComponent.DATA_STREAM_IDENTIFIER] = this.availableDataStreams
+                .filter(ds => ds["@class"] == EditorComponent.DATA_STREAM_IDENTIFIER );
+            this.allElements[EditorComponent.DATA_SET_IDENTIFIER] = this.availableDataStreams
+                .filter(ds => ds["@class"] == EditorComponent.DATA_SET_IDENTIFIER );
+            this.currentElements = this.allElements[EditorComponent.DATA_STREAM_IDENTIFIER];
         });
-        // this.editorService.getDataSources().subscribe(sources => {
-        //     this.availableDataStreams = this.collectStreams(sources);
-        //     this.allElements["stream"] = this.availableDataStreams;
-        // });
-        // this.editorService.getDataSinks().subscribe(sinks => {
-        //     sinks.forEach(processor => processor.type = "sink");
-        //     this.availableDataSinks = sinks;
-        //     this.allElements["sink"] = this.availableDataSinks;
-        // })
+        this.pipelineElementService.getDataSinks().subscribe(sinks => {
+            this.availableDataSinks = sinks;
+            this.allElements[EditorComponent.DATA_SINK_IDENTIFIER] = this.availableDataSinks;
+        })
+
     }
 
     private collectStreams(sources: Array<DataSourceDescription>) {
-        let streams: DataStreamDescription[] = [];
+        let streams: SpDataStream[] = [];
         sources.forEach(source => {
-            if (!Array.isArray(source.spDataStreams)) {
-                source.spDataStreams = [source.spDataStreams];
-            }
             source.spDataStreams.forEach(stream => {
-                stream.type = "stream";
                 streams.push(stream);
             });
         });
         return streams;
     }
 
-
     selectPipelineElements(index : number) {
         this.selectedIndex = index;
         this.activeType = this.tabs[index].type;
         this.currentElements = this.allElements[this.activeType];
+        this.makeDraggable();
     }
 
+    makeDraggable() {
+        console.log("makuing drabbg");
+        (<any>$('.draggable-icon')).draggable({
+            revert: 'invalid',
+            helper: 'clone',
+            stack: '.draggable-icon',
+            start: function (el, ui) {
+                ui.helper.appendTo('#content');
+                $('#outerAssemblyArea').css('border', '3px dashed #39b54a');
+            },
+            stop: function (el, ui) {
+                $('#outerAssemblyArea').css('border', '3px solid rgb(156, 156, 156)');
+            }
+        });
+    };
+
 }
diff --git a/ui/src/app/editor-v2/editor.module.ts b/ui/src/app/editor-v2/editor.module.ts
index dd4e8d8..54b1bae 100644
--- a/ui/src/app/editor-v2/editor.module.ts
+++ b/ui/src/app/editor-v2/editor.module.ts
@@ -33,6 +33,13 @@ import {PipelineElementIconStandComponent} from "./components/pipeline-element-i
 import {PipelineAssemblyComponent} from "./components/pipeline-assembly/pipeline-assembly.component";
 import {ImageChecker} from "../services/image-checker.service";
 import {PipelineElementComponent} from "./components/pipeline-element/pipeline-element.component";
+import {JsplumbBridge} from "./services/jsplumb-bridge.service";
+import {PipelinePositioningService} from "./services/pipeline-positioning.service";
+import {JsplumbService} from "./services/jsplumb.service";
+import {JsplumbConfigService} from "./services/jsplumb-config.service";
+import {PipelineEditorService} from "./services/pipeline-editor.service";
+import {PipelineValidationService} from "./services/pipeline-validation.service";
+import {DragAndDropModule} from "angular-draggable-droppable";
 
 
 @NgModule({
@@ -45,7 +52,8 @@ import {PipelineElementComponent} from "./components/pipeline-element/pipeline-e
         FlexLayoutModule,
         CustomMaterialModule,
         FormsModule,
-        ConnectModule
+        ConnectModule,
+        DragAndDropModule
     ],
     declarations: [
         EditorComponent,
@@ -61,12 +69,23 @@ import {PipelineElementComponent} from "./components/pipeline-element/pipeline-e
             useFactory: ($injector: any) => $injector.get('RestApi'),
             deps: ['$injector'],
         },
+        JsplumbBridge,
+        JsplumbService,
+        JsplumbConfigService,
+        PipelineEditorService,
+        PipelinePositioningService,
+        PipelineValidationService,
         ElementIconText,
         ImageChecker,
         {
             provide: '$state',
             useFactory: ($injector: any) => $injector.get('$state'),
             deps: ['$injector']
+        },
+        {
+            provide: '$timeout',
+            useFactory: ($injector: any) => $injector.get('$timeout'),
+            deps: ['$injector']
         }
     ],
     exports: [
diff --git a/ui/src/app/editor-v2/model/editor.model.ts b/ui/src/app/editor-v2/model/editor.model.ts
new file mode 100644
index 0000000..4662d0c
--- /dev/null
+++ b/ui/src/app/editor-v2/model/editor.model.ts
@@ -0,0 +1,9 @@
+import {
+  DataProcessorInvocation,
+  DataSinkInvocation,
+  SpDataStream
+} from "../../core-model/gen/streampipes-model";
+
+export interface PipelineElementHolder {
+  [key: string]: (SpDataStream | DataProcessorInvocation | DataSinkInvocation);
+}
\ No newline at end of file
diff --git a/ui/src/app/editor/services/editor-dialog-manager.service.ts b/ui/src/app/editor-v2/services/editor-dialog-manager.service.ts
similarity index 75%
rename from ui/src/app/editor/services/editor-dialog-manager.service.ts
rename to ui/src/app/editor-v2/services/editor-dialog-manager.service.ts
index 90e76ac..0da1af1 100644
--- a/ui/src/app/editor/services/editor-dialog-manager.service.ts
+++ b/ui/src/app/editor-v2/services/editor-dialog-manager.service.ts
@@ -17,14 +17,14 @@
  */
 
 import * as angular from 'angular';
-import {CustomizeController} from "../dialog/customize-pipeline-element/customize.controller";
-import {MatchingErrorController} from "../dialog/matching-error/matching-error.controller";
-import {TopicSelectionDialog} from "../dialog/topic/topic-selection-modal.controller";
-import {PossibleElementsController} from "../dialog/possible-elements/possible-elements-dialog.controller";
-import {HelpDialogController} from "../dialog/help/help-dialog.controller";
-import {SavePipelineController} from "../dialog/save-pipeline/save-pipeline.controller";
-import {WelcomeTourDialogController} from "../dialog/welcome-tour/welcome-tour-dialog.controller";
-import {MissingElementsForTutorialDialogController} from "../dialog/missing-elements-for-tutorial/missing-elements-for-tutorial-dialog.controller";
+import {CustomizeController} from "../../editor/dialog/customize-pipeline-element/customize.controller";
+import {MatchingErrorController} from "../../editor/dialog/matching-error/matching-error.controller";
+import {TopicSelectionDialog} from "../../editor/dialog/topic/topic-selection-modal.controller";
+import {PossibleElementsController} from "../../editor/dialog/possible-elements/possible-elements-dialog.controller";
+import {HelpDialogController} from "../../editor/dialog/help/help-dialog.controller";
+import {SavePipelineController} from "../../editor/dialog/save-pipeline/save-pipeline.controller";
+import {WelcomeTourDialogController} from "../../editor/dialog/welcome-tour/welcome-tour-dialog.controller";
+import {MissingElementsForTutorialDialogController} from "../../editor/dialog/missing-elements-for-tutorial/missing-elements-for-tutorial-dialog.controller";
 
 declare const require: any;
 
@@ -40,7 +40,7 @@ export class EditorDialogManager {
     }
 
     showMatchingErrorDialog(elementData) {
-        var dialogContent = this.DialogBuilder.getDialogTemplate(MatchingErrorController, require('../dialog/matching-error/matching-error.tmpl.html'));
+        var dialogContent = this.DialogBuilder.getDialogTemplate(MatchingErrorController, require('../../editor/dialog/matching-error/matching-error.tmpl.html'));
         dialogContent.locals = {
             elementData: elementData
         }
@@ -48,7 +48,7 @@ export class EditorDialogManager {
     }
 
     showCustomizeDialog(elementData, sourceEndpoint, sepa, restrictedEditMode) {
-        var dialogContent = this.DialogBuilder.getDialogTemplate(CustomizeController, require('../dialog/customize-pipeline-element/customizeElementDialog.tmpl.html'));
+        var dialogContent = this.DialogBuilder.getDialogTemplate(CustomizeController, require('../../editor/dialog/customize-pipeline-element/customizeElementDialog.tmpl.html'));
         dialogContent.locals = {
             elementData: elementData,
             sourceEndpoint: sourceEndpoint,
@@ -59,7 +59,7 @@ export class EditorDialogManager {
     };
 
     showCustomizeStreamDialog(streamDescription) {
-        var dialogContent = this.DialogBuilder.getDialogTemplate(TopicSelectionDialog, require('../dialog/topic/topic-selection-modal.tmpl.html'));
+        var dialogContent = this.DialogBuilder.getDialogTemplate(TopicSelectionDialog, require('../../editor/dialog/topic/topic-selection-modal.tmpl.html'));
         dialogContent.locals = {
             streamDescription: streamDescription
         }
@@ -67,7 +67,7 @@ export class EditorDialogManager {
     }
 
     showSavePipelineDialog(pipelineNew, modificationModeOn) {
-        var dialogContent = this.DialogBuilder.getDialogTemplate(SavePipelineController, require('../dialog/save-pipeline/submitPipelineModal.tmpl.html'));
+        var dialogContent = this.DialogBuilder.getDialogTemplate(SavePipelineController, require('../../editor/dialog/save-pipeline/submitPipelineModal.tmpl.html'));
         dialogContent.locals = {
             pipeline: pipelineNew,
             modificationMode: modificationModeOn
@@ -79,7 +79,7 @@ export class EditorDialogManager {
         this.$mdDialog.show({
             controller: HelpDialogController,
             controllerAs: 'ctrl',
-            template: require('../dialog/help/help-dialog.tmpl.html'),
+            template: require('../../editor/dialog/help/help-dialog.tmpl.html'),
             parent: angular.element(document.body),
             // must be false, otherwise polling of live data is not stopped in help-dialog.controller.js when dialog is closed
             clickOutsideToClose: false,
@@ -94,7 +94,7 @@ export class EditorDialogManager {
         this.$mdDialog.show({
             controller: PossibleElementsController,
             controllerAs: 'ctrl',
-            template: require('../dialog/possible-elements/possible-elements-dialog.tmpl.html'),
+            template: require('../../editor/dialog/possible-elements/possible-elements-dialog.tmpl.html'),
             parent: angular.element(document.body),
             clickOutsideToClose: true,
             bindToController: true,
@@ -119,7 +119,7 @@ export class EditorDialogManager {
         this.$mdDialog.show({
             controller: WelcomeTourDialogController,
             controllerAs: 'ctrl',
-            template: require('../dialog/welcome-tour/welcome-tour-dialog.tmpl.html'),
+            template: require('../../editor/dialog/welcome-tour/welcome-tour-dialog.tmpl.html'),
             parent: angular.element(document.body),
             clickOutsideToClose: false,
             bindToController: true,
@@ -133,7 +133,7 @@ export class EditorDialogManager {
         this.$mdDialog.show({
             controller: MissingElementsForTutorialDialogController,
             controllerAs: 'ctrl',
-            template: require('../dialog/missing-elements-for-tutorial/missing-elements-for-tutorial-dialog.tmpl.html'),
+            template: require('../../editor/dialog/missing-elements-for-tutorial/missing-elements-for-tutorial-dialog.tmpl.html'),
             parent: angular.element(document.body),
             clickOutsideToClose: false,
             bindToController: true,
diff --git a/ui/src/app/editor-v2/services/editor.service.ts b/ui/src/app/editor-v2/services/editor.service.ts
index 5e29981..42f8cc2 100644
--- a/ui/src/app/editor-v2/services/editor.service.ts
+++ b/ui/src/app/editor-v2/services/editor.service.ts
@@ -17,12 +17,9 @@
  */
 
 import {Injectable} from "@angular/core";
-import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {HttpClient} from "@angular/common/http";
 import {AuthStatusService} from "../../services/auth-status.service";
 import {TsonLdSerializerService} from "../../platform-services/tsonld-serializer.service";
-import {Observable} from "rxjs";
-import {DataProcessorInvocation, DataSinkInvocation} from "../../core-model/gen/streampipes-model";
-import {DataSourceDescription} from "../../connect/model/DataSourceDescription";
 
 @Injectable()
 export class EditorService {
@@ -32,50 +29,6 @@ export class EditorService {
                 private tsonLdSerializerService: TsonLdSerializerService) {
     }
 
-    getDataProcessors(): Observable<Array<DataProcessorInvocation>> {
-        return this.http.get(this.dataProcessorsUrl + "/own").map(data => {
-            return (data as []).map(dpi => DataProcessorInvocation.fromData(dpi));
-        })
-    }
-
-    getDataSinks(): Observable<Array<DataSinkInvocation>> {
-        return this.http.get(this.dataSinksUrl + "/own", this.jsonLdHeaders()).map(data => {
-            return this.tsonLdSerializerService.fromJsonLdContainer(data, "sp:DataSinkInvocation");
-        })
-    }
-
-    getDataSources(): Observable<Array<DataSourceDescription>> {
-        return this.http.get(this.dataSourcesUrl + "/own", this.jsonLdHeaders()).map(data => {
-            return this.tsonLdSerializerService.fromJsonLdContainer(data, "sp:DataSourceDescription");
-        })
-    }
-
-    private get baseUrl(): string {
-        return '/streampipes-backend';
-    }
-
-    private get dataProcessorsUrl(): string {
-        return this.baseUrl + '/api/v2/users/' + this.authStatusService.email + '/sepas'
-    }
-
-    private get dataSourcesUrl(): string {
-        return this.baseUrl + '/api/v2/users/' + this.authStatusService.email + '/sources'
-    }
-
-    private get dataSinksUrl(): string {
-        return this.baseUrl + '/api/v2/users/' + this.authStatusService.email + '/actions'
-    }
-
-    private get ownPath() {
-        return "/own";
-    }
 
-    jsonLdHeaders(): any {
-        return {
-            headers: new HttpHeaders({
-                'Accept': 'application/ld+json',
-            }),
-        };
-    }
 
 }
\ No newline at end of file
diff --git a/ui/src/app/services/jsplumb-bridge.service.ts b/ui/src/app/editor-v2/services/jsplumb-bridge.service.ts
similarity index 98%
rename from ui/src/app/services/jsplumb-bridge.service.ts
rename to ui/src/app/editor-v2/services/jsplumb-bridge.service.ts
index fbe3188..82631d1 100644
--- a/ui/src/app/services/jsplumb-bridge.service.ts
+++ b/ui/src/app/editor-v2/services/jsplumb-bridge.service.ts
@@ -16,8 +16,11 @@
  *
  */
 
+import {Injectable} from "@angular/core";
+
 declare const jsPlumb: any;
 
+@Injectable()
 export class JsplumbBridge {
 
     constructor() {
diff --git a/ui/src/app/services/jsplumb-config.service.ts b/ui/src/app/editor-v2/services/jsplumb-config.service.ts
similarity index 97%
rename from ui/src/app/services/jsplumb-config.service.ts
rename to ui/src/app/editor-v2/services/jsplumb-config.service.ts
index f459873..c18d55b 100644
--- a/ui/src/app/services/jsplumb-config.service.ts
+++ b/ui/src/app/editor-v2/services/jsplumb-config.service.ts
@@ -16,6 +16,9 @@
  *
  */
 
+import {Injectable} from "@angular/core";
+
+@Injectable()
 export class JsplumbConfigService {
 
     constructor() {
diff --git a/ui/src/app/services/jsplumb.service.ts b/ui/src/app/editor-v2/services/jsplumb.service.ts
similarity index 94%
rename from ui/src/app/services/jsplumb.service.ts
rename to ui/src/app/editor-v2/services/jsplumb.service.ts
index f66f9af..45a7277 100644
--- a/ui/src/app/services/jsplumb.service.ts
+++ b/ui/src/app/editor-v2/services/jsplumb.service.ts
@@ -16,27 +16,20 @@
  *
  */
 
-import {ObjectProvider} from "./object-provider.service";
 import {JsplumbConfigService} from "./jsplumb-config.service";
 import {JsplumbBridge} from "./jsplumb-bridge.service";
+import {Inject, Injectable} from "@angular/core";
 
+@Injectable()
 export class JsplumbService {
 
-    objectProvider: ObjectProvider;
     apiConstants: any;
-    JsplumbConfigService: JsplumbConfigService;
-    JsplumbBridge: JsplumbBridge;
-    $timeout: any;
     idCounter: any;
+    $timeout: any;
     RestApi: any;
 
-    constructor(ObjectProvider, JsplumbConfigService, JsplumbBridge, $timeout, RestApi) {
-        this.objectProvider = ObjectProvider;
-        this.JsplumbConfigService = JsplumbConfigService;
-        this.JsplumbBridge = JsplumbBridge;
-        this.$timeout = $timeout;
-        this.RestApi = RestApi;
-
+    constructor(private JsplumbConfigService: JsplumbConfigService,
+                private JsplumbBridge: JsplumbBridge) {
         this.idCounter = 0;
     }
 
@@ -255,4 +248,4 @@ export class JsplumbService {
     }
 }
 
-JsplumbService.$inject = ['ObjectProvider', 'JsplumbConfigService', 'JsplumbBridge', '$timeout', 'RestApi'];
+//JsplumbService.$inject = ['JsplumbConfigService', 'JsplumbBridge', '$timeout', 'RestApi'];
diff --git a/ui/src/app/services/pipeline-editor.service.ts b/ui/src/app/editor-v2/services/pipeline-editor.service.ts
similarity index 95%
rename from ui/src/app/services/pipeline-editor.service.ts
rename to ui/src/app/editor-v2/services/pipeline-editor.service.ts
index 3a2ed21..6d142a3 100644
--- a/ui/src/app/services/pipeline-editor.service.ts
+++ b/ui/src/app/editor-v2/services/pipeline-editor.service.ts
@@ -16,6 +16,9 @@
  *
  */
 
+import {Injectable} from "@angular/core";
+
+@Injectable()
 export class PipelineEditorService {
 
     JsplumbBridge: any;
@@ -64,4 +67,4 @@ export class PipelineEditorService {
 
 }
 
-PipelineEditorService.$inject = ['JsplumbBridge'];
\ No newline at end of file
+//PipelineEditorService.$inject = ['JsplumbBridge'];
\ No newline at end of file
diff --git a/ui/src/app/services/pipeline-positioning.service.ts b/ui/src/app/editor-v2/services/pipeline-positioning.service.ts
similarity index 92%
rename from ui/src/app/services/pipeline-positioning.service.ts
rename to ui/src/app/editor-v2/services/pipeline-positioning.service.ts
index 290b400..6f7b845 100644
--- a/ui/src/app/services/pipeline-positioning.service.ts
+++ b/ui/src/app/editor-v2/services/pipeline-positioning.service.ts
@@ -21,22 +21,19 @@ import * as dagre from "dagre";
 import {JsplumbBridge} from "./jsplumb-bridge.service";
 import {JsplumbConfigService} from "./jsplumb-config.service";
 import {JsplumbService} from "./jsplumb.service";
+import {Inject, Injectable} from "@angular/core";
 
 declare const jsPlumb: any;
 
+@Injectable()
 export class PipelinePositioningService {
 
-    JsplumbService: JsplumbService;
-    JsplumbConfigService: JsplumbConfigService;
-    JsplumbBridge: JsplumbBridge;
 
-    constructor(JsplumbService, JsplumbConfigService, JsplumbBridge) {
-        this.JsplumbService = JsplumbService;
-        this.JsplumbConfigService = JsplumbConfigService;
-        this.JsplumbBridge = JsplumbBridge;
+    constructor(private JsplumbService: JsplumbService,
+                private JsplumbConfigService: JsplumbConfigService,
+                private JsplumbBridge: JsplumbBridge) {
     }
 
-
     displayPipeline(rawPipelineModel, targetCanvas, isPreview, autoLayout) {
         var jsplumbConfig = isPreview ? this.JsplumbConfigService.getPreviewConfig() : this.JsplumbConfigService.getEditorConfig();
 
@@ -134,4 +131,4 @@ export class PipelinePositioningService {
 
 }
 
-PipelinePositioningService.$inject = ['JsplumbService', 'JsplumbConfigService', 'JsplumbBridge'];
\ No newline at end of file
+//PipelinePositioningService.$inject = ['JsplumbService', 'JsplumbConfigService', 'JsplumbBridge'];
\ No newline at end of file
diff --git a/ui/src/app/editor/services/pipeline-validation.service.ts b/ui/src/app/editor-v2/services/pipeline-validation.service.ts
similarity index 94%
rename from ui/src/app/editor/services/pipeline-validation.service.ts
rename to ui/src/app/editor-v2/services/pipeline-validation.service.ts
index 22be1e9..a97200e 100644
--- a/ui/src/app/editor/services/pipeline-validation.service.ts
+++ b/ui/src/app/editor-v2/services/pipeline-validation.service.ts
@@ -18,13 +18,13 @@
 
 import * as angular from 'angular';
 import * as dagre from 'dagre';
-import {JsplumbBridge} from "../../services/jsplumb-bridge.service";
+import {JsplumbBridge} from "./jsplumb-bridge.service";
+import {Injectable} from "@angular/core";
 
+@Injectable()
 export class PipelineValidationService {
 
-    ObjectProvider: any;
     errorMessages: any = [];
-    JsplumbBridge: JsplumbBridge;
 
     availableErrorMessages: any = [
         {title: "Did you add a data stream?", content: "Any pipeline needs at least one data stream."},
@@ -33,9 +33,7 @@ export class PipelineValidationService {
         {title: "Separate pipelines", content: "It seems you've created more than one pipeline at once. Create only one pipeline at a time!"}
     ];
 
-    constructor(ObjectProvider, JsplumbBridge) {
-        this.ObjectProvider = ObjectProvider;
-        this.JsplumbBridge = JsplumbBridge;
+    constructor(private JsplumbBridge: JsplumbBridge) {
     }
 
     isValidPipeline(rawPipelineModel) {
@@ -161,4 +159,4 @@ export class PipelineValidationService {
     }
 }
 
-PipelineValidationService.$inject=['ObjectProvider', 'JsplumbBridge'];
\ No newline at end of file
+//PipelineValidationService.$inject=['ObjectProvider', 'JsplumbBridge'];
\ No newline at end of file
diff --git a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.controller.ts b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.controller.ts
index bbb65e3..6153625 100644
--- a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.controller.ts
+++ b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.controller.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import {PipelineValidationService} from "../../services/pipeline-validation.service";
+import {PipelineValidationService} from "../../../editor-v2/services/pipeline-validation.service";
 import {RestApi} from "../../../services/rest-api.service";
 
 export class PipelineAssemblyController {
diff --git a/ui/src/app/editor/components/pipeline-element-icon-stand/pipeline-element-icon-stand.controller.ts b/ui/src/app/editor/components/pipeline-element-icon-stand/pipeline-element-icon-stand.controller.ts
index 1b6a709..3f7da65 100644
--- a/ui/src/app/editor/components/pipeline-element-icon-stand/pipeline-element-icon-stand.controller.ts
+++ b/ui/src/app/editor/components/pipeline-element-icon-stand/pipeline-element-icon-stand.controller.ts
@@ -19,7 +19,7 @@
 import * as angular from 'angular';
 
 import {RestApi} from "../../../services/rest-api.service";
-import {EditorDialogManager} from "../../services/editor-dialog-manager.service";
+import {EditorDialogManager} from "../../../editor-v2/services/editor-dialog-manager.service";
 
 export class PipelineElementIconStandController {
 
diff --git a/ui/src/app/editor/components/pipeline-element-options/pipeline-element-options.controller.ts b/ui/src/app/editor/components/pipeline-element-options/pipeline-element-options.controller.ts
index d2bad22..d6a0f2e 100644
--- a/ui/src/app/editor/components/pipeline-element-options/pipeline-element-options.controller.ts
+++ b/ui/src/app/editor/components/pipeline-element-options/pipeline-element-options.controller.ts
@@ -17,9 +17,9 @@
  */
 
 import * as angular from 'angular';
-import {JsplumbBridge} from "../../../services/jsplumb-bridge.service";
-import {JsplumbService} from "../../../services/jsplumb.service";
-import {PipelineValidationService} from "../../services/pipeline-validation.service";
+import {JsplumbBridge} from "../../../editor-v2/services/jsplumb-bridge.service";
+import {JsplumbService} from "../../../editor-v2/services/jsplumb.service";
+import {PipelineValidationService} from "../../../editor-v2/services/pipeline-validation.service";
 import {TransitionService} from "../../../services/transition.service";
 import {RestApi} from "../../../services/rest-api.service";
 
diff --git a/ui/src/app/editor/components/pipeline/pipeline.controller.ts b/ui/src/app/editor/components/pipeline/pipeline.controller.ts
index 12608b0..ddaa853 100644
--- a/ui/src/app/editor/components/pipeline/pipeline.controller.ts
+++ b/ui/src/app/editor/components/pipeline/pipeline.controller.ts
@@ -18,7 +18,7 @@
 
 import * as angular from "angular";
 
-import {PipelineValidationService} from "../../services/pipeline-validation.service";
+import {PipelineValidationService} from "../../../editor-v2/services/pipeline-validation.service";
 import {RestApi} from "../../../services/rest-api.service";
 
 export class PipelineController {
diff --git a/ui/src/app/editor/editor.controller.ts b/ui/src/app/editor/editor.controller.ts
index 22b3713..b308d3f 100644
--- a/ui/src/app/editor/editor.controller.ts
+++ b/ui/src/app/editor/editor.controller.ts
@@ -20,8 +20,8 @@ import * as angular from 'angular';
 import {AuthStatusService} from "../services/auth-status.service";
 import {RestApi} from "../services/rest-api.service";
 import {ShepherdService} from "../services/tour/shepherd.service";
-import {JsplumbBridge} from "../services/jsplumb-bridge.service";
-import {EditorDialogManager} from "./services/editor-dialog-manager.service";
+import {JsplumbBridge} from "../editor-v2/services/jsplumb-bridge.service";
+import {EditorDialogManager} from "../editor-v2/services/editor-dialog-manager.service";
 
 export class EditorCtrl {
 
diff --git a/ui/src/app/editor/editor.module.ts b/ui/src/app/editor/editor.module.ts
index db4c26e..2a9b2c7 100644
--- a/ui/src/app/editor/editor.module.ts
+++ b/ui/src/app/editor/editor.module.ts
@@ -50,13 +50,13 @@ import {CollectionComponent} from './components/collection/collection.component'
 import {CustomizeDialogComponent} from './components/customize/customize-dialog.component';
 import {TopicSelectionDialogComponent} from './components/topic/topic-selection-dialog.component';
 import {PipelineComponent} from './components/pipeline/pipeline.component';
-import {EditorDialogManager} from './services/editor-dialog-manager.service';
+import {EditorDialogManager} from '../editor-v2/services/editor-dialog-manager.service';
 import {PipelineElementComponent} from './components/pipeline-element/pipeline-element.component';
 import {PipelineElementRecommendationComponent} from "./components/pipeline-element-recommendation/pipeline-element-recommendation.component";
 import {PipelineElementRecommendationService} from "./services/pipeline-element-recommendation.service";
 import {PipelineAssemblyComponent} from "./components/pipeline-assembly/pipeline-assembly.component";
 import {PipelineElementIconStandComponent} from './components/pipeline-element-icon-stand/pipeline-element-icon-stand.component';
-import {PipelineValidationService} from "./services/pipeline-validation.service";
+import {PipelineValidationService} from "../editor-v2/services/pipeline-validation.service";
 import {OneOfRemoteComponent} from "./components/oneof-remote/oneof-remote.component";
 
 import {TextValidatorDirective} from "./validator/text/text-validator.directive";
diff --git a/ui/src/app/platform-services/apis/pipeline-element.service.ts b/ui/src/app/platform-services/apis/pipeline-element.service.ts
new file mode 100644
index 0000000..31c1b79
--- /dev/null
+++ b/ui/src/app/platform-services/apis/pipeline-element.service.ts
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+
+import {Injectable} from "@angular/core";
+import {HttpClient} from "@angular/common/http";
+import {AuthStatusService} from "../../services/auth-status.service";
+import {Observable} from "rxjs";
+import {
+  DataProcessorInvocation,
+  DataSinkInvocation,
+  DataSourceDescription
+} from "../../core-model/gen/streampipes-model";
+
+@Injectable()
+export class PipelineElementService {
+
+  constructor(private http: HttpClient,
+              private authStatusService: AuthStatusService) {
+  }
+
+  getDataProcessors(): Observable<Array<DataProcessorInvocation>> {
+    return this.http.get(this.dataProcessorsUrl + "/own").map(data => {
+      return (data as []).map(dpi => DataProcessorInvocation.fromData(dpi));
+    })
+  }
+
+  getDataSinks(): Observable<Array<DataSinkInvocation>> {
+    return this.http.get(this.dataSinksUrl + "/own").map(data => {
+      return (data as []).map(dpi => DataSinkInvocation.fromData(dpi));
+    })
+  }
+
+  getDataSources(): Observable<Array<DataSourceDescription>> {
+    return this.http.get(this.dataSourcesUrl + "/own").map(data => {
+      return (data as []).map(dpi => DataSourceDescription.fromData(dpi));
+    })
+  }
+
+  private get baseUrl(): string {
+    return '/streampipes-backend';
+  }
+
+  private get dataProcessorsUrl(): string {
+    return this.baseUrl + '/api/v2/users/' + this.authStatusService.email + '/sepas'
+  }
+
+  private get dataSourcesUrl(): string {
+    return this.baseUrl + '/api/v2/users/' + this.authStatusService.email + '/sources'
+  }
+
+  private get dataSinksUrl(): string {
+    return this.baseUrl + '/api/v2/users/' + this.authStatusService.email + '/actions'
+  }
+}
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.ts b/ui/src/app/platform-services/contants/pipeline-element-constants.ts
similarity index 72%
copy from ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.ts
copy to ui/src/app/platform-services/contants/pipeline-element-constants.ts
index 3a31d2c..58ba04b 100644
--- a/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.ts
+++ b/ui/src/app/platform-services/contants/pipeline-element-constants.ts
@@ -16,20 +16,3 @@
  *
  */
 
-import {
-    Component,
-    OnInit,
-} from "@angular/core";
-
-
-@Component({
-    selector: 'pipeline-assembly',
-    templateUrl: './pipeline-assembly.component.html',
-    styleUrls: ['./pipeline-assembly.component.css']
-})
-export class PipelineAssemblyComponent implements OnInit {
-
-    ngOnInit(): void {
-    }
-
-}
\ No newline at end of file
diff --git a/ui/src/app/platform-services/platform.module.ts b/ui/src/app/platform-services/platform.module.ts
index e566bc6..b4f2ca9 100644
--- a/ui/src/app/platform-services/platform.module.ts
+++ b/ui/src/app/platform-services/platform.module.ts
@@ -19,18 +19,17 @@
 import {NgModule} from '@angular/core';
 import {TsonLdSerializerService} from './tsonld-serializer.service';
 import {PipelineTemplateService} from './apis/pipeline-template.service';
+import {PipelineElementService} from "./apis/pipeline-element.service";
 
 @NgModule({
-    imports: [
-    ],
-    declarations: [
-    ],
-    providers: [
-        TsonLdSerializerService,
-        PipelineTemplateService
-    ],
-    entryComponents: [
-    ]
+  imports: [],
+  declarations: [],
+  providers: [
+    TsonLdSerializerService,
+    PipelineTemplateService,
+    PipelineElementService
+  ],
+  entryComponents: []
 })
 export class PlatformServicesModule {
 }
\ No newline at end of file
diff --git a/ui/src/app/services/services.module.ts b/ui/src/app/services/services.module.ts
index bc65f4d..98652a2 100644
--- a/ui/src/app/services/services.module.ts
+++ b/ui/src/app/services/services.module.ts
@@ -28,14 +28,14 @@ import {InitTooltips} from './init-tooltips.service'
 import {RestApi} from './rest-api.service'
 import {AuthStatusService} from './auth-status.service'
 import {DomainProperties} from './domain-properties.service'
-import {JsplumbBridge} from './jsplumb-bridge.service'
-import {JsplumbService} from './jsplumb.service'
-import {PipelinePositioningService} from './pipeline-positioning.service'
-import {PipelineEditorService} from './pipeline-editor.service'
+import {JsplumbBridge} from '../editor-v2/services/jsplumb-bridge.service'
+import {JsplumbService} from '../editor-v2/services/jsplumb.service'
+import {PipelinePositioningService} from '../editor-v2/services/pipeline-positioning.service'
+import {PipelineEditorService} from '../editor-v2/services/pipeline-editor.service'
 import {DialogBuilder} from './dialog-builder.service'
 import {MeasurementUnits} from './measurement-units.service'
 import {DeploymentService} from './deployment.service'
-import {JsplumbConfigService} from './jsplumb-config.service'
+import {JsplumbConfigService} from '../editor-v2/services/jsplumb-config.service'
 import {PipelineElementIconService} from './pipeline-icon.service'
 import {ObjectProvider} from './object-provider.service'
 import {downgradeInjectable} from '@angular/upgrade/static';
@@ -62,10 +62,10 @@ export default angular.module('sp.services', [spConstants])
 	.service('AuthStatusService', downgradeInjectable(AuthStatusService))
 	.service('ObjectProvider', ObjectProvider)
 	.service('DomainProperties', DomainProperties)
-	.service('JsplumbBridge', JsplumbBridge)
-	.service('JsplumbService', JsplumbService)
-	.service('PipelinePositioningService', PipelinePositioningService)
-	.service('PipelineEditorService', PipelineEditorService)
+	//.service('JsplumbBridge', downgradeInjectable(JsplumbBridge))
+	//.service('JsplumbService', downgradeInjectable(JsplumbService))
+	//.service('PipelinePositioningService', downgradeInjectable(PipelinePositioningService))
+	//.service('PipelineEditorService', PipelineEditorService)
 	.service('DialogBuilder', DialogBuilder)
     .service('MeasurementUnitsService', MeasurementUnits)
     .service('DeploymentService', DeploymentService)
diff --git a/ui/src/app/services/transition.service.ts b/ui/src/app/services/transition.service.ts
index 3415db6..f4bbe6e 100644
--- a/ui/src/app/services/transition.service.ts
+++ b/ui/src/app/services/transition.service.ts
@@ -16,6 +16,9 @@
  *
  */
 
+import {Inject, Injectable} from "@angular/core";
+
+@Injectable()
 export class TransitionService {
 
     AuthService: any;
diff --git a/ui/src/scss/sp/main.scss b/ui/src/scss/sp/main.scss
index 538bed9..4e73178 100644
--- a/ui/src/scss/sp/main.scss
+++ b/ui/src/scss/sp/main.scss
@@ -789,6 +789,7 @@ md-select.md-default-theme .md-select-value.md-select-placeholder, md-select .md
   margin-top: 5px;
   box-shadow: 1px 1px 2px #555;
   text-align: center;
+  z-index:200;
 }
 
 .block {