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/08/20 13:10:29 UTC

[incubator-streampipes] 02/03: [STREAMPIPES-145] Fix runtime-resolvable static property renderer

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

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

commit 0e0c1b6929e1d9ce5c8a6efc16b8c24dee675b6e
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Thu Aug 20 15:10:00 2020 +0200

    [STREAMPIPES-145] Fix runtime-resolvable static property renderer
---
 .../master/rest/AdapterTemplateResource.java       | 17 +---
 .../model/runtime/RuntimeOptionsRequest.java       | 10 +++
 .../model/runtime/RuntimeOptionsResponse.java      |  2 +
 .../streampipes/manager/operations/Operations.java | 10 +--
 .../remote/ContainerProvidedOptionsHandler.java    | 45 +++-------
 .../rest/impl/ContainerProvidedOptions.java        |  8 +-
 ui/src/app/connect/connect.component.ts            |  5 +-
 ui/src/app/connect/connect.module.ts               |  2 +
 .../data-marketplace/data-marketplace.component.ts |  2 +-
 .../connect/new-adapter/new-adapter.component.html | 10 +--
 ui/src/app/connect/rest.service.ts                 | 12 ---
 .../base/abstract-static-property.ts               |  6 +-
 .../base/abstract-validated-static-property.ts     |  2 +-
 .../filter/display-recommended.pipe.ts             |  1 -
 .../static-alternatives.component.ts               |  5 +-
 .../static-any-input.component.html                | 11 +--
 .../static-any-input/static-any-input.component.ts |  6 ++
 .../static-code-input.component.ts                 |  8 +-
 .../static-collection.component.ts                 |  9 +-
 .../static-color-picker.component.ts               |  5 +-
 .../static-free-input.component.ts                 |  8 +-
 .../static-mapping/static-mapping.ts               | 11 ++-
 .../static-property.component.html                 | 12 ++-
 .../static-properties/static-property.component.ts |  7 +-
 ...tic-runtime-resolvable-any-input.component.html | 24 ++++--
 ...tatic-runtime-resolvable-any-input.component.ts | 27 +++---
 .../base-runtime-resolvable-input.ts               | 98 ++++++++++++++++++++++
 .../runtime-resolvable.service.ts                  | 43 ++++++++++
 ...c-runtime-resolvable-oneof-input.component.html | 19 +++--
 ...tic-runtime-resolvable-oneof-input.component.ts | 81 +++---------------
 .../static-secret-input.component.ts               |  3 +-
 ui/src/app/core-model/gen/streampipes-model.ts     | 13 +--
 .../dialog/customize/customize.component.html      |  8 +-
 .../editor/dialog/customize/customize.component.ts |  6 ++
 ui/src/scss/sp/main.scss                           |  5 ++
 35 files changed, 308 insertions(+), 233 deletions(-)

diff --git a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AdapterTemplateResource.java b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AdapterTemplateResource.java
index f51972b..57fb640 100644
--- a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AdapterTemplateResource.java
+++ b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AdapterTemplateResource.java
@@ -20,11 +20,10 @@ package org.apache.streampipes.connect.container.master.rest;
 
 import org.apache.streampipes.connect.adapter.exception.AdapterException;
 import org.apache.streampipes.connect.container.master.management.AdapterTemplateMasterManagement;
-import org.apache.streampipes.connect.management.AdapterDeserializer;
 import org.apache.streampipes.connect.rest.AbstractContainerResource;
-import org.apache.streampipes.model.message.Notifications;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
 import org.apache.streampipes.model.connect.adapter.AdapterDescriptionList;
+import org.apache.streampipes.model.message.Notifications;
 import org.apache.streampipes.rest.shared.annotation.JacksonSerialized;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -50,17 +49,7 @@ public class AdapterTemplateResource extends AbstractContainerResource {
     @Path("/")
     @JacksonSerialized
     @Produces(MediaType.APPLICATION_JSON)
-    public Response addAdapterTemplate(String s, @PathParam("username") String userName) {
-
-        AdapterDescription adapterDescription = null;
-
-        try {
-            adapterDescription = AdapterDeserializer.getAdapterDescription(s);
-        } catch (AdapterException e) {
-            logger.error("Could not deserialize AdapterDescription: " + s, e);
-            e.printStackTrace();
-        }
-
+    public Response addAdapterTemplate(AdapterDescription adapterDescription, @PathParam("username") String userName) {
         try {
             String adapterTemplateId = adapterTemplateMasterManagement.addAdapterTemplate(adapterDescription);
             logger.info("User: " + userName + " added adapter as adapter template");
@@ -70,8 +59,6 @@ public class AdapterTemplateResource extends AbstractContainerResource {
             logger.error("Error while storing the adapter template", e);
             return ok(Notifications.error(e.getMessage()));
         }
-
-
     }
 
     @GET
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/runtime/RuntimeOptionsRequest.java b/streampipes-model/src/main/java/org/apache/streampipes/model/runtime/RuntimeOptionsRequest.java
index 4f9033a..bc270d1 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/runtime/RuntimeOptionsRequest.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/runtime/RuntimeOptionsRequest.java
@@ -52,6 +52,8 @@ public class RuntimeOptionsRequest extends UnnamedStreamPipesEntity {
   @RdfProperty(StreamPipes.RECEIVES_STREAM)
   protected List<SpDataStream> inputStreams;
 
+  private String belongsTo;
+
   public RuntimeOptionsRequest() {
     super();
   }
@@ -100,4 +102,12 @@ public class RuntimeOptionsRequest extends UnnamedStreamPipesEntity {
   public void setAppId(String appId) {
     this.appId = appId;
   }
+
+  public String getBelongsTo() {
+    return belongsTo;
+  }
+
+  public void setBelongsTo(String belongsTo) {
+    this.belongsTo = belongsTo;
+  }
 }
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/runtime/RuntimeOptionsResponse.java b/streampipes-model/src/main/java/org/apache/streampipes/model/runtime/RuntimeOptionsResponse.java
index 1a5cd18..cf73f9b 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/runtime/RuntimeOptionsResponse.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/runtime/RuntimeOptionsResponse.java
@@ -27,6 +27,7 @@ import javax.persistence.CascadeType;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.OneToMany;
+import java.util.ArrayList;
 import java.util.List;
 
 @RdfsClass(StreamPipes.RUNTIME_OPTIONS_RESPONSE)
@@ -41,6 +42,7 @@ public class RuntimeOptionsResponse extends RuntimeOptionsRequest {
 
   public RuntimeOptionsResponse() {
     super();
+    this.options = new ArrayList<>();
   }
 
   public RuntimeOptionsResponse(RuntimeOptionsRequest request, List<Option> options) {
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/operations/Operations.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/operations/Operations.java
index c647878..a3696a3 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/operations/Operations.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/operations/Operations.java
@@ -38,14 +38,14 @@ import org.apache.streampipes.model.SpDataSet;
 import org.apache.streampipes.model.SpDataStream;
 import org.apache.streampipes.model.client.endpoint.RdfEndpoint;
 import org.apache.streampipes.model.client.endpoint.RdfEndpointItem;
-import org.apache.streampipes.model.message.Message;
 import org.apache.streampipes.model.message.DataSetModificationMessage;
+import org.apache.streampipes.model.message.Message;
+import org.apache.streampipes.model.message.PipelineModificationMessage;
 import org.apache.streampipes.model.pipeline.Pipeline;
 import org.apache.streampipes.model.pipeline.PipelineElementRecommendationMessage;
-import org.apache.streampipes.model.message.PipelineModificationMessage;
 import org.apache.streampipes.model.pipeline.PipelineOperationStatus;
-import org.apache.streampipes.model.runtime.ContainerProvidedOptionsParameterRequest;
-import org.apache.streampipes.model.staticproperty.Option;
+import org.apache.streampipes.model.runtime.RuntimeOptionsRequest;
+import org.apache.streampipes.model.runtime.RuntimeOptionsResponse;
 import org.apache.streampipes.model.template.PipelineTemplateDescription;
 import org.apache.streampipes.model.template.PipelineTemplateInvocation;
 import org.apache.streampipes.storage.management.StorageDispatcher;
@@ -156,7 +156,7 @@ public class Operations {
     return new WildcardTopicGenerator(stream).computeActualTopic();
   }
 
-  public static List<Option> fetchRemoteOptions(ContainerProvidedOptionsParameterRequest request) {
+  public static RuntimeOptionsResponse fetchRemoteOptions(RuntimeOptionsRequest request) {
     return new ContainerProvidedOptionsHandler().fetchRemoteOptions(request);
   }
 
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java
index 59ac20c..6766d98 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java
@@ -21,62 +21,39 @@ import com.google.gson.JsonSyntaxException;
 import org.apache.http.client.fluent.Request;
 import org.apache.http.client.fluent.Response;
 import org.apache.http.entity.ContentType;
-import org.apache.streampipes.model.runtime.ContainerProvidedOptionsParameterRequest;
 import org.apache.streampipes.model.runtime.RuntimeOptionsRequest;
 import org.apache.streampipes.model.runtime.RuntimeOptionsResponse;
-import org.apache.streampipes.model.staticproperty.Option;
 import org.apache.streampipes.serializers.json.GsonSerializer;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
 
 public class ContainerProvidedOptionsHandler {
 
 
-  public List<Option> fetchRemoteOptions(ContainerProvidedOptionsParameterRequest parameterRequest) {
+  public RuntimeOptionsResponse fetchRemoteOptions(RuntimeOptionsRequest request) {
+
+//    RuntimeOptionsRequest request = new RuntimeOptionsRequest();
+//    request.setRequestId(parameterRequest.getRuntimeResolvableInternalId());
+//    request.setInputStreams(parameterRequest.getInputStreams());
+//    request.setStaticProperties(parameterRequest.getStaticProperties());
+//    request.setAppId(parameterRequest.getAppId());
 
-    RuntimeOptionsRequest request = new RuntimeOptionsRequest();
-    request.setRequestId(parameterRequest.getRuntimeResolvableInternalId());
-    request.setInputStreams(parameterRequest.getInputStreams());
-    request.setStaticProperties(parameterRequest.getStaticProperties());
-    request.setAppId(parameterRequest.getAppId());
-//    Optional<RuntimeResolvableSelectionStaticProperty> runtimeResolvableOpt = findProperty
-//            (parameterRequest.getStaticProperties(), parameterRequest.getRuntimeResolvableInternalId());
-//
-//    if (runtimeResolvableOpt.isPresent()) {
-//      RuntimeResolvableSelectionStaticProperty rsp = runtimeResolvableOpt.get();
-//      RuntimeOptionsRequest request = new RuntimeOptionsRequest(rsp.getInternalName());
-//
-//      if (rsp.getLinkedMappingPropertyId() != null) {
-//        Optional<EventProperty> eventPropertyOpt = findEventProperty(parameterRequest.getEventProperties(),
-//                parameterRequest.getStaticProperties(), rsp
-//                        .getLinkedMappingPropertyId());
-//        eventPropertyOpt.ifPresent(request::setMappedEventProperty);
-//      }
     String httpRequestBody = GsonSerializer.getGsonWithIds()
             .toJson(request);
 
     try {
-      Response httpResp = Request.Post(parameterRequest.getBelongsTo() + "/configurations").bodyString(httpRequestBody, ContentType.APPLICATION_JSON).execute();
+      Response httpResp = Request.Post(request.getBelongsTo() + "/configurations").bodyString(httpRequestBody, ContentType.APPLICATION_JSON).execute();
       return handleResponse(httpResp);
     } catch (Exception e) {
       e.printStackTrace();
-      return new ArrayList<>();
+      return new RuntimeOptionsResponse();
     }
   }
 
-  private List<Option> handleResponse(Response httpResp) throws JsonSyntaxException, IOException {
+  private RuntimeOptionsResponse handleResponse(Response httpResp) throws JsonSyntaxException, IOException {
     String resp = httpResp.returnContent().asString();
-    RuntimeOptionsResponse response = GsonSerializer
+    return GsonSerializer
             .getGsonWithIds()
             .fromJson(resp, RuntimeOptionsResponse.class);
-
-    return response
-            .getOptions()
-            .stream()
-            .map(Option::new)
-            .collect(Collectors.toList());
   }
 }
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/ContainerProvidedOptions.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/ContainerProvidedOptions.java
index 771744c..ed929be 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/ContainerProvidedOptions.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/ContainerProvidedOptions.java
@@ -18,8 +18,8 @@
 package org.apache.streampipes.rest.impl;
 
 import org.apache.streampipes.manager.operations.Operations;
-import org.apache.streampipes.model.runtime.ContainerProvidedOptionsParameterRequest;
-import org.apache.streampipes.rest.shared.annotation.GsonWithIds;
+import org.apache.streampipes.model.runtime.RuntimeOptionsRequest;
+import org.apache.streampipes.rest.shared.annotation.JacksonSerialized;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.POST;
@@ -34,8 +34,8 @@ public class ContainerProvidedOptions extends AbstractRestInterface {
   @POST
   @Consumes(MediaType.APPLICATION_JSON)
   @Produces(MediaType.APPLICATION_JSON)
-  @GsonWithIds
-  public Response fetchRemoteOptions(ContainerProvidedOptionsParameterRequest request) {
+  @JacksonSerialized
+  public Response fetchRemoteOptions(RuntimeOptionsRequest request) {
     return ok(Operations.fetchRemoteOptions(request));
   }
 }
diff --git a/ui/src/app/connect/connect.component.ts b/ui/src/app/connect/connect.component.ts
index df15311..e74712e 100644
--- a/ui/src/app/connect/connect.component.ts
+++ b/ui/src/app/connect/connect.component.ts
@@ -18,6 +18,7 @@
 
 import {Component} from '@angular/core';
 import {AdapterDescription} from './model/connect/AdapterDescription';
+import {AdapterDescriptionUnion} from "../core-model/gen/streampipes-model";
 
 @Component({
   selector: 'sp-connect',
@@ -25,9 +26,9 @@ import {AdapterDescription} from './model/connect/AdapterDescription';
   styleUrls: ['./connect.component.css'],
 })
 export class ConnectComponent {
-  newAdapterFromDescription: AdapterDescription;
+  newAdapterFromDescription: AdapterDescriptionUnion;
 
-  selectAdapter(adapterDescription: AdapterDescription) {
+  selectAdapter(adapterDescription: AdapterDescriptionUnion) {
     this.newAdapterFromDescription = adapterDescription;
   }
 
diff --git a/ui/src/app/connect/connect.module.ts b/ui/src/app/connect/connect.module.ts
index a6c6efd..9be2929 100644
--- a/ui/src/app/connect/connect.module.ts
+++ b/ui/src/app/connect/connect.module.ts
@@ -98,6 +98,7 @@ import { EventSchemaPreviewComponent } from './schema-editor/event-schema-previe
 import { StaticColorPickerComponent } from './static-properties/static-color-picker/static-color-picker.component';
 import {DisplayRecommendedPipe} from "./static-properties/filter/display-recommended.pipe";
 import {TourProviderService} from "../services/tour/tour-provider.service";
+import {RuntimeResolvableService} from "./static-properties/static-runtime-resolvable-input/runtime-resolvable.service";
 
 
 @NgModule({
@@ -168,6 +169,7 @@ import {TourProviderService} from "../services/tour/tour-provider.service";
     ],
     providers: [
         RestService,
+        RuntimeResolvableService,
         ConnectService,
         DataTypesService,
         TransformationRuleService,
diff --git a/ui/src/app/connect/data-marketplace/data-marketplace.component.ts b/ui/src/app/connect/data-marketplace/data-marketplace.component.ts
index b0fbdac..dc77a43 100644
--- a/ui/src/app/connect/data-marketplace/data-marketplace.component.ts
+++ b/ui/src/app/connect/data-marketplace/data-marketplace.component.ts
@@ -47,7 +47,7 @@ export class DataMarketplaceComponent implements OnInit {
     visibleAdapters: AdapterDescriptionUnion[];
 
     @Output()
-    selectAdapterEmitter: EventEmitter<AdapterDescription> = new EventEmitter<AdapterDescription>();
+    selectAdapterEmitter: EventEmitter<AdapterDescriptionUnion> = new EventEmitter<AdapterDescriptionUnion>();
 
     selectedIndex: number = 0;
     filterTerm: string = "";
diff --git a/ui/src/app/connect/new-adapter/new-adapter.component.html b/ui/src/app/connect/new-adapter/new-adapter.component.html
index 6f286ae..d82ed2e 100644
--- a/ui/src/app/connect/new-adapter/new-adapter.component.html
+++ b/ui/src/app/connect/new-adapter/new-adapter.component.html
@@ -235,11 +235,11 @@
                 <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-->
-<!--                        id="button-saveTemplate" color="primary" (click)="saveTemplate()" mat-button-->
-<!--                        style="margin-left:10px;">-->
-<!--                        Save as Template-->
-<!--                    </button>-->
+                    <button [disabled]="startAdapterFormGroup.invalid || !isEditable" 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"
                         color="primary" (click)="startAdapter()" mat-button style="margin-left:10px;">
                         Start Adapter
diff --git a/ui/src/app/connect/rest.service.ts b/ui/src/app/connect/rest.service.ts
index a836f91..0cf436d 100644
--- a/ui/src/app/connect/rest.service.ts
+++ b/ui/src/app/connect/rest.service.ts
@@ -53,18 +53,6 @@ export class RestService {
         return this.addAdapterDescription(adapter, '/master/adapters/template');
     }
 
-    fetchRemoteOptions(resolvableOptionsParameterRequest: any, adapterId: string): Observable<RuntimeOptionsResponse> {
-        resolvableOptionsParameterRequest["@class"] = "org.apache.streampipes.model.runtime.RuntimeOptionsRequest";
-        return this.http.post("/streampipes-connect/api/v1/"
-            + this.authStatusService.email
-            + "/master/resolvable/"
-            + encodeURIComponent(adapterId)
-            + "/configurations", resolvableOptionsParameterRequest)
-            .pipe(map(response => {
-                return RuntimeOptionsResponse.fromData(response as RuntimeOptionsResponse);
-            }));
-    }
-
     addAdapterDescription(adapter: AdapterDescription, url: String): Observable<Message> {
         adapter.userName = this.authStatusService.email;
 
diff --git a/ui/src/app/connect/static-properties/base/abstract-static-property.ts b/ui/src/app/connect/static-properties/base/abstract-static-property.ts
index 8240f0b..f9175e8 100644
--- a/ui/src/app/connect/static-properties/base/abstract-static-property.ts
+++ b/ui/src/app/connect/static-properties/base/abstract-static-property.ts
@@ -21,9 +21,10 @@ import {
   StaticProperty,
   StaticPropertyUnion
 } from "../../../core-model/gen/streampipes-model";
-import { EventEmitter, Input, Output, Directive } from "@angular/core";
+import {Directive, EventEmitter, Input, Output} from "@angular/core";
 import {FormGroup} from "@angular/forms";
 import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
+import {InvocablePipelineElementUnion} from "../../../editor/model/editor.model";
 
 @Directive()
 export abstract class AbstractStaticPropertyRenderer<T extends StaticProperty> {
@@ -41,6 +42,9 @@ export abstract class AbstractStaticPropertyRenderer<T extends StaticProperty> {
   adapterId: string;
 
   @Input()
+  pipelineElement: InvocablePipelineElementUnion;
+
+  @Input()
   parentForm: FormGroup;
 
   @Input()
diff --git a/ui/src/app/connect/static-properties/base/abstract-validated-static-property.ts b/ui/src/app/connect/static-properties/base/abstract-validated-static-property.ts
index bf57469..3a2718d 100644
--- a/ui/src/app/connect/static-properties/base/abstract-validated-static-property.ts
+++ b/ui/src/app/connect/static-properties/base/abstract-validated-static-property.ts
@@ -19,7 +19,7 @@
 import {StaticProperty} from "../../../core-model/gen/streampipes-model";
 import {AbstractStaticPropertyRenderer} from "./abstract-static-property";
 import {FormControl, ValidatorFn} from "@angular/forms";
-import { OnDestroy, Directive } from "@angular/core";
+import {Directive, OnDestroy} from "@angular/core";
 
 @Directive()
 export abstract class AbstractValidatedStaticPropertyRenderer<T extends StaticProperty>
diff --git a/ui/src/app/connect/static-properties/filter/display-recommended.pipe.ts b/ui/src/app/connect/static-properties/filter/display-recommended.pipe.ts
index 0834937..cd56b3d 100644
--- a/ui/src/app/connect/static-properties/filter/display-recommended.pipe.ts
+++ b/ui/src/app/connect/static-properties/filter/display-recommended.pipe.ts
@@ -17,7 +17,6 @@
  */
 
 import {Pipe, PipeTransform} from "@angular/core";
-import * as angular from "angular";
 import {EventPropertyUnion} from "../../../core-model/gen/streampipes-model";
 
 @Pipe({name: 'displayRecommendedPipe'})
diff --git a/ui/src/app/connect/static-properties/static-alternatives/static-alternatives.component.ts b/ui/src/app/connect/static-properties/static-alternatives/static-alternatives.component.ts
index c36f27e..e6599b8 100644
--- a/ui/src/app/connect/static-properties/static-alternatives/static-alternatives.component.ts
+++ b/ui/src/app/connect/static-properties/static-alternatives/static-alternatives.component.ts
@@ -18,10 +18,7 @@
 
 import {ChangeDetectorRef, Component, EventEmitter, OnInit, Output} from '@angular/core';
 import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
-import {
-  StaticPropertyAlternatives,
-  StaticPropertyGroup
-} from "../../../core-model/gen/streampipes-model";
+import {StaticPropertyAlternatives} from "../../../core-model/gen/streampipes-model";
 
 @Component({
     selector: 'app-static-alternatives',
diff --git a/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.html b/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.html
index 057bb1d..c43d8bc 100644
--- a/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.html
+++ b/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.html
@@ -18,11 +18,6 @@
 
 <div id="formWrapper" fxFlex="100" fxLayout="column">
     <div *ngIf="!staticProperty.horizontalRendering" fxLayout="column">
-        <div>
-            <p>{{staticProperty.label}}: <br>
-                <mat-hint class="description">{{staticProperty.description}}</mat-hint>
-            </p>
-        </div>
         <mat-checkbox *ngFor="let option of staticProperty.options" [(ngModel)]="option.selected" style="margin-left: 10px;">
             {{option.name}}
         </mat-checkbox>
@@ -31,16 +26,14 @@
 
     <div *ngIf="staticProperty.horizontalRendering">
         <mat-form-field style="width: 100%">
-            <mat-label>{{staticProperty.label}}</mat-label>
             <mat-select multiple>
-                <mat-option *ngFor="let option of staticProperty.options" [value]="option.id"
-                            (click)="select(option.id)">
+                <mat-option *ngFor="let option of staticProperty.options" [value]="option.elementId"
+                            (click)="select(option.elementId)">
                     <label style="font-weight: normal">
                         {{option.name}}
                     </label>
                 </mat-option>
             </mat-select>
-            <mat-hint>{{staticProperty.description}}</mat-hint>
         </mat-form-field>
     </div>
 </div>
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.ts b/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.ts
index 2f3fadf..bfd9d26 100644
--- a/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.ts
@@ -36,4 +36,10 @@ export class StaticAnyInput extends AbstractStaticPropertyRenderer<AnyStaticProp
     }
     this.inputEmitter.emit(true);
   }
+
+  select(elementId: string) {
+    this.staticProperty.options
+        .filter(option => option.elementId === elementId)
+        .forEach(option => option.selected = !(option.selected));
+  }
 }
diff --git a/ui/src/app/connect/static-properties/static-code-input/static-code-input.component.ts b/ui/src/app/connect/static-properties/static-code-input/static-code-input.component.ts
index 1dc8f60..d847a3e 100644
--- a/ui/src/app/connect/static-properties/static-code-input/static-code-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-code-input/static-code-input.component.ts
@@ -16,13 +16,9 @@
  *
  */
 
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
-import {
-  CodeInputStaticProperty,
-  CollectionStaticProperty
-} from "../../../core-model/gen/streampipes-model";
+import {CodeInputStaticProperty} from "../../../core-model/gen/streampipes-model";
 import {AbstractValidatedStaticPropertyRenderer} from "../base/abstract-validated-static-property";
-import {AfterViewInit, Component, OnInit, ViewChild} from "@angular/core";
+import {AfterViewInit, Component, OnInit} from "@angular/core";
 
 import 'codemirror/mode/javascript/javascript';
 import 'codemirror/addon/edit/closebrackets';
diff --git a/ui/src/app/connect/static-properties/static-collection/static-collection.component.ts b/ui/src/app/connect/static-properties/static-collection/static-collection.component.ts
index 8c0b6b7..526a1f7 100644
--- a/ui/src/app/connect/static-properties/static-collection/static-collection.component.ts
+++ b/ui/src/app/connect/static-properties/static-collection/static-collection.component.ts
@@ -16,15 +16,10 @@
  *
  */
 
-import {Component, EventEmitter, OnInit, Output} from '@angular/core';
+import {Component, OnInit} from '@angular/core';
 import {ConfigurationInfo} from '../../model/message/ConfigurationInfo';
 import {StaticPropertyUtilService} from '../static-property-util.service';
-import {
-    CollectionStaticProperty,
-    StaticProperty,
-    StaticPropertyUnion
-} from "../../../core-model/gen/streampipes-model";
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
+import {CollectionStaticProperty} from "../../../core-model/gen/streampipes-model";
 import {AbstractValidatedStaticPropertyRenderer} from "../base/abstract-validated-static-property";
 
 
diff --git a/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts b/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts
index 5782623..f1a1a50 100644
--- a/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts
+++ b/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts
@@ -16,11 +16,10 @@
  *
  */
 
-import {Component, EventEmitter, OnInit, Output} from "@angular/core";
+import {Component, OnInit} from "@angular/core";
 import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
 import {StaticPropertyUtilService} from "../static-property-util.service";
-import {FormControl, FormGroup, Validators} from "@angular/forms";
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
+import {FormGroup, Validators} from "@angular/forms";
 import {ColorPickerStaticProperty} from "../../../core-model/gen/streampipes-model";
 import {AbstractValidatedStaticPropertyRenderer} from "../base/abstract-validated-static-property";
 
diff --git a/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.ts b/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.ts
index f861ccf..327ad94 100644
--- a/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.ts
@@ -16,17 +16,13 @@
  *
  */
 
-import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
+import {Component, OnInit, ViewChild} from '@angular/core';
 import {ValidatorFn, Validators} from '@angular/forms';
 import {StaticPropertyUtilService} from '../static-property-util.service';
 import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
 import {FreeTextStaticProperty} from "../../../core-model/gen/streampipes-model";
 import {xsService} from "../../../NS/XS.service";
-import {
-  ValidateNumber,
-  ValidateString,
-  ValidateUrl
-} from "../input.validator";
+import {ValidateNumber, ValidateString, ValidateUrl} from "../input.validator";
 import {AbstractValidatedStaticPropertyRenderer} from "../base/abstract-validated-static-property";
 import {QuillEditorComponent} from "ngx-quill";
 
diff --git a/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts b/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
index 521bed9..e61f549 100644
--- a/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
+++ b/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
@@ -19,12 +19,15 @@
 import {StaticPropertyUtilService} from "../static-property-util.service";
 import {PropertySelectorService} from "../../../services/property-selector.service";
 import {
-    EventProperty, EventPropertyList, EventPropertyNested, EventPropertyPrimitive,
-    EventPropertyUnion,
-    MappingProperty
+  EventProperty,
+  EventPropertyList,
+  EventPropertyNested,
+  EventPropertyPrimitive,
+  EventPropertyUnion,
+  MappingProperty
 } from "../../../core-model/gen/streampipes-model";
 import {AbstractValidatedStaticPropertyRenderer} from "../base/abstract-validated-static-property";
-import { Directive } from "@angular/core";
+import {Directive} from "@angular/core";
 
 
 @Directive()
diff --git a/ui/src/app/connect/static-properties/static-property.component.html b/ui/src/app/connect/static-properties/static-property.component.html
index dc5762f..ecd7b49 100644
--- a/ui/src/app/connect/static-properties/static-property.component.html
+++ b/ui/src/app/connect/static-properties/static-property.component.html
@@ -59,12 +59,18 @@
             </app-static-color-picker>
 
             <app-static-runtime-resolvable-any-input *ngIf="isRuntimeResolvableAnyStaticProperty(staticProperty)"
-                                                     (inputEmitter)="valueChange($event)"
-                                                     [staticProperty]="staticProperty"></app-static-runtime-resolvable-any-input>
+                                                     [staticProperty]="staticProperty"
+                                                     [staticProperties]="staticProperties"
+                                                     [eventSchemas]="eventSchemas"
+                                                     [pipelineElement]="pipelineElement"
+                                                     [completedStaticProperty]="completedStaticProperty"
+                                                     [adapterId]="adapterId">
+            </app-static-runtime-resolvable-any-input>
 
             <app-static-runtime-resolvable-oneof-input *ngIf="isRuntimeResolvableOneOfStaticProperty(staticProperty)"
-                                                       (inputEmitter)="valueChange($event)"
                                                        [completedStaticProperty]="completedStaticProperty"
+                                                       [pipelineElement]="pipelineElement"
+                                                       [eventSchemas]="eventSchemas"
                                                        [staticProperty]="staticProperty"
                                                        [staticProperties]="staticProperties"
                                                        [adapterId]="adapterId"></app-static-runtime-resolvable-oneof-input>
diff --git a/ui/src/app/connect/static-properties/static-property.component.ts b/ui/src/app/connect/static-properties/static-property.component.ts
index 1c37dd9..5a38c8a 100644
--- a/ui/src/app/connect/static-properties/static-property.component.ts
+++ b/ui/src/app/connect/static-properties/static-property.component.ts
@@ -23,7 +23,8 @@ import {xsService} from '../../NS/XS.service';
 import {StaticPropertyUtilService} from './static-property-util.service';
 import {ConfigurationInfo} from "../model/message/ConfigurationInfo";
 import {
-  AnyStaticProperty, CodeInputStaticProperty,
+  AnyStaticProperty,
+  CodeInputStaticProperty,
   CollectionStaticProperty,
   ColorPickerStaticProperty,
   EventSchema,
@@ -40,6 +41,7 @@ import {
   StaticPropertyGroup
 } from "../../core-model/gen/streampipes-model";
 import {FormGroup} from "@angular/forms";
+import {InvocablePipelineElementUnion} from "../../editor/model/editor.model";
 
 @Component({
   selector: 'app-static-property',
@@ -79,6 +81,9 @@ export class StaticPropertyComponent implements OnInit {
   @Input()
   displayRecommended: boolean;
 
+  @Input()
+  pipelineElement: InvocablePipelineElementUnion;
+
   constructor(
     private logger: Logger,
     public xsService: xsService,
diff --git a/ui/src/app/connect/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.html b/ui/src/app/connect/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.html
index ea40d59..faeb85d 100644
--- a/ui/src/app/connect/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.html
+++ b/ui/src/app/connect/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.html
@@ -18,16 +18,26 @@
 
 
 <div id="formWrapper" fxFlex="100" fxLayout="column">
-
-    <div *ngIf="!staticProperty.horizontalRendering" fxLayout="column">
-
-        <p>{{staticProperty.label}}: <br>
-            <mat-hint class="description">{{staticProperty.description}}</mat-hint>
-        </p>
-        <mat-checkbox style="padding-left: 10px" *ngFor="let option of staticProperty.options" [(ngModel)]="option.selected">
+    <div>
+        <button mat-button mat-raised-button color="primary" class="small-button"
+                (click)="loadOptionsFromRestApi()"
+                style="margin-right:10px;margin-left:10px;" [disabled]="!showOptions">
+            <span>Reload</span>
+        </button>
+    </div>
+    <div *ngIf="!staticProperty.horizontalRendering" fxLayout="column" style="margin-top:10px;">
+        <mat-checkbox style="padding-left: 10px;"
+                      color="primary"
+                      *ngFor="let option of staticProperty.options" [(ngModel)]="option.selected">
             {{option.name}}
         </mat-checkbox>
     </div>
+    <div fxLayout="column" *ngIf="!showOptions && !loading">
+        <span>(waiting for input)</span>
+    </div>
+    <div fxLayout="column" *ngIf="loading">
+        <mat-spinner [mode]="'indeterminate'" [diameter]="20"></mat-spinner>
+    </div>
 
     <div *ngIf="staticProperty.horizontalRendering">
         <mat-form-field style="width: 100%">
diff --git a/ui/src/app/connect/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.ts b/ui/src/app/connect/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.ts
index aeef18c..9ca2720 100644
--- a/ui/src/app/connect/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.ts
@@ -16,35 +16,34 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {RuntimeResolvableAnyStaticProperty} from "../../model/RuntimeResolvableAnyStaticProperty";
+import {Component, OnInit} from '@angular/core';
+import {BaseRuntimeResolvableInput} from "../static-runtime-resolvable-input/base-runtime-resolvable-input";
+import {RuntimeResolvableAnyStaticProperty} from "../../../core-model/gen/streampipes-model";
+import {RuntimeResolvableService} from "../static-runtime-resolvable-input/runtime-resolvable.service";
 
 @Component({
     selector: 'app-static-runtime-resolvable-any-input',
     templateUrl: './static-runtime-resolvable-any-input.component.html',
     styleUrls: ['./static-runtime-resolvable-any-input.component.css']
 })
-export class StaticRuntimeResolvableAnyInputComponent implements OnInit {
+export class StaticRuntimeResolvableAnyInputComponent extends BaseRuntimeResolvableInput<RuntimeResolvableAnyStaticProperty> implements OnInit {
 
-    @Input()
-    staticProperty: RuntimeResolvableAnyStaticProperty;
-
-    @Output() inputEmitter: EventEmitter<Boolean> = new EventEmitter<Boolean>();
-
-    constructor() { }
+    constructor(RuntimeResolvableService: RuntimeResolvableService) {
+        super(RuntimeResolvableService);
+    }
 
     ngOnInit() {
-        for (let option of this.staticProperty.options) {
-            option.selected = false;
-        }
+        super.onInit();
     }
 
     select(id) {
         for (let option of this.staticProperty.options) {
             option.selected = false;
         }
-        this.staticProperty.options.find(option => option.id === id).selected = true;
-        this.inputEmitter.emit(true)
+        this.staticProperty.options.find(option => option.elementId === id).selected = true;
+    }
+
+    afterOptionsLoaded() {
     }
 
 }
diff --git a/ui/src/app/connect/static-properties/static-runtime-resolvable-input/base-runtime-resolvable-input.ts b/ui/src/app/connect/static-properties/static-runtime-resolvable-input/base-runtime-resolvable-input.ts
new file mode 100644
index 0000000..8b5cb24
--- /dev/null
+++ b/ui/src/app/connect/static-properties/static-runtime-resolvable-input/base-runtime-resolvable-input.ts
@@ -0,0 +1,98 @@
+/*
+ * 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 {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
+import {
+  RuntimeOptionsRequest,
+  RuntimeOptionsResponse,
+  RuntimeResolvableAnyStaticProperty,
+  RuntimeResolvableOneOfStaticProperty
+} from "../../../core-model/gen/streampipes-model";
+import {RuntimeResolvableService} from "./runtime-resolvable.service";
+import {Observable} from "rxjs";
+import {Directive, Input, OnChanges, SimpleChanges} from "@angular/core";
+import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
+
+@Directive()
+export abstract class BaseRuntimeResolvableInput<T extends RuntimeResolvableAnyStaticProperty | RuntimeResolvableOneOfStaticProperty>
+    extends AbstractStaticPropertyRenderer<T>
+    implements OnChanges {
+
+  @Input()
+  completedStaticProperty: ConfigurationInfo;
+
+  showOptions: boolean = false;
+  loading: boolean = false;
+  dependentStaticProperties: any = new Map();
+
+  constructor(private RuntimeResolvableService: RuntimeResolvableService) {
+    super();
+  }
+
+  onInit() {
+    if (this.staticProperty.options.length == 0 && (!this.staticProperty.dependsOn || this.staticProperty.dependsOn.length == 0)) {
+      this.loadOptionsFromRestApi();
+    } else if (this.staticProperty.options.length > 0) {
+      this.showOptions = true;
+    }
+
+    if (this.staticProperty.dependsOn && this.staticProperty.dependsOn.length > 0) {
+      this.staticProperty.dependsOn.forEach(dp => {
+        this.dependentStaticProperties.set(dp, false);
+      });
+    }
+  }
+
+  loadOptionsFromRestApi() {
+    var resolvableOptionsParameterRequest = new RuntimeOptionsRequest();
+    resolvableOptionsParameterRequest.staticProperties = this.staticProperties;
+    resolvableOptionsParameterRequest.requestId = this.staticProperty.internalName;
+
+    if (this.pipelineElement) {
+      resolvableOptionsParameterRequest.inputStreams = this.pipelineElement.inputStreams;
+      resolvableOptionsParameterRequest.appId = this.pipelineElement.appId;
+      resolvableOptionsParameterRequest.belongsTo = this.pipelineElement.belongsTo;
+    }
+
+    this.showOptions = false;
+    this.loading = true;
+    let observable: Observable<RuntimeOptionsResponse> = this.adapterId ?
+        this.RuntimeResolvableService.fetchRemoteOptionsForAdapter(resolvableOptionsParameterRequest, this.adapterId) :
+        this.RuntimeResolvableService.fetchRemoteOptionsForPipelineElement(resolvableOptionsParameterRequest);
+    observable.subscribe(msg => {
+      this.staticProperty.options = msg.options;
+      this.afterOptionsLoaded();
+      this.loading = false;
+      this.showOptions = true;
+    });
+  }
+
+  ngOnChanges(changes: SimpleChanges): void {
+    if (changes['completedStaticProperty']) {
+      if (this.completedStaticProperty != undefined) {
+        this.dependentStaticProperties.set(this.completedStaticProperty.staticPropertyInternalName, this.completedStaticProperty.configured);
+        if (Array.from(this.dependentStaticProperties.values()).every(v => v === true)) {
+          this.loadOptionsFromRestApi();
+        }
+      }
+    }
+  }
+
+  abstract afterOptionsLoaded();
+
+}
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-runtime-resolvable-input/runtime-resolvable.service.ts b/ui/src/app/connect/static-properties/static-runtime-resolvable-input/runtime-resolvable.service.ts
new file mode 100644
index 0000000..8e0274d
--- /dev/null
+++ b/ui/src/app/connect/static-properties/static-runtime-resolvable-input/runtime-resolvable.service.ts
@@ -0,0 +1,43 @@
+import {Observable} from "rxjs";
+import {
+  RuntimeOptionsRequest,
+  RuntimeOptionsResponse
+} from "../../../core-model/gen/streampipes-model";
+import {map} from "rxjs/operators";
+import {HttpClient} from "@angular/common/http";
+import {AuthStatusService} from "../../../services/auth-status.service";
+import {PlatformServicesCommons} from "../../../platform-services/apis/commons.service";
+import {Injectable} from "@angular/core";
+
+@Injectable()
+export class RuntimeResolvableService {
+
+  constructor(private http: HttpClient,
+              private authStatusService: AuthStatusService,
+              private platformServicesCommons: PlatformServicesCommons) {
+
+  }
+
+  fetchRemoteOptionsForAdapter(resolvableOptionsParameterRequest: RuntimeOptionsRequest, adapterId: string): Observable<RuntimeOptionsResponse> {
+    let url: string = "/streampipes-connect/api/v1/"
+        + this.authStatusService.email
+        + "/master/resolvable/"
+        + encodeURIComponent(adapterId)
+        + "/configurations";
+    return this.fetchRemoteOptions(url, resolvableOptionsParameterRequest);
+  }
+
+  fetchRemoteOptionsForPipelineElement(resolvableOptionsParameterRequest: RuntimeOptionsRequest): Observable<RuntimeOptionsResponse> {
+    let url: string = this.platformServicesCommons.authUserBasePath() + "/pe/options";
+    return this.fetchRemoteOptions(url, resolvableOptionsParameterRequest);
+  }
+
+  fetchRemoteOptions(url, resolvableOptionsParameterRequest) {
+    resolvableOptionsParameterRequest["@class"] = "org.apache.streampipes.model.runtime.RuntimeOptionsRequest";
+    return this.http.post(url, resolvableOptionsParameterRequest)
+        .pipe(map(response => {
+          return RuntimeOptionsResponse.fromData(response as RuntimeOptionsResponse);
+        }));
+  }
+
+}
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.html b/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.html
index 26bf91d..1f18050 100644
--- a/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.html
+++ b/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.html
@@ -17,13 +17,14 @@
   -->
 
 <div id="formWrapper" fxFlex="100" fxLayout="column">
-
+    <div>
+        <button mat-button mat-raised-button color="primary" class="small-button"
+                (click)="loadOptionsFromRestApi()"
+                style="margin-right:10px;margin-left:10px;" [disabled]="!showOptions">
+            <span>Reload</span>
+        </button>
+    </div>
     <div *ngIf="!staticProperty.horizontalRendering" fxLayout="column">
-        <div>
-            <p>{{staticProperty.label}}: <br>
-                <mat-hint class="description">{{staticProperty.description}}</mat-hint>
-            </p>
-        </div>
         <div fxFlex fxLayout="row">
             <div fxLayout="column" *ngIf="showOptions || staticProperty.options" style="margin-left: 10px">
                 <mat-radio-button *ngFor="let option of staticProperty.options"
@@ -33,11 +34,11 @@
                     </label>
                 </mat-radio-button>
             </div>
-            <div fxLayout="column" *ngIf="!showOptions && !staticProperty.options && !loading">
-                (waiting for input)
+            <div fxLayout="column" *ngIf="!showOptions && !loading">
+                <span>(waiting for input)</span>
             </div>
             <div fxLayout="column" *ngIf="loading">
-                <mat-spinner [diameter]="20"></mat-spinner>
+                <mat-spinner [mode]="'indeterminate'" [diameter]="20"></mat-spinner>
             </div>
         </div>
     </div>
diff --git a/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.ts b/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.ts
index 968f8c9..aedbd0c 100644
--- a/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.ts
@@ -16,22 +16,10 @@
  *
  */
 
-import {
-  Component,
-  EventEmitter,
-  Input,
-  OnChanges,
-  OnInit,
-  Output,
-  SimpleChanges
-} from '@angular/core';
-import {RestService} from "../../rest.service";
-import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
-import {
-  RuntimeOptionsRequest,
-  RuntimeResolvableOneOfStaticProperty
-} from "../../../core-model/gen/streampipes-model";
+import {Component, OnChanges, OnInit} from '@angular/core';
+import {RuntimeResolvableOneOfStaticProperty} from "../../../core-model/gen/streampipes-model";
+import {BaseRuntimeResolvableInput} from "../static-runtime-resolvable-input/base-runtime-resolvable-input";
+import {RuntimeResolvableService} from "../static-runtime-resolvable-input/runtime-resolvable.service";
 
 @Component({
     selector: 'app-static-runtime-resolvable-oneof-input',
@@ -39,52 +27,20 @@ import {
     styleUrls: ['./static-runtime-resolvable-oneof-input.component.css']
 })
 export class StaticRuntimeResolvableOneOfInputComponent
-    extends AbstractStaticPropertyRenderer<RuntimeResolvableOneOfStaticProperty> implements OnInit, OnChanges {
+    extends BaseRuntimeResolvableInput<RuntimeResolvableOneOfStaticProperty> implements OnInit, OnChanges {
 
-    @Input()
-    completedStaticProperty: ConfigurationInfo;
-
-    @Output() inputEmitter: EventEmitter<Boolean> = new EventEmitter<Boolean>();
-
-    showOptions: boolean = false;
-    loading: boolean = false;
-    dependentStaticProperties: any = new Map();
-
-    constructor(private RestService: RestService) {
-        super();
+    constructor(RuntimeResolvableService: RuntimeResolvableService) {
+        super(RuntimeResolvableService);
     }
 
     ngOnInit() {
-        for (let option of this.staticProperty.options) {
-            option.selected = false;
-        }
-
-        if (this.staticProperty.options.length == 0 && (!this.staticProperty.dependsOn || this.staticProperty.dependsOn.length == 0)) {
-            this.loadOptionsFromRestApi();
-        }
-
-        if (this.staticProperty.dependsOn && this.staticProperty.dependsOn.length > 0) {
-            this.staticProperty.dependsOn.forEach(dp => {
-                this.dependentStaticProperties.set(dp, false);
-            });
-        }
+        super.onInit();
     }
 
-    loadOptionsFromRestApi() {
-        var resolvableOptionsParameterRequest = new RuntimeOptionsRequest();
-        resolvableOptionsParameterRequest.staticProperties = this.staticProperties;
-        resolvableOptionsParameterRequest.requestId = this.staticProperty.internalName;
-
-        this.showOptions = false;
-        this.loading = true;
-        this.RestService.fetchRemoteOptions(resolvableOptionsParameterRequest, this.adapterId).subscribe(msg => {
-            this.staticProperty.options = msg.options;
-            if (this.staticProperty.options && this.staticProperty.options.length > 0) {
-                this.staticProperty.options[0].selected = true;
-            }
-            this.loading = false;
-            this.showOptions = true;
-        });
+    afterOptionsLoaded() {
+        if (this.staticProperty.options && this.staticProperty.options.length > 0) {
+            this.staticProperty.options[0].selected = true;
+        }
     }
 
     select(id) {
@@ -92,18 +48,5 @@ export class StaticRuntimeResolvableOneOfInputComponent
             option.selected = false;
         }
         this.staticProperty.options.find(option => option.elementId === id).selected = true;
-        this.inputEmitter.emit(true)
-    }
-
-
-    ngOnChanges(changes: SimpleChanges): void {
-        if (changes['completedStaticProperty']) {
-            if (this.completedStaticProperty != undefined) {
-                this.dependentStaticProperties.set(this.completedStaticProperty.staticPropertyInternalName, this.completedStaticProperty.configured);
-                if (Array.from(this.dependentStaticProperties.values()).every(v => v === true)) {
-                    this.loadOptionsFromRestApi();
-                }
-            }
-        }
     }
 }
diff --git a/ui/src/app/connect/static-properties/static-secret-input/static-secret-input.component.ts b/ui/src/app/connect/static-properties/static-secret-input/static-secret-input.component.ts
index 058c70e..bbabbae 100644
--- a/ui/src/app/connect/static-properties/static-secret-input/static-secret-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-secret-input/static-secret-input.component.ts
@@ -17,11 +17,10 @@
  */
 
 import {Component, EventEmitter, OnInit, Output} from '@angular/core';
-import {FormControl, FormGroup, Validators} from '@angular/forms';
+import {Validators} from '@angular/forms';
 import {StaticPropertyUtilService} from '../static-property-util.service';
 import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
 import {SecretStaticProperty} from "../../../core-model/gen/streampipes-model";
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
 import {AbstractValidatedStaticPropertyRenderer} from "../base/abstract-validated-static-property";
 
 @Component({
diff --git a/ui/src/app/core-model/gen/streampipes-model.ts b/ui/src/app/core-model/gen/streampipes-model.ts
index 3f01db7..8ca8ccf 100644
--- a/ui/src/app/core-model/gen/streampipes-model.ts
+++ b/ui/src/app/core-model/gen/streampipes-model.ts
@@ -16,11 +16,10 @@
  *
  */
 
-
 /* tslint:disable */
 /* eslint-disable */
 // @ts-nocheck
-// Generated using typescript-generator version 2.24.612 on 2020-08-04 20:08:43.
+// Generated using typescript-generator version 2.24.612 on 2020-08-20 14:07:30.
 
 export class AbstractStreamPipesEntity {
     "@class": "org.apache.streampipes.model.base.NamedStreamPipesEntity" | "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.AdapterStreamDescription" | "org.apache.streampipes.model.connect.adapter.G [...]
@@ -152,8 +151,8 @@ export class NamedStreamPipesEntity extends AbstractStreamPipesEntity {
         instance.includedLocales = __getCopyArrayFn(__identity<string>())(data.includedLocales);
         instance.applicationLinks = __getCopyArrayFn(ApplicationLink.fromData)(data.applicationLinks);
         instance.connectedTo = __getCopyArrayFn(__identity<string>())(data.connectedTo);
-        instance.uri = data.uri;
         instance.dom = data.dom;
+        instance.uri = data.uri;
         return instance;
     }
 }
@@ -188,9 +187,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);
         instance.couchDBId = data.couchDBId;
         instance._rev = data._rev;
         return instance;
@@ -1556,9 +1555,9 @@ export class GenericAdapterSetDescription extends AdapterSetDescription implemen
         }
         const instance = target || new GenericAdapterSetDescription();
         super.fromData(data, instance);
+        instance.protocolDescription = ProtocolDescription.fromData(data.protocolDescription);
         instance.formatDescription = FormatDescription.fromData(data.formatDescription);
         instance.eventSchema = EventSchema.fromData(data.eventSchema);
-        instance.protocolDescription = ProtocolDescription.fromData(data.protocolDescription);
         return instance;
     }
 }
@@ -1575,9 +1574,9 @@ export class GenericAdapterStreamDescription extends AdapterStreamDescription im
         }
         const instance = target || new GenericAdapterStreamDescription();
         super.fromData(data, instance);
+        instance.protocolDescription = ProtocolDescription.fromData(data.protocolDescription);
         instance.formatDescription = FormatDescription.fromData(data.formatDescription);
         instance.eventSchema = EventSchema.fromData(data.eventSchema);
-        instance.protocolDescription = ProtocolDescription.fromData(data.protocolDescription);
         return instance;
     }
 }
@@ -2274,6 +2273,7 @@ export class Resolution extends EventPropertyQualityDefinition {
 export class RuntimeOptionsRequest extends UnnamedStreamPipesEntity {
     "@class": "org.apache.streampipes.model.runtime.RuntimeOptionsRequest" | "org.apache.streampipes.model.runtime.RuntimeOptionsResponse";
     appId: string;
+    belongsTo: string;
     inputStreams: SpDataStreamUnion[];
     requestId: string;
     staticProperties: StaticPropertyUnion[];
@@ -2288,6 +2288,7 @@ export class RuntimeOptionsRequest extends UnnamedStreamPipesEntity {
         instance.appId = data.appId;
         instance.staticProperties = __getCopyArrayFn(StaticProperty.fromDataUnion)(data.staticProperties);
         instance.inputStreams = __getCopyArrayFn(SpDataStream.fromDataUnion)(data.inputStreams);
+        instance.belongsTo = data.belongsTo;
         return instance;
     }
 }
diff --git a/ui/src/app/editor/dialog/customize/customize.component.html b/ui/src/app/editor/dialog/customize/customize.component.html
index 4b27140..ab6ee980 100644
--- a/ui/src/app/editor/dialog/customize/customize.component.html
+++ b/ui/src/app/editor/dialog/customize/customize.component.html
@@ -21,12 +21,13 @@
         <div fxFlex="100" fxLayout="column">
             <div style="border-bottom:1px solid #ccc;padding:10px;background-color:#f6f6f6">
                 <div fxFlex="100" fxLayout="row" fxLayoutAlign="end end">
-                    <mat-slide-toggle [(ngModel)]="showDocumentation" aria-label="Switch 1"
+                    <mat-slide-toggle [(ngModel)]="showDocumentation"
+                                      color="primary"
                                       [disabled]="!pipelineElement.payload.includesAssets">
                         Show documentation
                     </mat-slide-toggle>
                     <span>&nbsp;</span>
-                    <mat-slide-toggle [(ngModel)]="displayRecommended" aria-label="Switch 1">
+                    <mat-slide-toggle [(ngModel)]="displayRecommended" color="primary">
                         Show only recommended settings
                     </mat-slide-toggle>
                 </div>
@@ -50,11 +51,14 @@
                             <form [formGroup]="parentForm" fxFlex="100">
                                 <app-static-property *ngFor="let config of cachedPipelineElement.staticProperties"
                                                      [staticProperty]="config"
+                                                     [pipelineElement] = "cachedPipelineElement"
                                                      [displayRecommended]="displayRecommended"
                                                      [staticProperties]="cachedPipelineElement.staticProperties"
                                                      [eventSchemas]="eventSchemas"
                                                      [parentForm]="parentForm"
                                                      [fieldName]="config.internalName"
+                                                     [completedStaticProperty]="completedStaticProperty"
+                                                     (updateEmitter)="triggerUpdate($event)"
                                                      (validateEmitter)="validConfiguration($event)">
                                 </app-static-property>
                                 <div *ngIf="isDataProcessor">
diff --git a/ui/src/app/editor/dialog/customize/customize.component.ts b/ui/src/app/editor/dialog/customize/customize.component.ts
index e049835..1c6fd37 100644
--- a/ui/src/app/editor/dialog/customize/customize.component.ts
+++ b/ui/src/app/editor/dialog/customize/customize.component.ts
@@ -23,6 +23,7 @@ import {JsplumbService} from "../../services/jsplumb.service";
 import {DataProcessorInvocation, EventSchema} from "../../../core-model/gen/streampipes-model";
 import {FormBuilder, FormGroup} from "@angular/forms";
 import {ShepherdService} from "../../../services/tour/shepherd.service";
+import {ConfigurationInfo} from "../../../connect/model/message/ConfigurationInfo";
 
 @Component({
   selector: 'customize-pipeline-element',
@@ -61,6 +62,7 @@ export class CustomizeComponent implements OnInit, AfterViewInit {
 
   isDataProcessor: boolean = false;
   originalDialogWidth: string | number;
+  completedStaticProperty: ConfigurationInfo;
 
   constructor(private dialogRef: DialogRef<CustomizeComponent>,
               private JsPlumbService: JsplumbService,
@@ -130,4 +132,8 @@ export class CustomizeComponent implements OnInit, AfterViewInit {
     this.changeDetectorRef.detectChanges();
   }
 
+  triggerUpdate(configurationInfo: ConfigurationInfo) {
+    this.completedStaticProperty = {...configurationInfo};
+  }
+
 }
\ No newline at end of file
diff --git a/ui/src/scss/sp/main.scss b/ui/src/scss/sp/main.scss
index cfc610b..b86fcfc 100644
--- a/ui/src/scss/sp/main.scss
+++ b/ui/src/scss/sp/main.scss
@@ -35,6 +35,11 @@ body {
   width: 100%;
 }
 
+.md-toolbar-tools {
+  width: 100%;
+  align-items: center;
+}
+
 code[class*="language-"], pre[class*="language-"] {
   white-space:pre-wrap;
 }