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


The following commit(s) were added to refs/heads/dev by this push:
     new ec5f27c  [STREAMPIPES-360] Improve adapter management
ec5f27c is described below

commit ec5f27c99d09e31a42764bd8bc7eed04f9b88d86
Author: Dominik Riemer <[email protected]>
AuthorDate: Mon May 17 21:50:49 2021 +0200

    [STREAMPIPES-360] Improve adapter management
---
 .../master/management/AdapterMasterManagement.java |  65 ++++++++---
 .../management/WorkerAdministrationManagement.java |   4 +-
 .../master/management/WorkerRestClient.java        |  94 ++++++---------
 .../master/rest/AbstractAdapterResource.java       |  21 ++--
 .../container/master/rest/AdapterResource.java     |  93 +++++++++------
 .../master/rest/AdapterTemplateResource.java       |  19 +---
 .../container/master/rest/DescriptionResource.java |  59 ++++------
 .../container/master/rest/GuessResource.java       |  32 ++----
 .../master/rest/RuntimeResolvableResource.java     |   8 +-
 .../container/master/rest/SourcesResource.java     |  33 ++----
 .../container/master/rest/UnitResource.java        |  17 +--
 .../container/master/rest/WelcomePageMaster.java   |  46 +++-----
 .../management}/AdapterMasterManagementTest.java   |  31 +++--
 .../AdapterTemplateMasterManagementTest.java       |  14 +--
 .../management}/DescriptionManagementTest.java     |  19 ++--
 .../master/management/SourcesManagementTest.java   |   0
 .../management/UnitMasterManagementTest.java       |   0
 .../master/management/WorkerRestClientTest.java    |  20 ++--
 .../model/connect/adapter/AdapterDescription.java  |  13 +++
 .../connect/adapter/AdapterStreamDescription.java  |  11 ++
 .../serializers/json/AdapterSerializer.java        |  14 ++-
 .../streampipes/storage/api/IAdapterStorage.java   |   2 +-
 .../streampipes/storage/api/INoSqlStorage.java     |   4 +
 .../storage/couchdb/CouchDbStorageManager.java     |  10 ++
 .../storage/couchdb/impl/AdapterStorageImpl.java   |   7 +-
 .../streampipes/storage/couchdb/utils/Utils.java   | 107 +++++++----------
 .../adapter-description.component.html             |  15 +--
 .../adapter-description.component.ts               |  10 --
 .../data-marketplace.component.html                |  62 ++++++----
 .../data-marketplace/data-marketplace.component.ts |  16 +--
 .../existing-adapters.component.html               | 126 +++++++++++++++++++++
 .../existing-adapters.component.scss               |  35 ++++--
 .../existing-adapters.component.ts                 |  96 ++++++++++++++++
 ui/src/app/connect/connect.module.ts               |   2 +
 .../delete-adapter-dialog.component.html           |  52 +++++++++
 .../delete-adapter-dialog.component.ts             |  64 +++++++++++
 .../delete-pipeline-dialog.component.scss          |  19 +---
 .../connect/services/data-marketplace.service.ts   |  37 +++---
 ui/src/app/core-model/gen/streampipes-model.ts     |  16 ++-
 39 files changed, 807 insertions(+), 486 deletions(-)

diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/AdapterMasterManagement.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/AdapterMasterManagement.java
index cb86280..52f5e5f 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/AdapterMasterManagement.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/AdapterMasterManagement.java
@@ -32,6 +32,7 @@ import 
org.apache.streampipes.model.connect.adapter.AdapterStreamDescription;
 import org.apache.streampipes.model.connect.worker.ConnectWorkerContainer;
 import org.apache.streampipes.model.grounding.EventGrounding;
 import org.apache.streampipes.model.util.Cloner;
+import org.apache.streampipes.storage.api.IAdapterStorage;
 import 
org.apache.streampipes.storage.api.IPipelineElementDescriptionStorageCache;
 import org.apache.streampipes.storage.couchdb.impl.AdapterStorageImpl;
 import org.apache.streampipes.storage.management.StorageDispatcher;
@@ -48,8 +49,18 @@ public class AdapterMasterManagement {
 
   private static final Logger LOG = 
LoggerFactory.getLogger(AdapterMasterManagement.class);
 
-  public static void startAllStreamAdapters(ConnectWorkerContainer 
connectWorkerContainer) throws AdapterException {
-    AdapterStorageImpl adapterStorage = new AdapterStorageImpl();
+  private IAdapterStorage adapterStorage;
+
+  public AdapterMasterManagement() {
+    this.adapterStorage = getAdapterStorage();
+  }
+
+  public AdapterMasterManagement(IAdapterStorage adapterStorage) {
+    this.adapterStorage = adapterStorage;
+  }
+
+  public void startAllStreamAdapters(ConnectWorkerContainer 
connectWorkerContainer) throws AdapterException {
+    IAdapterStorage adapterStorage = getAdapterStorage();
     List<AdapterDescription> allAdapters = adapterStorage.getAllAdapters();
 
     for (AdapterDescription ad : allAdapters) {
@@ -69,8 +80,9 @@ public class AdapterMasterManagement {
     }
   }
 
-  public String addAdapter(AdapterDescription ad, String baseUrl, 
AdapterStorageImpl
-          adapterStorage, String username)
+  public String addAdapter(AdapterDescription ad,
+                           String baseUrl,
+                           String username)
           throws AdapterException {
 
     // Add EventGrounding to AdapterDescription
@@ -83,17 +95,17 @@ public class AdapterMasterManagement {
     String newId = ConnectContainerConfig.INSTANCE.getBackendApiUrl() + 
"api/v2/connect/" + username + "/master/sources/" + uuid;
 
     ad.setElementId(newId);
-
+    ad.setCreatedAt(System.currentTimeMillis());
 
     AdapterDescription encryptedAdapterDescription =
             new AdapterEncryptionService(new 
Cloner().adapterDescription(ad)).encrypt();
     // store in db
-    adapterStorage.storeAdapter(encryptedAdapterDescription);
+    String adapterId = 
adapterStorage.storeAdapter(encryptedAdapterDescription);
 
     // start when stream adapter
     if (ad instanceof AdapterStreamDescription) {
       // TODO
-      WorkerRestClient.invokeStreamAdapter(baseUrl, (AdapterStreamDescription) 
ad);
+      WorkerRestClient.invokeStreamAdapter(baseUrl, adapterId);
       LOG.info("Start adapter");
     }
 
@@ -117,8 +129,7 @@ public class AdapterMasterManagement {
     }
   }
 
-  public AdapterDescription getAdapter(String id, AdapterStorageImpl 
adapterStorage) throws AdapterException {
-
+  public AdapterDescription getAdapter(String id) throws AdapterException {
     List<AdapterDescription> allAdapters = adapterStorage.getAllAdapters();
 
     if (allAdapters != null && id != null) {
@@ -134,11 +145,10 @@ public class AdapterMasterManagement {
 
   public void deleteAdapter(String id, String baseUrl) throws AdapterException 
{
     //        // IF Stream adapter delete it
-    AdapterStorageImpl adapterStorage = new AdapterStorageImpl();
-    boolean isStreamAdapter = isStreamAdapter(id, adapterStorage);
+    boolean isStreamAdapter = isStreamAdapter(id);
 
     if (isStreamAdapter) {
-      stopStreamAdapter(id, baseUrl, adapterStorage);
+      stopStreamAdapter(id, baseUrl);
     }
     AdapterDescription ad = adapterStorage.getAdapter(id);
     String username = ad.getUserName();
@@ -155,7 +165,7 @@ public class AdapterMasterManagement {
     }
   }
 
-  public List<AdapterDescription> getAllAdapters(AdapterStorageImpl 
adapterStorage) throws AdapterException {
+  public List<AdapterDescription> getAllAdapters() throws AdapterException {
 
     List<AdapterDescription> allAdapters = adapterStorage.getAllAdapters();
 
@@ -166,23 +176,42 @@ public class AdapterMasterManagement {
     return allAdapters;
   }
 
-  public static void stopSetAdapter(String adapterId, String baseUrl, 
AdapterStorageImpl adapterStorage) throws AdapterException {
+  public void stopSetAdapter(String adapterId, String baseUrl, 
AdapterStorageImpl adapterStorage) throws AdapterException {
 
     AdapterSetDescription ad = (AdapterSetDescription) 
adapterStorage.getAdapter(adapterId);
 
     WorkerRestClient.stopSetAdapter(baseUrl, ad);
   }
 
-  public static void stopStreamAdapter(String adapterId, String baseUrl, 
AdapterStorageImpl adapterStorage) throws AdapterException {
-    AdapterStreamDescription ad = (AdapterStreamDescription) 
adapterStorage.getAdapter(adapterId);
+  public void stopStreamAdapter(String adapterId, String baseUrl) throws 
AdapterException {
+    AdapterDescription ad = adapterStorage.getAdapter(adapterId);
+
+    if (!isStreamAdapter(adapterId)) {
+      throw new AdapterException("Adapter " + adapterId + "is not a stream 
adapter.");
+    } else {
+      WorkerRestClient.stopStreamAdapter(baseUrl, (AdapterStreamDescription) 
ad);
 
-    WorkerRestClient.stopStreamAdapter(baseUrl, ad);
+    }
+  }
+
+  public void startStreamAdapter(String adapterId, String baseUrl) throws 
AdapterException {
+    AdapterDescription ad = adapterStorage.getAdapter(adapterId);
+
+    if (!isStreamAdapter(adapterId)) {
+      throw new AdapterException("Adapter " + adapterId + "is not a stream 
adapter.");
+    } else {
+      WorkerRestClient.invokeStreamAdapter(baseUrl, (AdapterStreamDescription) 
ad);
+    }
   }
 
-  public static boolean isStreamAdapter(String id, AdapterStorageImpl 
adapterStorage) {
+  public boolean isStreamAdapter(String id) {
     AdapterDescription ad = adapterStorage.getAdapter(id);
 
     return ad instanceof AdapterStreamDescription;
   }
 
+  private IAdapterStorage getAdapterStorage() {
+    return new AdapterStorageImpl();
+  }
+
 }
diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/WorkerAdministrationManagement.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/WorkerAdministrationManagement.java
index 6c39bb2..fa231a9 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/WorkerAdministrationManagement.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/WorkerAdministrationManagement.java
@@ -33,9 +33,11 @@ public class WorkerAdministrationManagement {
     private static final Logger LOG = 
LoggerFactory.getLogger(AdapterMasterManagement.class);
 
     private ConnectionWorkerContainerStorageImpl 
connectionWorkerContainerStorage;
+    private AdapterMasterManagement adapterMasterManagement;
 
     public WorkerAdministrationManagement() {
         this.connectionWorkerContainerStorage = new 
ConnectionWorkerContainerStorageImpl();
+        this.adapterMasterManagement = new AdapterMasterManagement();
     }
 
     public void register(ConnectWorkerContainer connectWorker) {
@@ -78,7 +80,7 @@ public class WorkerAdministrationManagement {
             LOG.info("Stored new connect worker: " + 
connectWorker.getEndpointUrl() + " in database");
         } else {
             try {
-                AdapterMasterManagement.startAllStreamAdapters(connectWorker);
+                
this.adapterMasterManagement.startAllStreamAdapters(connectWorker);
             } catch (AdapterException e) {
                 LOG.error("Could not start adapters on worker: " + 
connectWorker.getEndpointUrl());
             }
diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/WorkerRestClient.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/WorkerRestClient.java
index 747fdbb..892725c 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/WorkerRestClient.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/WorkerRestClient.java
@@ -18,19 +18,25 @@
 
 package org.apache.streampipes.connect.container.master.management;
 
+import com.google.gson.Gson;
 import org.apache.http.client.fluent.Request;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.mime.MultipartEntity;
 import org.apache.http.entity.mime.content.InputStreamBody;
 import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import 
org.apache.streampipes.connect.container.master.util.AdapterEncryptionService;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
 import org.apache.streampipes.model.connect.adapter.AdapterSetDescription;
 import org.apache.streampipes.model.connect.adapter.AdapterStreamDescription;
 import org.apache.streampipes.model.connect.grounding.ProtocolDescription;
 import org.apache.streampipes.model.runtime.RuntimeOptionsRequest;
 import org.apache.streampipes.model.runtime.RuntimeOptionsResponse;
+import org.apache.streampipes.model.util.Cloner;
+import org.apache.streampipes.serializers.json.GsonSerializer;
 import org.apache.streampipes.serializers.json.JacksonSerializer;
+import org.apache.streampipes.storage.api.IAdapterStorage;
 import org.apache.streampipes.storage.couchdb.impl.AdapterStorageImpl;
+import org.apache.streampipes.storage.management.StorageDispatcher;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,12 +52,16 @@ public class WorkerRestClient {
 
     private static final Logger logger = 
LoggerFactory.getLogger(WorkerRestClient.class);
 
+    public static void invokeStreamAdapter(String baseUrl, String adapterId) 
throws AdapterException {
+        invokeStreamAdapter(baseUrl, (AdapterStreamDescription) 
getAndDecryptAdapter(adapterId));
+    }
 
     public static void invokeStreamAdapter(String baseUrl, 
AdapterStreamDescription adapterStreamDescription) throws AdapterException {
 
         String url = baseUrl + "worker/stream/invoke";
 
         startAdapter(url, adapterStreamDescription);
+        updateStreamAdapterStatus(adapterStreamDescription.getId(), true);
     }
 
     public static void stopStreamAdapter(String baseUrl, 
AdapterStreamDescription adapterStreamDescription) throws AdapterException {
@@ -60,6 +70,7 @@ public class WorkerRestClient {
         AdapterDescription ad = getAdapterDescriptionById(new 
AdapterStorageImpl(), adapterStreamDescription.getUri());
 
         stopAdapter(adapterStreamDescription.getId(), ad, url);
+        updateStreamAdapterStatus(adapterStreamDescription.getId(), false);
     }
 
     public static void invokeSetAdapter(String baseUrl, AdapterSetDescription 
adapterSetDescription) throws AdapterException {
@@ -76,7 +87,7 @@ public class WorkerRestClient {
 
     public static void startAdapter(String url, AdapterDescription ad) throws 
AdapterException {
         try {
-            logger.info("Trying to start adpater on endpoint: " + url);
+            logger.info("Trying to start adapter on endpoint: " + url);
 
             // this ensures that all adapters have a valid uri otherwise the 
json-ld serializer fails
             if (ad.getUri() == null) {
@@ -168,65 +179,6 @@ public class WorkerRestClient {
         }
     }
 
-    public static InputStream getFileFromWorker(String baseUrl, String 
fileName) throws AdapterException {
-        String url = baseUrl + "worker/file/" + fileName;
-        logger.info("Trying to get file from endpoint: " + url);
-
-        try {
-            InputStream inputStream = Request.Get(url)
-                    .connectTimeout(1000)
-                    .socketTimeout(100000)
-                    .execute().returnContent().asStream();
-
-            logger.info("Got File from worker successfully from worker");
-            return inputStream;
-        } catch (IOException e) {
-            e.printStackTrace();
-            throw new AdapterException("Could not get file from endpoint " + 
url);
-        }
-    }
-
-    public static List<String> getAllFilePathsFromWorker(java.lang.String 
baseUrl) throws AdapterException {
-        String url = baseUrl + "worker/file";
-        logger.info("Trying to get file paths from endpoint: " + url);
-
-        try {
-            String stringResponse = Request.Get(url)
-                    .connectTimeout(1000)
-                    .socketTimeout(100000)
-                    .execute().returnContent().asString();
-            List<String> paths = 
JacksonSerializer.getObjectMapper().readValue(stringResponse, List.class);
-
-            logger.info("Got File paths successfully");
-            return paths;
-        } catch (IOException e) {
-            e.printStackTrace();
-            throw new AdapterException("Could not get file from endpoint " + 
url);
-        }
-    }
-
-    public static void deleteFileFromWorker(String baseUrl, String fileName) 
throws AdapterException {
-        String url = baseUrl + "worker/file/" + fileName;
-        logger.info("Trying to delete file from endpoint: " + url);
-
-        try {
-            int statusCode = Request.Delete(url)
-                    .connectTimeout(1000)
-                    .socketTimeout(100000)
-                    
.execute().returnResponse().getStatusLine().getStatusCode();
-
-            if (statusCode == 200) {
-                logger.info("Deleted File successfully");
-            } else {
-                throw new AdapterException("Could not delete file from 
endpoint " + url);
-            }
-
-        } catch (IOException e) {
-            e.printStackTrace();
-            throw new AdapterException("Could not delete file from endpoint " 
+ url);
-        }
-    }
-
     public static String getAdapterAssets(String baseUrl,  AdapterDescription 
ad) throws AdapterException {
         return getAssets(baseUrl + "worker/adapters", ad.getAppId());
     }
@@ -240,11 +192,10 @@ public class WorkerRestClient {
         logger.info("Trying to Assets from endpoint: " + url + " for adapter: 
" + appId);
 
         try {
-            String responseString = Request.Get(url)
+            return Request.Get(url)
                     .connectTimeout(1000)
                     .socketTimeout(100000)
                     .execute().returnContent().asString();
-            return responseString;
         } catch (IOException e) {
             logger.error(e.getMessage());
             throw new AdapterException("Could not get assets endpoint: " + url 
+ " for adapter: " + appId);
@@ -322,8 +273,27 @@ public class WorkerRestClient {
         }
     }
 
+    private static void updateStreamAdapterStatus(String adapterId,
+                                           boolean running) {
+        AdapterStreamDescription adapter = (AdapterStreamDescription) 
getAndDecryptAdapter(adapterId);
+        adapter.setRunning(running);
+        encryptAndUpdateAdapter(adapter);
+    }
 
+    private static void encryptAndUpdateAdapter(AdapterDescription adapter) {
+        Gson gson = GsonSerializer.getAdapterGsonBuilder().create();
+        System.out.println(gson.toJson(adapter));
+        AdapterDescription encryptedDescription = new 
AdapterEncryptionService(new Cloner().adapterDescription(adapter)).encrypt();
+        getAdapterStorage().updateAdapter(encryptedDescription);
+    }
 
+    private static AdapterDescription getAndDecryptAdapter(String adapterId) {
+        AdapterDescription adapter = getAdapterStorage().getAdapter(adapterId);
+        return new AdapterEncryptionService(new 
Cloner().adapterDescription(adapter)).decrypt();
+    }
 
+    private static IAdapterStorage getAdapterStorage() {
+        return StorageDispatcher.INSTANCE.getNoSqlStore().getAdapterStorage();
+    }
 }
 
diff --git 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AbstractAdapterResource.java
similarity index 65%
copy from 
streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
copy to 
streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AbstractAdapterResource.java
index 6909489..ffe445a 100644
--- 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AbstractAdapterResource.java
@@ -15,22 +15,17 @@
  * limitations under the License.
  *
  */
+package org.apache.streampipes.connect.container.master.rest;
 
-package org.apache.streampipes.storage.api;
+import org.apache.streampipes.connect.rest.AbstractContainerResource;
 
-import org.apache.streampipes.model.connect.adapter.AdapterDescription;
+import java.util.function.Supplier;
 
-import java.util.List;
+public class AbstractAdapterResource<T> extends AbstractContainerResource {
 
-public interface IAdapterStorage {
+  protected T managementService;
 
-    List<AdapterDescription> getAllAdapters();
-
-    void storeAdapter(AdapterDescription adapter);
-
-    void updateAdapter(AdapterDescription adapter);
-
-    AdapterDescription getAdapter(String adapterId);
-
-    void deleteAdapter(String adapterId);
+  public AbstractAdapterResource(Supplier<T> managementServiceSupplier) {
+    this.managementService = managementServiceSupplier.get();
+  }
 }
diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AdapterResource.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AdapterResource.java
index 4530f71..8f49202 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AdapterResource.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/AdapterResource.java
@@ -21,12 +21,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.AdapterMasterManagement;
 import org.apache.streampipes.connect.container.master.management.Utils;
-import org.apache.streampipes.connect.rest.AbstractContainerResource;
 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.apache.streampipes.storage.couchdb.impl.AdapterStorageImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,32 +34,26 @@ import javax.ws.rs.core.Response;
 import java.util.List;
 
 @Path("/v2/connect/{username}/master/adapters")
-public class AdapterResource extends AbstractContainerResource {
+public class AdapterResource extends 
AbstractAdapterResource<AdapterMasterManagement> {
 
     private Logger LOG = LoggerFactory.getLogger(AdapterResource.class);
 
-    private AdapterMasterManagement adapterMasterManagement;
-
-
     public AdapterResource() {
-        this.adapterMasterManagement = new AdapterMasterManagement();
+        super(AdapterMasterManagement::new);
     }
 
     @POST
     @JacksonSerialized
     @Produces(MediaType.APPLICATION_JSON)
-    public Response addAdapter(AdapterDescription adapterDescription, 
@PathParam("username") String userName) {
+    public Response addAdapter(AdapterDescription adapterDescription,
+                               @PathParam("username") String username) {
 
         String adapterId;
-        LOG.info("User: " + userName + " starts adapter " + 
adapterDescription.getAdapterId());
-
-
-        String workerUrl = new Utils().getWorkerUrl(adapterDescription);
-        String newUrl = Utils.addUserNameToApi(workerUrl, userName);
+        LOG.info("User: " + username + " starts adapter " + 
adapterDescription.getAdapterId());
 
         try {
-            adapterId = adapterMasterManagement.addAdapter(adapterDescription, 
newUrl, new
-                    AdapterStorageImpl(), userName);
+            String workerUrl = getModifiedWorkerUrl(adapterDescription, 
username);
+            adapterId = managementService.addAdapter(adapterDescription, 
workerUrl, username);
         } catch (AdapterException e) {
             LOG.error("Error while starting adapter with id " + 
adapterDescription.getAppId(), e);
             return ok(Notifications.error(e.getMessage()));
@@ -75,46 +67,73 @@ public class AdapterResource extends 
AbstractContainerResource {
     @JacksonSerialized
     @Path("/{id}")
     @Produces(MediaType.APPLICATION_JSON)
-    public Response getAdapter(@PathParam("id") String id, 
@PathParam("username") String userName) {
+    public Response getAdapter(@PathParam("id") String adapterId) {
 
         try {
-            AdapterDescription adapterDescription = 
adapterMasterManagement.getAdapter(id, new AdapterStorageImpl());
+            AdapterDescription adapterDescription = 
getAdapterDescription(adapterId);
 
             return ok(adapterDescription);
         } catch (AdapterException e) {
-            LOG.error("Error while getting adapter with id " + id, e);
+            LOG.error("Error while getting adapter with id " + adapterId, e);
             return fail();
         }
+    }
 
+    @POST
+    @JacksonSerialized
+    @Path("/{id}/stop")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response stopAdapter(@PathParam("id") String adapterId,
+                                @PathParam("username") String username) {
+        try {
+            String workerUrl = getModifiedWorkerUrl(adapterId, username);
+            managementService.stopStreamAdapter(adapterId, workerUrl);
+            return ok(Notifications.success("Adapter started"));
+        } catch (AdapterException e) {
+            LOG.error("Could not stop adapter with id " +adapterId, e);
+            return ok(Notifications.error(e.getMessage()));
+        }
     }
 
+    @POST
+    @JacksonSerialized
+    @Path("/{id}/start")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response startAdapter(@PathParam("id") String adapterId,
+                                @PathParam("username") String username) {
+        try {
+            String workerUrl = getModifiedWorkerUrl(adapterId, username);
+            managementService.startStreamAdapter(adapterId, workerUrl);
+            return ok(Notifications.success("Adapter stopped"));
+        } catch (AdapterException e) {
+            LOG.error("Could not start adapter with id " +adapterId, e);
+            return ok(Notifications.error(e.getMessage()));
+        }
+    }
 
     @DELETE
     @JacksonSerialized
     @Path("/{id}")
     @Produces(MediaType.APPLICATION_JSON)
-    public Response deleteAdapter(@PathParam("id") String id, 
@PathParam("username") String userName) {
+    public Response deleteAdapter(@PathParam("id") String adapterId,
+                                  @PathParam("username") String username) {
 
         try {
-
-            AdapterDescription adapterDescription = 
adapterMasterManagement.getAdapter(id, new AdapterStorageImpl());
-
-            String workerUrl = new 
Utils().getWorkerUrlById(adapterDescription.getAppId());
-            String newUrl = Utils.addUserNameToApi(workerUrl, userName);
-            adapterMasterManagement.deleteAdapter(id, newUrl);
-            return ok(true);
+            String workerUrl = getModifiedWorkerUrl(adapterId, username);
+            managementService.deleteAdapter(adapterId, workerUrl);
+            return ok(Notifications.success("Adapter deleted."));
         } catch (AdapterException e) {
-            LOG.error("Error while deleting adapter with id " + id, e);
-            return fail();
+            LOG.error("Error while deleting adapter with id " + adapterId, e);
+            return ok(Notifications.error(e.getMessage()));
         }
     }
 
     @GET
     @JacksonSerialized
     @Produces(MediaType.APPLICATION_JSON)
-    public Response getAllAdapters(@PathParam("username") String userName) {
+    public Response getAllAdapters() {
         try {
-            List<AdapterDescription> allAdapterDescription = 
adapterMasterManagement.getAllAdapters(new AdapterStorageImpl());
+            List<AdapterDescription> allAdapterDescription = 
managementService.getAllAdapters();
             AdapterDescriptionList result = new AdapterDescriptionList();
             result.setList(allAdapterDescription);
 
@@ -123,11 +142,21 @@ public class AdapterResource extends 
AbstractContainerResource {
             LOG.error("Error while getting all adapters", e);
             return fail();
         }
+    }
 
+    private AdapterDescription getAdapterDescription(String adapterId) throws 
AdapterException {
+        return managementService.getAdapter(adapterId);
     }
 
-    public void setAdapterMasterManagement(AdapterMasterManagement 
adapterMasterManagement) {
-        this.adapterMasterManagement = adapterMasterManagement;
+    private String getModifiedWorkerUrl(String adapterId,
+                                        String username) throws 
AdapterException {
+        AdapterDescription adapterDescription = 
getAdapterDescription(adapterId);
+        return getModifiedWorkerUrl(adapterDescription, username);
     }
 
+    private String getModifiedWorkerUrl(AdapterDescription adapterDescription,
+                                        String username) throws 
AdapterException {
+        String workerUrl = new 
Utils().getWorkerUrlById(adapterDescription.getAppId());
+        return Utils.addUserNameToApi(workerUrl, username);
+    }
 }
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 527fdea..a601c17 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,7 +20,6 @@ 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.rest.AbstractContainerResource;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
 import org.apache.streampipes.model.connect.adapter.AdapterDescriptionList;
 import org.apache.streampipes.model.message.Notifications;
@@ -33,16 +32,12 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 @Path("/v2/connect/{username}/master/adapters/template")
-public class AdapterTemplateResource extends AbstractContainerResource {
+public class AdapterTemplateResource extends 
AbstractAdapterResource<AdapterTemplateMasterManagement> {
 
     private Logger logger = 
LoggerFactory.getLogger(AdapterTemplateResource.class);
 
-    private AdapterTemplateMasterManagement adapterTemplateMasterManagement;
-
-    private String connectContainerEndpoint;
-
     public AdapterTemplateResource() {
-        this.adapterTemplateMasterManagement = new 
AdapterTemplateMasterManagement();
+        super(AdapterTemplateMasterManagement::new);
     }
 
     @POST
@@ -50,7 +45,7 @@ public class AdapterTemplateResource extends 
AbstractContainerResource {
     @Produces(MediaType.APPLICATION_JSON)
     public Response addAdapterTemplate(AdapterDescription adapterDescription, 
@PathParam("username") String userName) {
         try {
-            String adapterTemplateId = 
adapterTemplateMasterManagement.addAdapterTemplate(adapterDescription);
+            String adapterTemplateId = 
managementService.addAdapterTemplate(adapterDescription);
             logger.info("User: " + userName + " added adapter as adapter 
template");
 
             return ok(Notifications.success(adapterTemplateId));
@@ -66,7 +61,7 @@ public class AdapterTemplateResource extends 
AbstractContainerResource {
     @Produces(MediaType.APPLICATION_JSON)
     public Response getAllAdapterTemplates(@PathParam("username") String 
userName) {
         try {
-            AdapterDescriptionList result = 
adapterTemplateMasterManagement.getAllAdapterTemplates();
+            AdapterDescriptionList result = 
managementService.getAllAdapterTemplates();
 
             return ok(result);
         } catch (AdapterException e) {
@@ -83,15 +78,11 @@ public class AdapterTemplateResource extends 
AbstractContainerResource {
     public Response deleteAdapter(@PathParam("id") String id, 
@PathParam("username") String userName) {
 
         try {
-            adapterTemplateMasterManagement.deleteAdapterTemplates(id);
+            managementService.deleteAdapterTemplates(id);
             return ok(true);
         } catch (AdapterException e) {
             logger.error("Error while deleting adapter with id " + id, e);
             return fail();
         }
     }
-
-    public void 
setAdapterTemplateMasterManagement(AdapterTemplateMasterManagement 
adapterTemplateMasterManagement) {
-        this.adapterTemplateMasterManagement = adapterTemplateMasterManagement;
-    }
 }
diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/DescriptionResource.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/DescriptionResource.java
index 7c60314..0105f73 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/DescriptionResource.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/DescriptionResource.java
@@ -20,7 +20,6 @@ package org.apache.streampipes.connect.container.master.rest;
 import org.apache.streampipes.connect.adapter.exception.AdapterException;
 import 
org.apache.streampipes.connect.container.master.management.DescriptionManagement;
 import org.apache.streampipes.connect.container.master.management.Utils;
-import org.apache.streampipes.connect.rest.AbstractContainerResource;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
 import org.apache.streampipes.model.connect.adapter.AdapterDescriptionList;
 import org.apache.streampipes.model.connect.grounding.FormatDescriptionList;
@@ -39,18 +38,12 @@ import javax.ws.rs.core.Response;
 import java.util.Optional;
 
 @Path("/v2/connect/{username}/master/description")
-public class DescriptionResource extends AbstractContainerResource {
+public class DescriptionResource extends 
AbstractAdapterResource<DescriptionManagement> {
 
-    private Logger logger = LoggerFactory.getLogger(DescriptionResource.class);
-
-    private DescriptionManagement descriptionManagement;
+    private static final Logger LOG = 
LoggerFactory.getLogger(DescriptionResource.class);
 
     public DescriptionResource() {
-        descriptionManagement = new DescriptionManagement();
-    }
-
-    public DescriptionResource(DescriptionManagement descriptionManagement) {
-        this.descriptionManagement = descriptionManagement;
+        super(DescriptionManagement::new);
     }
 
     @GET
@@ -58,7 +51,7 @@ public class DescriptionResource extends 
AbstractContainerResource {
     @Path("/formats")
     @Produces(MediaType.APPLICATION_JSON)
     public Response getFormats() {
-        FormatDescriptionList result = descriptionManagement.getFormats();
+        FormatDescriptionList result = managementService.getFormats();
 
         return ok(result);
     }
@@ -68,7 +61,7 @@ public class DescriptionResource extends 
AbstractContainerResource {
     @Path("/protocols")
     @Produces(MediaType.APPLICATION_JSON)
     public Response getProtocols() {
-        ProtocolDescriptionList result = descriptionManagement.getProtocols();
+        ProtocolDescriptionList result = managementService.getProtocols();
 
         return ok(result);
     }
@@ -78,15 +71,11 @@ public class DescriptionResource extends 
AbstractContainerResource {
     @Path("/adapters")
     @Produces(MediaType.APPLICATION_JSON)
     public Response getAdapters() {
-        AdapterDescriptionList result = descriptionManagement.getAdapters();
+        AdapterDescriptionList result = managementService.getAdapters();
 
         return ok(result);
     }
 
-    public void setDescriptionManagement(DescriptionManagement 
descriptionManagement) {
-        this.descriptionManagement = descriptionManagement;
-    }
-
     @GET
     @Path("/{id}/assets")
     @Produces("application/zip")
@@ -94,32 +83,32 @@ public class DescriptionResource extends 
AbstractContainerResource {
         try {
             String result = null;
 
-            Optional<AdapterDescription> adapterDescriptionOptional = 
descriptionManagement.getAdapter(id);
+            Optional<AdapterDescription> adapterDescriptionOptional = 
managementService.getAdapter(id);
             if (adapterDescriptionOptional.isPresent()) {
                 AdapterDescription adapterDescription = 
adapterDescriptionOptional.get();
                 String workerUrl = new 
Utils().getWorkerUrl(adapterDescription);
                 String newUrl = Utils.addUserNameToApi(workerUrl, userName);
 
-                result = 
descriptionManagement.getAdapterAssets(adapterDescription, newUrl);
+                result = 
managementService.getAdapterAssets(adapterDescription, newUrl);
             }
 
-            Optional<ProtocolDescription> protocolDescriptionOptional  = 
descriptionManagement.getProtocol(id);
+            Optional<ProtocolDescription> protocolDescriptionOptional  = 
managementService.getProtocol(id);
             if (protocolDescriptionOptional.isPresent()) {
                 ProtocolDescription protocolDescription = 
protocolDescriptionOptional.get();
                 String workerUrl = new 
Utils().getWorkerUrl(protocolDescription);
                 String newUrl = Utils.addUserNameToApi(workerUrl, userName);
 
-                result = 
descriptionManagement.getProtocolAssets(protocolDescription, newUrl);
+                result = 
managementService.getProtocolAssets(protocolDescription, newUrl);
             }
 
             if (result == null) {
-                logger.error("Not found adapter with id " + id);
+                LOG.error("Not found adapter with id " + id);
                 return fail();
             } else {
                 return ok(result);
             }
         } catch (AdapterException e) {
-            logger.error("Not found adapter with id " + id, e);
+            LOG.error("Not found adapter with id " + id, e);
             return fail();
         }
     }
@@ -132,32 +121,32 @@ public class DescriptionResource extends 
AbstractContainerResource {
 
             byte[] result = null;
 
-            Optional<AdapterDescription> adapterDescriptionOptional = 
descriptionManagement.getAdapter(id);
+            Optional<AdapterDescription> adapterDescriptionOptional = 
managementService.getAdapter(id);
             if (adapterDescriptionOptional.isPresent()) {
                 AdapterDescription adapterDescription = 
adapterDescriptionOptional.get();
                 String workerUrl = new 
Utils().getWorkerUrl(adapterDescription);
                 String newUrl = Utils.addUserNameToApi(workerUrl, userName);
 
-                result = 
descriptionManagement.getAdapterIconAsset(adapterDescription, newUrl);
+                result = 
managementService.getAdapterIconAsset(adapterDescription, newUrl);
             }
 
-            Optional<ProtocolDescription> protocolDescriptionOptional  = 
descriptionManagement.getProtocol(id);
+            Optional<ProtocolDescription> protocolDescriptionOptional  = 
managementService.getProtocol(id);
             if (protocolDescriptionOptional.isPresent()) {
                 ProtocolDescription protocolDescription = 
protocolDescriptionOptional.get();
                 String workerUrl = new 
Utils().getWorkerUrl(protocolDescription);
                 String newUrl = Utils.addUserNameToApi(workerUrl, userName);
 
-                result = 
descriptionManagement.getProtocolIconAsset(protocolDescription, newUrl);
+                result = 
managementService.getProtocolIconAsset(protocolDescription, newUrl);
             }
 
             if (result == null) {
-                logger.error("Not found adapter with id " + id);
+                LOG.error("Not found adapter with id " + id);
                 return fail();
             } else {
                 return ok(result);
             }
         } catch (AdapterException e) {
-            logger.error("Not found adapter with id " + id);
+            LOG.error("Not found adapter with id " + id);
             return fail();
         }
     }
@@ -169,32 +158,32 @@ public class DescriptionResource extends 
AbstractContainerResource {
         try {
             String result = null;
 
-            Optional<AdapterDescription> adapterDescriptionOptional = 
descriptionManagement.getAdapter(id);
+            Optional<AdapterDescription> adapterDescriptionOptional = 
managementService.getAdapter(id);
             if (adapterDescriptionOptional.isPresent()) {
                 AdapterDescription adapterDescription = 
adapterDescriptionOptional.get();
                 String workerUrl = new 
Utils().getWorkerUrl(adapterDescription);
                 String newUrl = Utils.addUserNameToApi(workerUrl, userName);
 
-                result =  
descriptionManagement.getAdapterDocumentationAsset(adapterDescription, newUrl);
+                result =  
managementService.getAdapterDocumentationAsset(adapterDescription, newUrl);
             }
 
-            Optional<ProtocolDescription> protocolDescriptionOptional  = 
descriptionManagement.getProtocol(id);
+            Optional<ProtocolDescription> protocolDescriptionOptional  = 
managementService.getProtocol(id);
             if (protocolDescriptionOptional.isPresent()) {
                 ProtocolDescription protocolDescription = 
protocolDescriptionOptional.get();
                 String workerUrl = new 
Utils().getWorkerUrl(protocolDescription);
                 String newUrl = Utils.addUserNameToApi(workerUrl, userName);
 
-                result =  
descriptionManagement.getProtocolDocumentationAsset(protocolDescription, 
newUrl);
+                result =  
managementService.getProtocolDocumentationAsset(protocolDescription, newUrl);
             }
 
             if (result == null) {
-                logger.error("Not found adapter with id " + id);
+                LOG.error("Not found adapter with id " + id);
                 return fail();
             } else {
                 return ok(result);
             }
         } catch (AdapterException e) {
-            logger.error("Not found adapter with id " + id, e);
+            LOG.error("Not found adapter with id " + id, e);
             return fail();
         }
     }
diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/GuessResource.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/GuessResource.java
index 01ec4b6..1fe92d6 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/GuessResource.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/GuessResource.java
@@ -21,32 +21,28 @@ package 
org.apache.streampipes.connect.container.master.rest;
 import org.apache.streampipes.connect.adapter.exception.ParseException;
 import org.apache.streampipes.connect.adapter.exception.WorkerAdapterException;
 import 
org.apache.streampipes.connect.container.master.management.GuessManagement;
-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.guess.GuessSchema;
+import org.apache.streampipes.model.message.Notifications;
 import org.apache.streampipes.rest.shared.annotation.JacksonSerialized;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.ws.rs.*;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 
 @Path("/v2/connect/{username}/master/guess")
-public class GuessResource extends AbstractContainerResource {
-
-  private static final Logger logger = 
LoggerFactory.getLogger(GuessResource.class);
+public class GuessResource extends AbstractAdapterResource<GuessManagement> {
 
-  private GuessManagement guessManagement;
+  private static final Logger LOG = 
LoggerFactory.getLogger(GuessResource.class);
 
   public GuessResource() {
-    this.guessManagement = new GuessManagement();
-  }
-
-  public GuessResource(GuessManagement guessManagement) {
-    this.guessManagement = guessManagement;
+    super(GuessManagement::new);
   }
 
   @POST
@@ -56,24 +52,18 @@ public class GuessResource extends 
AbstractContainerResource {
   public Response guessSchema(AdapterDescription adapterDescription, 
@PathParam("username") String userName) {
 
       try {
-          GuessSchema result = guessManagement.guessSchema(adapterDescription);
+          GuessSchema result = 
managementService.guessSchema(adapterDescription);
 
           return ok(result);
       } catch (ParseException e) {
-          logger.error("Error while parsing events: ", e);
+          LOG.error("Error while parsing events: ", e);
           return error(Notifications.error(e.getMessage()));
       } catch (WorkerAdapterException e) {
           return error(e.getContent());
       } catch (Exception e) {
-          logger.error("Error while guess schema for AdapterDescription: ", e);
+          LOG.error("Error while guess schema for AdapterDescription: ", e);
           return error(Notifications.error(e.getMessage()));
       }
-
-  }
-
-  public void setGuessManagement(GuessManagement guessManagement) {
-    this.guessManagement = guessManagement;
   }
-
 }
 
diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/RuntimeResolvableResource.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/RuntimeResolvableResource.java
index a543192..1cc2d75 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/RuntimeResolvableResource.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/RuntimeResolvableResource.java
@@ -21,7 +21,6 @@ package org.apache.streampipes.connect.container.master.rest;
 import org.apache.streampipes.connect.adapter.exception.AdapterException;
 import 
org.apache.streampipes.connect.container.master.management.WorkerAdministrationManagement;
 import 
org.apache.streampipes.connect.container.master.management.WorkerRestClient;
-import org.apache.streampipes.connect.rest.AbstractContainerResource;
 import org.apache.streampipes.model.runtime.RuntimeOptionsRequest;
 import org.apache.streampipes.model.runtime.RuntimeOptionsResponse;
 import org.apache.streampipes.rest.shared.annotation.JacksonSerialized;
@@ -31,13 +30,12 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 @Path("/v2/connect/{username}/master/resolvable")
-public class RuntimeResolvableResource extends AbstractContainerResource {
+public class RuntimeResolvableResource extends 
AbstractAdapterResource<WorkerAdministrationManagement> {
 
     private static final String SP_NS =  
"https://streampipes.org/vocabulary/v1/";;
-    private WorkerAdministrationManagement workerAdministrationManagement;
 
     public RuntimeResolvableResource() {
-        this.workerAdministrationManagement = new 
WorkerAdministrationManagement();
+        super(WorkerAdministrationManagement::new);
     }
 
     @POST
@@ -53,7 +51,7 @@ public class RuntimeResolvableResource extends 
AbstractContainerResource {
 //        ResolvesContainerProvidedOptions runtimeResolvableOptions = 
RuntimeResovable.getRuntimeResolvableFormat(elementId);
 
         String id = elementId.replaceAll("sp:", SP_NS);
-        String workerEndpoint = 
this.workerAdministrationManagement.getWorkerUrl(id);
+        String workerEndpoint = managementService.getWorkerUrl(id);
 
         try {
 
diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/SourcesResource.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/SourcesResource.java
index bd3d02a..bd73114 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/SourcesResource.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/SourcesResource.java
@@ -20,7 +20,6 @@ package org.apache.streampipes.connect.container.master.rest;
 
 import org.apache.streampipes.connect.adapter.exception.AdapterException;
 import 
org.apache.streampipes.connect.container.master.management.SourcesManagement;
-import org.apache.streampipes.connect.rest.AbstractContainerResource;
 import org.apache.streampipes.model.SpDataSet;
 import org.apache.streampipes.model.message.Notifications;
 import org.apache.streampipes.rest.shared.annotation.GsonWithIds;
@@ -33,15 +32,12 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 @Path("/v2/connect/{username}/master/sources")
-public class SourcesResource extends AbstractContainerResource {
+public class SourcesResource extends 
AbstractAdapterResource<SourcesManagement> {
 
-    private Logger logger = LoggerFactory.getLogger(SourcesResource.class);
-
-
-    private SourcesManagement sourcesManagement;
+    private static final Logger LOG = 
LoggerFactory.getLogger(SourcesResource.class);
 
     public SourcesResource() {
-        this.sourcesManagement = new SourcesManagement();
+        super(SourcesManagement::new);
     }
 
     @GET
@@ -50,25 +46,23 @@ public class SourcesResource extends 
AbstractContainerResource {
     public Response getAllAdaptersInstallDescription(@PathParam("username") 
String username) {
 
         try {
-            String resultingJson = 
this.sourcesManagement.getAllAdaptersInstallDescription(username);
+            String resultingJson = 
managementService.getAllAdaptersInstallDescription(username);
             return ok(resultingJson);
         } catch (AdapterException e) {
-            logger.error("Error while getting all adapter descriptions", e);
+            LOG.error("Error while getting all adapter descriptions", e);
             return fail();
         }
     }
 
-
-
     @GET
     @Path("/{id}")
     @JacksonSerialized
     @Produces(MediaType.APPLICATION_JSON)
     public Response getAdapterDataSource(@PathParam("id") String id) {
         try {
-            return ok(this.sourcesManagement.getAdapterDataStream(id));
+            return ok(managementService.getAdapterDataStream(id));
         } catch (AdapterException e) {
-            logger.error("Error while retrieving DataSourceDescription with 
id: " + id);
+            LOG.error("Error while retrieving DataSourceDescription with id: " 
+ id);
             return fail();
         }
     }
@@ -84,9 +78,9 @@ public class SourcesResource extends 
AbstractContainerResource {
         String responseMessage = "Instance of data set " + dataSet.getUri() + 
" successfully started";
 
         try {
-            this.sourcesManagement.addAdapter(elementId,  dataSet, username);
+            managementService.addAdapter(elementId,  dataSet, username);
         } catch (AdapterException e) {
-            logger.error("Could not set data set instance: " + 
dataSet.getUri(), e);
+            LOG.error("Could not set data set instance: " + dataSet.getUri(), 
e);
             return ok(Notifications.error("Could not set data set instance: " 
+ dataSet.getUri()));
         }
 
@@ -103,17 +97,12 @@ public class SourcesResource extends 
AbstractContainerResource {
 //        String newUrl = Utils.addUserNameToApi(workerUrl, username);
 
         try {
-            this.sourcesManagement.detachAdapter(elementId, runningInstanceId, 
username);
+            managementService.detachAdapter(elementId, runningInstanceId, 
username);
         } catch (AdapterException e) {
-            logger.error("Could not set set id "+ elementId  + " with instance 
id: "+ runningInstanceId, e);
+            LOG.error("Could not set set id "+ elementId  + " with instance 
id: "+ runningInstanceId, e);
             return fail();
         }
 
-
         return ok(Notifications.success(responseMessage));
     }
-
-    public void setSourcesManagement(SourcesManagement sourcesManagement) {
-        this.sourcesManagement = sourcesManagement;
-    }
 }
diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/UnitResource.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/UnitResource.java
index c714960..fe4037e 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/UnitResource.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/UnitResource.java
@@ -18,12 +18,11 @@
 
 package org.apache.streampipes.connect.container.master.rest;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.streampipes.connect.adapter.exception.AdapterException;
 import 
org.apache.streampipes.connect.container.master.management.UnitMasterManagement;
-import org.apache.streampipes.connect.rest.AbstractContainerResource;
 import org.apache.streampipes.model.connect.unit.UnitDescription;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.POST;
@@ -33,14 +32,12 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 @Path("/v2/connect/{username}/master/unit")
-public class UnitResource extends AbstractContainerResource {
+public class UnitResource extends 
AbstractAdapterResource<UnitMasterManagement> {
 
     private static final Logger logger = 
LoggerFactory.getLogger(UnitResource.class);
 
-    private UnitMasterManagement unitManagement;
-
     public UnitResource() {
-        unitManagement = new UnitMasterManagement();
+        super(UnitMasterManagement::new);
     }
 
     @POST
@@ -48,7 +45,7 @@ public class UnitResource extends AbstractContainerResource {
     @Produces(MediaType.APPLICATION_JSON)
     public Response getFittingUnits(UnitDescription unitDescription) {
         try {
-            String resultingJson = 
this.unitManagement.getFittingUnits(unitDescription);
+            String resultingJson = 
managementService.getFittingUnits(unitDescription);
             return ok(resultingJson);
         } catch (AdapterException e) {
             logger.error("Error while getting all adapter descriptions", e);
@@ -56,8 +53,4 @@ public class UnitResource extends AbstractContainerResource {
         }
     }
 
-    public void setUnitMasterManagement(UnitMasterManagement 
unitMasterManagement) {
-        this.unitManagement = unitMasterManagement;
-    }
-
 }
diff --git 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/WelcomePageMaster.java
 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/WelcomePageMaster.java
index c99847c..e0bc80b 100644
--- 
a/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/WelcomePageMaster.java
+++ 
b/streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/rest/WelcomePageMaster.java
@@ -19,39 +19,31 @@
 package org.apache.streampipes.connect.container.master.rest;
 
 
-import org.rendersnake.HtmlCanvas;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.streampipes.connect.adapter.GroundingService;
 import org.apache.streampipes.connect.adapter.exception.AdapterException;
 import 
org.apache.streampipes.connect.container.master.management.AdapterMasterManagement;
-import org.apache.streampipes.connect.rest.AbstractContainerResource;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
-import org.apache.streampipes.storage.couchdb.impl.AdapterStorageImpl;
 import org.apache.streampipes.storage.couchdb.utils.CouchDbConfig;
+import org.rendersnake.HtmlCanvas;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import java.io.IOException;
-import java.util.List;
 
 
 @Path("/v2/connect")
-public class WelcomePageMaster extends AbstractContainerResource {
-
-       private Logger logger = 
LoggerFactory.getLogger(WelcomePageMaster.class);
+public class WelcomePageMaster extends 
AbstractAdapterResource<AdapterMasterManagement> {
 
-       private AdapterMasterManagement adapterMasterManagement;
+       private Logger LOG = LoggerFactory.getLogger(WelcomePageMaster.class);
 
        public WelcomePageMaster() {
-               this.adapterMasterManagement = new AdapterMasterManagement();
+               super(AdapterMasterManagement::new);
        }
 
-       public WelcomePageMaster(AdapterMasterManagement 
adapterMasterManagement) {
-               this.adapterMasterManagement = adapterMasterManagement;
-       }
        @GET
        @Produces(MediaType.TEXT_HTML)
        public String getWelcomePageHtml() {
@@ -71,37 +63,27 @@ public class WelcomePageMaster extends 
AbstractContainerResource {
                                        .h2().write("All Running 
Adapters")._h2()
                                        .ol();
 
-                       tmp = getAllRunningAdapters(tmp);
+                       getAllRunningAdapters(tmp);
 
                        html = tmp._ol()
                                        ._body();
                } catch (IOException e) {
-                       logger.error("Error in SP Connect Master Container: ", 
e);
+                       LOG.error("Error in SP Connect Master Container: ", e);
                }
 
                return html.toHtml();
        }
 
-       private HtmlCanvas getAllRunningAdapters(HtmlCanvas canvas) throws 
IOException {
+       private void getAllRunningAdapters(HtmlCanvas canvas) throws 
IOException {
 
-               List<AdapterDescription> allAdapterDescriptions = null;
                try {
-                       allAdapterDescriptions = 
this.adapterMasterManagement.getAllAdapters(new AdapterStorageImpl());
+                       for (AdapterDescription ad : 
managementService.getAllAdapters()) {
+                               canvas.li().write(ad.getAdapterId())._li();
+                               canvas.ul().li().write("Kafka Topic: " + 
GroundingService.extractTopic(ad))._li()._ul();
+                       }
                } catch (AdapterException e) {
-                       logger.error("Could not connect to couchdb on URL: " + 
CouchDbConfig.INSTANCE.getHost(), e);
+                       LOG.error("Could not connect to couchdb on URL: " + 
CouchDbConfig.INSTANCE.getHost(), e);
                        canvas.li().write("Error while connecting to CouchDB on 
Host: " + CouchDbConfig.INSTANCE.getHost())._li();
-                       return canvas;
-               }
-
-               for (AdapterDescription ad : allAdapterDescriptions) {
-                       canvas.li().write(ad.getAdapterId())._li();
-                       canvas.ul().li().write("Kafka Topic: " + 
GroundingService.extractTopic(ad))._li()._ul();
                }
-
-               return canvas;
-       }
-
-       public void setAdapterMasterManagement(AdapterMasterManagement 
adapterMasterManagement) {
-               this.adapterMasterManagement = adapterMasterManagement;
        }
 }
diff --git 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/AdapterMasterManagementTest.java
 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/AdapterMasterManagementTest.java
similarity index 86%
rename from 
streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/AdapterMasterManagementTest.java
rename to 
streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/AdapterMasterManagementTest.java
index e50ebc5..b39252a 100644
--- 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/AdapterMasterManagementTest.java
+++ 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/AdapterMasterManagementTest.java
@@ -16,22 +16,21 @@
  *
  */
 
-package org.apache.streampipes.connect.container.master;
+package org.apache.streampipes.connect.container.master.management;
 
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.junit.Test;
 import org.apache.streampipes.connect.adapter.exception.AdapterException;
-import 
org.apache.streampipes.connect.container.master.management.AdapterMasterManagement;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
 import 
org.apache.streampipes.model.connect.adapter.GenericAdapterStreamDescription;
 import org.apache.streampipes.storage.couchdb.impl.AdapterStorageImpl;
+import org.junit.Test;
 
 import java.util.Arrays;
 import java.util.List;
 
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 public class AdapterMasterManagementTest {
 
     @Test(expected = AdapterException.class)
@@ -39,9 +38,9 @@ public class AdapterMasterManagementTest {
         AdapterStorageImpl adapterStorage = mock(AdapterStorageImpl.class);
         when(adapterStorage.getAllAdapters()).thenReturn(null);
 
-        AdapterMasterManagement adapterMasterManagement = new 
AdapterMasterManagement();
+        AdapterMasterManagement adapterMasterManagement = new 
AdapterMasterManagement(adapterStorage);
 
-        adapterMasterManagement.getAdapter("id2", adapterStorage);
+        adapterMasterManagement.getAdapter("id2");
     }
 
     @Test(expected = AdapterException.class)
@@ -51,9 +50,9 @@ public class AdapterMasterManagementTest {
         when(adapterStorage.getAllAdapters()).thenReturn(adapterDescriptions);
 
         String id = "http://t.id";;
-        AdapterMasterManagement adapterMasterManagement = new 
AdapterMasterManagement();
+        AdapterMasterManagement adapterMasterManagement = new 
AdapterMasterManagement(adapterStorage);
 
-        adapterMasterManagement.getAdapter("id2", adapterStorage);
+        adapterMasterManagement.getAdapter("id2");
     }
 
     @Test
@@ -62,9 +61,9 @@ public class AdapterMasterManagementTest {
         AdapterStorageImpl adapterStorage = mock(AdapterStorageImpl.class);
         when(adapterStorage.getAllAdapters()).thenReturn(adapterDescriptions);
 
-        AdapterMasterManagement adapterMasterManagement = new 
AdapterMasterManagement();
+        AdapterMasterManagement adapterMasterManagement = new 
AdapterMasterManagement(adapterStorage);
 
-        List<AdapterDescription> result = 
adapterMasterManagement.getAllAdapters(adapterStorage);
+        List<AdapterDescription> result = 
adapterMasterManagement.getAllAdapters();
 
         assertEquals(1, result.size());
         assertEquals(GenericAdapterStreamDescription.ID, 
result.get(0).getUri());
@@ -75,9 +74,9 @@ public class AdapterMasterManagementTest {
         AdapterStorageImpl adapterStorage = mock(AdapterStorageImpl.class);
         when(adapterStorage.getAllAdapters()).thenReturn(null);
 
-        AdapterMasterManagement adapterMasterManagement = new 
AdapterMasterManagement();
+        AdapterMasterManagement adapterMasterManagement = new 
AdapterMasterManagement(adapterStorage);
 
-        adapterMasterManagement.getAllAdapters(adapterStorage);
+        adapterMasterManagement.getAllAdapters();
 
     }
-}
\ No newline at end of file
+}
diff --git 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/AdapterTemplateMasterManagementTest.java
 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/AdapterTemplateMasterManagementTest.java
similarity index 99%
rename from 
streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/AdapterTemplateMasterManagementTest.java
rename to 
streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/AdapterTemplateMasterManagementTest.java
index be017c8..1081104 100644
--- 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/AdapterTemplateMasterManagementTest.java
+++ 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/AdapterTemplateMasterManagementTest.java
@@ -18,20 +18,20 @@
 
 package org.apache.streampipes.connect.container.master.management;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.junit.Test;
 import org.apache.streampipes.connect.adapter.exception.AdapterException;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
 import org.apache.streampipes.model.connect.adapter.AdapterDescriptionList;
 import 
org.apache.streampipes.model.connect.adapter.GenericAdapterStreamDescription;
 import org.apache.streampipes.storage.couchdb.impl.AdapterTemplateStorageImpl;
+import org.junit.Test;
 
 import java.util.Arrays;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 public class AdapterTemplateMasterManagementTest {
 
     @Test
@@ -55,4 +55,4 @@ public class AdapterTemplateMasterManagementTest {
         assertEquals(1, result.getList().size());
         assertEquals(uri, result.getList().get(0).getUri());
     }
-}
\ No newline at end of file
+}
diff --git 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/DescriptionManagementTest.java
 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/DescriptionManagementTest.java
similarity index 94%
rename from 
streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/DescriptionManagementTest.java
rename to 
streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/DescriptionManagementTest.java
index 2fc2d53..dd9a803 100644
--- 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/DescriptionManagementTest.java
+++ 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/DescriptionManagementTest.java
@@ -16,11 +16,12 @@
  *
  */
 
-package org.apache.streampipes.connect.container.master;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+package org.apache.streampipes.connect.container.master.management;
 
+import org.apache.streampipes.connect.adapter.AdapterRegistry;
+import org.apache.streampipes.connect.adapter.format.json.arraykey.JsonFormat;
+import org.apache.streampipes.connect.adapter.model.generic.Format;
+import org.apache.streampipes.model.connect.grounding.FormatDescriptionList;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
@@ -28,15 +29,13 @@ import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PowerMockIgnore;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
-import org.apache.streampipes.connect.adapter.AdapterRegistry;
-import org.apache.streampipes.connect.adapter.format.json.arraykey.JsonFormat;
-import org.apache.streampipes.connect.adapter.model.generic.Format;
-import 
org.apache.streampipes.connect.container.master.management.DescriptionManagement;
-import org.apache.streampipes.model.connect.grounding.FormatDescriptionList;
 
 import java.util.HashMap;
 import java.util.Map;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
 @RunWith(PowerMockRunner.class)
 @PrepareForTest({ AdapterRegistry.class })
 @PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", 
"javax.management.*"})
@@ -62,4 +61,4 @@ public class DescriptionManagementTest {
         assertEquals(JsonFormat.ID, result.getList().get(0).getUri());
     }
 
-}
\ No newline at end of file
+}
diff --git 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/SourcesManagementTest.java
 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/SourcesManagementTest.java
similarity index 100%
rename from 
streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/SourcesManagementTest.java
rename to 
streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/SourcesManagementTest.java
diff --git 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/UnitMasterManagementTest.java
 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/UnitMasterManagementTest.java
similarity index 100%
rename from 
streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/UnitMasterManagementTest.java
rename to 
streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/UnitMasterManagementTest.java
diff --git 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/WorkerRestClientTest.java
 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/WorkerRestClientTest.java
similarity index 98%
rename from 
streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/WorkerRestClientTest.java
rename to 
streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/WorkerRestClientTest.java
index 533c1ef..e87f012 100644
--- 
a/streampipes-connect-container-master/src/test/java/org/streampipes/connect/container/master/management/WorkerRestClientTest.java
+++ 
b/streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/WorkerRestClientTest.java
@@ -18,10 +18,9 @@
 
 package org.apache.streampipes.connect.container.master.management;
 
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.times;
-import static org.powermock.api.mockito.PowerMockito.*;
-
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import 
org.apache.streampipes.model.connect.adapter.GenericAdapterSetDescription;
+import 
org.apache.streampipes.model.connect.adapter.GenericAdapterStreamDescription;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -29,9 +28,10 @@ import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PowerMockIgnore;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
-import org.apache.streampipes.connect.adapter.exception.AdapterException;
-import 
org.apache.streampipes.model.connect.adapter.GenericAdapterSetDescription;
-import 
org.apache.streampipes.model.connect.adapter.GenericAdapterStreamDescription;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.times;
+import static org.powermock.api.mockito.PowerMockito.*;
 
 @RunWith(PowerMockRunner.class)
 @PrepareForTest({ WorkerRestClient.class })
@@ -53,7 +53,7 @@ public class WorkerRestClientTest {
         doNothing().when(WorkerRestClient.class, "startAdapter", anyString(), 
any());
         when(WorkerRestClient.class, "invokeStreamAdapter", anyString(), 
any()).thenCallRealMethod();
 
-        WorkerRestClient.invokeStreamAdapter("", null);
+        WorkerRestClient.invokeStreamAdapter("", "");
 
         verifyStatic(WorkerRestClient.class, times(1));
         WorkerRestClient.startAdapter(eq("worker/stream/invoke"), any());
@@ -64,7 +64,7 @@ public class WorkerRestClientTest {
         doThrow(new AdapterException()).when(WorkerRestClient.class, 
"startAdapter", anyString(), any());
         when(WorkerRestClient.class, "invokeStreamAdapter", anyString(), 
any()).thenCallRealMethod();
 
-        WorkerRestClient.invokeStreamAdapter("", null);
+        WorkerRestClient.invokeStreamAdapter("", "");
     }
 
     @Test
@@ -143,4 +143,4 @@ public class WorkerRestClientTest {
 
     }
 
-}
\ No newline at end of file
+}
diff --git 
a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/AdapterDescription.java
 
b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/AdapterDescription.java
index 37fa541..b906375 100644
--- 
a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/AdapterDescription.java
+++ 
b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/AdapterDescription.java
@@ -92,6 +92,8 @@ public abstract class AdapterDescription extends 
NamedStreamPipesEntity {
     @RdfProperty(StreamPipes.HAS_ADAPTER_TYPE)
     private List<String> category;
 
+    private long createdAt;
+
     public AdapterDescription() {
         super();
         this.rules = new ArrayList<>();
@@ -119,12 +121,15 @@ public abstract class AdapterDescription extends 
NamedStreamPipesEntity {
     public AdapterDescription(AdapterDescription other) {
         super(other);
         this.adapterId = other.getAdapterId();
+        this.id = other.getId();
+        this.rev = other.getRev();
         this.config = new Cloner().staticProperties(other.getConfig());
         this.userName = other.getUserName();
         this.rules = other.getRules();
         this.adapterType = other.getAdapterType();
         this.icon = other.getIcon();
         this.category = new Cloner().epaTypes(other.getCategory());
+        this.createdAt = other.getCreatedAt();
         if (other.getEventGrounding() != null) this.eventGrounding = new 
EventGrounding(other.getEventGrounding());
     }
 
@@ -250,4 +255,12 @@ public abstract class AdapterDescription extends 
NamedStreamPipesEntity {
                 ", DOM='" + DOM + '\'' +
                 '}';
     }
+
+    public long getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(long createdAt) {
+        this.createdAt = createdAt;
+    }
 }
diff --git 
a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/AdapterStreamDescription.java
 
b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/AdapterStreamDescription.java
index 4293e5e..211b3f1 100644
--- 
a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/AdapterStreamDescription.java
+++ 
b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/AdapterStreamDescription.java
@@ -38,6 +38,8 @@ public abstract class AdapterStreamDescription extends 
AdapterDescription {
     @RdfProperty("sp:hasDataStream")
     private SpDataStream dataStream;
 
+    private boolean running;
+
     public AdapterStreamDescription() {
         super();
     }
@@ -49,6 +51,7 @@ public abstract class AdapterStreamDescription extends 
AdapterDescription {
 
     public AdapterStreamDescription(AdapterStreamDescription other) {
         super(other);
+        this.running = other.isRunning();
         if (other.getDataStream() != null) {
             this.dataStream = new SpDataStream(other.getDataStream());
         }
@@ -61,4 +64,12 @@ public abstract class AdapterStreamDescription extends 
AdapterDescription {
     public void setDataStream(SpDataStream dataStream) {
         this.dataStream = dataStream;
     }
+
+    public boolean isRunning() {
+        return running;
+    }
+
+    public void setRunning(boolean running) {
+        this.running = running;
+    }
 }
diff --git 
a/streampipes-serializers-json/src/main/java/org/apache/streampipes/serializers/json/AdapterSerializer.java
 
b/streampipes-serializers-json/src/main/java/org/apache/streampipes/serializers/json/AdapterSerializer.java
index cf72656..b13cdd8 100644
--- 
a/streampipes-serializers-json/src/main/java/org/apache/streampipes/serializers/json/AdapterSerializer.java
+++ 
b/streampipes-serializers-json/src/main/java/org/apache/streampipes/serializers/json/AdapterSerializer.java
@@ -32,8 +32,12 @@ public class AdapterSerializer implements 
JsonSerializer<AdapterDescription>, Js
     String type = jsonObject.get("field_type").getAsString();
     JsonElement element = jsonObject.get("properties");
     JsonObject tmp = element.getAsJsonObject();
-    tmp.addProperty("_id", jsonObject.get("_id").getAsString());
-    tmp.addProperty("_rev", jsonObject.get("_rev").getAsString());
+    if (jsonObject.has("_id")) {
+      tmp.addProperty("_id", jsonObject.get("_id").getAsString());
+    }
+    if (jsonObject.has("_rev")) {
+      tmp.addProperty("_rev", jsonObject.get("_rev").getAsString());
+    }
 
     try {
       return (AdapterDescription) GsonSerializer.getGson().fromJson(element, 
Class.forName(type));
@@ -50,6 +54,12 @@ public class AdapterSerializer implements 
JsonSerializer<AdapterDescription>, Js
       result.add("type", new JsonPrimitive(src.getClass().getCanonicalName()));
       result.add("field_type", new 
JsonPrimitive(src.getClass().getCanonicalName()));
       result.add("properties", GsonSerializer.getGson().toJsonTree(src));
+      if (src.getId() != null) {
+        result.add("_id", new JsonPrimitive(src.getId()));
+      }
+      if (src.getRev() != null) {
+        result.add("_rev", new JsonPrimitive(src.getRev()));
+      }
     } catch (MalformedParameterizedTypeException e) {
       e.printStackTrace();
     }
diff --git 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
 
b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
index 6909489..dee2107 100644
--- 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
+++ 
b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
@@ -26,7 +26,7 @@ public interface IAdapterStorage {
 
     List<AdapterDescription> getAllAdapters();
 
-    void storeAdapter(AdapterDescription adapter);
+    String storeAdapter(AdapterDescription adapter);
 
     void updateAdapter(AdapterDescription adapter);
 
diff --git 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
 
b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
index 856c64a..fe8cd3c 100644
--- 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
+++ 
b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
@@ -19,6 +19,10 @@ package org.apache.streampipes.storage.api;
 
 public interface INoSqlStorage {
 
+  IAdapterStorage getAdapterStorage();
+
+  IAdapterTemplateStorage getAdapterTemplateStorage();
+
   ICategoryStorage getCategoryStorageAPI();
 
   ILabelStorage getLabelStorageAPI();
diff --git 
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java
 
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java
index fc1d4b8..f15dc5b 100644
--- 
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java
+++ 
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java
@@ -25,6 +25,16 @@ public enum CouchDbStorageManager implements INoSqlStorage {
   INSTANCE;
 
   @Override
+  public IAdapterStorage getAdapterStorage() {
+    return new AdapterStorageImpl();
+  }
+
+  @Override
+  public IAdapterTemplateStorage getAdapterTemplateStorage() {
+    return new AdapterTemplateStorageImpl();
+  }
+
+  @Override
   public ICategoryStorage getCategoryStorageAPI() { return new 
CategoryStorageImpl(); }
 
   @Override
diff --git 
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterStorageImpl.java
 
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterStorageImpl.java
index beb8c47..1970a09 100644
--- 
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterStorageImpl.java
+++ 
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterStorageImpl.java
@@ -46,14 +46,13 @@ public class AdapterStorageImpl extends 
AbstractDao<AdapterDescription> implemen
     }
 
     @Override
-    public void storeAdapter(AdapterDescription adapter) {
-        persist(adapter);
+    public String storeAdapter(AdapterDescription adapter) {
+        return persist(adapter).b;
     }
 
     @Override
     public void updateAdapter(AdapterDescription adapter) {
-        couchDbClientSupplier.get().
-        update(adapter);
+        couchDbClientSupplier.get().update(adapter);
     }
 
     @Override
diff --git 
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
 
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
index f0c3e81..5895a2b 100644
--- 
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
+++ 
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
@@ -25,73 +25,51 @@ import 
org.apache.streampipes.serializers.json.GsonSerializer;
 public class Utils {
 
   public static CouchDbClient getCouchDbPipelineElementTemplateClient() {
-    CouchDbClient dbClient = new 
CouchDbClient(props("pipelineelementtemplate"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("pipelineelementtemplate");
   }
 
   public static CouchDbClient getCouchDbCategoryClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("category"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("category");
   }
 
   public static CouchDbClient getCouchDbLabelClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("label"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("label");
   }
 
   public static CouchDbClient getCouchDbConnectWorkerContainerClient() {
-    CouchDbClient dbClient = new 
CouchDbClient(props("connectworkercontainer"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("connectworkercontainer");
   }
 
   public static CouchDbClient getCouchDbFileMetadataClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("filemetadata"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("filemetadata");
   }
 
   public static CouchDbClient getCouchDbAdapterTemplateClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("adaptertemplate"));
-    dbClient.setGsonBuilder(GsonSerializer.getAdapterGsonBuilder());
-    return dbClient;
+    return getCouchDbAdapterClient("adaptertemplate");
   }
 
   public static CouchDbClient getCouchDbAssetDashboardClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("assetdashboard"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("assetdashboard");
   }
 
   public static CouchDbClient getCouchDbAdapterClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("adapter"));
-    dbClient.setGsonBuilder(GsonSerializer.getAdapterGsonBuilder());
-    return dbClient;
+    return getCouchDbAdapterClient("adapter");
   }
 
   public static CouchDbClient getCouchDbPipelineClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("pipeline"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("pipeline");
   }
 
   public static CouchDbClient getCouchDbSepaInvocationClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("invocation"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("invocation");
   }
 
   public static CouchDbClient getCouchDbConnectionClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("connection"));
-    return dbClient;
+    return getCouchDbStandardSerializerClient("connection");
   }
 
   public static CouchDbClient getCouchDbVisualizationClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("visualizations"));
-    return dbClient;
+    return getCouchDbStandardSerializerClient("visualizations");
   }
 
   //TODO: Remove??
@@ -101,82 +79,77 @@ public class Utils {
   }
 
   public static CouchDbClient getCouchDbVisualizablePipelineClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("visualizablepipeline"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("visualizablepipeline");
   }
 
   public static CouchDbClient getCouchDbDataExplorerDashboardClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("dataexplorerdashboard"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("dataexplorerdashboard");
   }
 
-
   public static CouchDbClient getCouchDbDataExplorerWidgetClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("dataexplorerwidget"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("dataexplorerwidget");
   }
 
-
   public static CouchDbClient getCouchDbDashboardClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("dashboard"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("dashboard");
   }
 
   public static CouchDbClient getCouchDbDashboardWidgetClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("dashboardwidget"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("dashboardwidget");
   }
 
   public static CouchDbClient getCouchDbUserClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("users"));
-    dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
-    return dbClient;
+    return getCouchDbGsonClient("users");
   }
 
   public static CouchDbClient getCouchDbInternalUsersClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("_users"));
-    return dbClient;
+    return getCouchDbStandardSerializerClient("_users");
   }
 
   public static CouchDbClient getCouchDbReplicatorClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("_replicator"));
-    return dbClient;
+    return getCouchDbStandardSerializerClient("_replicator");
   }
 
   public static CouchDbClient getCouchDbGlobalChangesClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("_global_changes"));
-    return dbClient;
+    return getCouchDbStandardSerializerClient("_global_changes");
   }
 
-
   public static CouchDbClient getCouchDbMonitoringClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("monitoring"));
-    return dbClient;
+    return getCouchDbStandardSerializerClient("monitoring");
   }
 
   public static CouchDbClient getCouchDbNotificationClient() {
-    return new CouchDbClient(props("notification"));
+    return getCouchDbStandardSerializerClient("notification");
   }
 
   public static CouchDbClient getCouchDbPipelineCategoriesClient() {
-    return new CouchDbClient(props("pipelinecategories"));
+    return getCouchDbStandardSerializerClient("pipelinecategories");
   }
 
   public static CouchDbClient getCouchDbElasticsearchFilesEndppointClient() {
-    return new CouchDbClient(props("file-export-endpoints-elasticsearch"));
+    return 
getCouchDbStandardSerializerClient("file-export-endpoints-elasticsearch");
   }
 
   public static CouchDbClient getCouchDbDataLakeClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("data-lake"));
+    return getCouchDbGsonClient("data-lake");
+  }
+
+  private static CouchDbClient getCouchDbGsonClient(String dbname) {
+    CouchDbClient dbClient = new CouchDbClient(props(dbname));
     dbClient.setGsonBuilder(GsonSerializer.getGsonBuilder());
     return dbClient;
   }
 
+  private static CouchDbClient getCouchDbAdapterClient(String dbname) {
+    CouchDbClient dbClient = new CouchDbClient(props(dbname));
+    dbClient.setGsonBuilder(GsonSerializer.getAdapterGsonBuilder());
+    return dbClient;
+  }
+
+  private static CouchDbClient getCouchDbStandardSerializerClient(String 
dbname) {
+    return new CouchDbClient(props(dbname));
+  }
+
   public static CouchDbClient getCoucbDbClient(String table) {
     return new CouchDbClient(props(table));
   }
diff --git 
a/ui/src/app/connect/components/data-marketplace/adapter-description/adapter-description.component.html
 
b/ui/src/app/connect/components/data-marketplace/adapter-description/adapter-description.component.html
index 4280abf..e23e83b 100644
--- 
a/ui/src/app/connect/components/data-marketplace/adapter-description/adapter-description.component.html
+++ 
b/ui/src/app/connect/components/data-marketplace/adapter-description/adapter-description.component.html
@@ -37,19 +37,6 @@
         <div fxFlex="70" class="description" fxLayoutAlign="start start">
             <p [innerHTML]="adapter.description"></p>
         </div>
-        <div fxFlex="30" fxLayout="row" fxLayoutAlign="end end" 
*ngIf="isRunningAdapter" class="delete">
-            <button id="{{ 'create-template-' + adapter.name.split(' 
').join('_') }}" matTooltip="Create Adapter Template" color="secondary" 
class="edit" mat-fab (click)="createTemplate(adapter)">
-                <i class="material-icons">
-                    content_copy
-                </i>
-            </button>
-            <button id="{{ 'delete-' + adapterLabel }}" matTooltip="Delete 
Adapter" color="primary" mat-fab (click)="deleteAdapter(adapter)" 
[disabled]="deleteInProgress(adapter.couchDBId)">
-                <i class="material-icons" 
*ngIf="!deleteInProgress(adapter.couchDBId)">
-                    delete
-                </i>
-                <mat-spinner *ngIf="deleteInProgress(adapter.couchDBId)" 
[diameter]="20" fxLayoutAlign="center"></mat-spinner>
-            </button>
-        </div>
         <div fxFlex="30" fxLayout="row" fxLayoutAlign="end end" 
*ngIf="$any(adapter).isTemplate" class="delete">
             <button id="{{ 'share-template-' + adapterLabel }}" 
matTooltip="Share Adapter Template" color="secondary" mat-fab 
(click)="shareAdapterTemplate(adapter); $event.stopPropagation()">
                 <i class="material-icons" 
*ngIf="!deleteInProgress(adapter.couchDBId)">
@@ -65,4 +52,4 @@
 
         </div>
     </div>
-</div>
\ No newline at end of file
+</div>
diff --git 
a/ui/src/app/connect/components/data-marketplace/adapter-description/adapter-description.component.ts
 
b/ui/src/app/connect/components/data-marketplace/adapter-description/adapter-description.component.ts
index 56f41f6..23701ee 100644
--- 
a/ui/src/app/connect/components/data-marketplace/adapter-description/adapter-description.component.ts
+++ 
b/ui/src/app/connect/components/data-marketplace/adapter-description/adapter-description.component.ts
@@ -71,16 +71,6 @@ export class AdapterDescriptionComponent {
     return this.connectService.isSpecificDescription(this.adapter);
   }
 
-  deleteAdapter(adapter: AdapterDescription): void {
-  this.deleting = true;
-      this.adapterToDelete = adapter.couchDBId;
-      this.dataMarketplaceService.deleteAdapter(adapter).subscribe(res => {
-          this.adapterToDelete = undefined;
-          this.updateAdapterEmitter.emit();
-          this.deleting = false;
-      });
-  }
-
   shareAdapterTemplate(adapter: AdapterDescription): void {
     this.dialogService.open(AdapterExportDialog,{
       panelType: PanelType.STANDARD_PANEL,
diff --git 
a/ui/src/app/connect/components/data-marketplace/data-marketplace.component.html
 
b/ui/src/app/connect/components/data-marketplace/data-marketplace.component.html
index 3c00d77..6b85661 100644
--- 
a/ui/src/app/connect/components/data-marketplace/data-marketplace.component.html
+++ 
b/ui/src/app/connect/components/data-marketplace/data-marketplace.component.html
@@ -22,13 +22,15 @@
             <mat-tab-group [selectedIndex]="selectedIndex" 
(selectedIndexChange)="selectedIndexChange($event)">
                 <mat-tab label="Data Marketplace">
                 </mat-tab>
-                <mat-tab id="all-adapters" label="Running Adapters">
+                <mat-tab id="all-adapters" label="My Adapters">
                 </mat-tab>
             </mat-tab-group>
         </div>
-        <div fxFlex="100" fxLayout="row" fxLayoutAlign="end center" 
style="padding-left:10px;padding-right:10px;font-size:14px;line-height:24px;border-bottom:1px
 solid #ccc"
-            *ngIf="selectedIndex === 0 && newAdapterFromDescription === 
undefined">
-            <button mat-icon-button id="startAdapterTutorial3" 
(click)="startAdapterTutorial3()" matTooltip="Tutorial: Generic Adapter">
+        <div fxFlex="100" fxLayout="row" fxLayoutAlign="end center"
+             
style="padding-left:10px;padding-right:10px;font-size:14px;line-height:24px;border-bottom:1px
 solid #ccc"
+             *ngIf="selectedIndex === 0 && newAdapterFromDescription === 
undefined">
+            <button mat-icon-button id="startAdapterTutorial3" 
(click)="startAdapterTutorial3()"
+                    matTooltip="Tutorial: Generic Adapter">
                 <mat-icon color="primary">school</mat-icon>
             </button>
         </div>
@@ -36,11 +38,12 @@
 
     <div fxLayout="row" class="fixed-height data-marketplace-options">
 
-        <div class="data-marketplace-options-item pl-5" 
style="margin-top:8px;" fxLayoutAlign="start center" fxLayout="row">
+        <div class="data-marketplace-options-item pl-5" 
style="margin-top:8px;" fxLayoutAlign="start center"
+             fxLayout="row">
             <mat-icon color="primary">search</mat-icon>
             <mat-form-field class="form-style">
                 <input matInput placeholder="Find Element" value="" 
(input)="updateFilterTerm($event.target.value)"
-                    name="something">
+                       name="something">
             </mat-form-field>
         </div>
         <div class="data-marketplace-options-item">
@@ -63,39 +66,54 @@
         </div>
         <span fxFlex></span>
 
-        <mat-icon class="icon-style" matTooltip="Download All Adapter 
Templates" (click)="downloadAllAdapterTemplates()" style="margin-right: 15px; 
cursor: pointer;">cloud_download</mat-icon>
-        <mat-icon class="icon-style" matTooltip="Upload Adapter Templates" 
(click)="uploadAdapterTemplates()" style="margin-right: 15px; cursor: 
pointer;">cloud_upload</mat-icon>
+        <mat-icon class="icon-style" matTooltip="Download All Adapter 
Templates" (click)="downloadAllAdapterTemplates()"
+                  style="margin-right: 15px; cursor: pointer;">cloud_download
+        </mat-icon>
+        <mat-icon class="icon-style" matTooltip="Upload Adapter Templates" 
(click)="uploadAdapterTemplates()"
+                  style="margin-right: 15px; cursor: pointer;">cloud_upload
+        </mat-icon>
 
     </div>
-    <div class="container-fluid marketplace-container" 
*ngIf="adapterLoadingError" fxFlex="100" fxLayoutAlign="center center" 
fxLayout="row">
+    <div class="container-fluid marketplace-container" 
*ngIf="adapterLoadingError" fxFlex="100"
+         fxLayoutAlign="center center" fxLayout="row">
         <h4>Available adapters could not be loaded. Did you start a 
StreamPipes Connect worker node?</h4>
     </div>
-    <div class="container-fluid marketplace-container" *ngIf="adaptersLoading" 
fxFlex="100" fxLayoutAlign="center center" fxLayout="row">
+    <div class="container-fluid marketplace-container" *ngIf="adaptersLoading" 
fxFlex="100"
+         fxLayoutAlign="center center" fxLayout="row">
         <mat-spinner [mode]="'indeterminate'" [diameter]="20"></mat-spinner>
         <h4>&nbsp;&nbsp;Searching for available adapters, please wait...</h4>
     </div>
     <div class="container-fluid marketplace-container" *ngIf="!adaptersLoading 
&& !adapterLoadingError">
         <div *ngIf="selectedIndex === 0">
 
-            <div *ngIf="newAdapterFromDescription===undefined" fxLayout="row 
wrap" fxLayoutAlign="start stretch" class="adapter-description-container">
-                <sp-adapter-description 
attr.id="{{adapterDescription.name.replace(' ', '_')}}" 
class="adapter-description"
-                    fxFlex="33" (click)="selectAdapter(adapterDescription)" 
*ngFor="let adapterDescription of filteredAdapterDescriptions | 
filter:filterTerm"
-                    [adapter]="adapterDescription" 
(updateAdapterEmitter)="updateDescriptionsAndRunningAdatpers()"></sp-adapter-description>
+            <div *ngIf="newAdapterFromDescription===undefined" fxLayout="row 
wrap" fxLayoutAlign="start stretch"
+                 class="adapter-description-container">
+                <sp-adapter-description 
attr.id="{{adapterDescription.name.replace(' ', '_')}}"
+                                        class="adapter-description"
+                                        fxFlex="33" 
(click)="selectAdapter(adapterDescription)"
+                                        *ngFor="let adapterDescription of 
filteredAdapterDescriptions | filter:filterTerm"
+                                        [adapter]="adapterDescription"
+                                        
(updateAdapterEmitter)="updateDescriptionsAndRunningAdatpers()"></sp-adapter-description>
             </div>
 
 
-            <div class="new-adapter-container" fxFlex="100" fxLayout="row" 
fxLayoutAlign="start start" *ngIf="newAdapterFromDescription!==undefined">
-                <sp-new-adapter fxFlex="100" 
(removeSelectionEmitter)="removeSelection($event)" 
[adapter]="newAdapterFromDescription"
-                    
(updateAdapterEmitter)="updateDescriptionsAndRunningAdatpers()"></sp-new-adapter>
+            <div class="new-adapter-container" fxFlex="100" fxLayout="row" 
fxLayoutAlign="start start"
+                 *ngIf="newAdapterFromDescription!==undefined">
+                <sp-new-adapter fxFlex="100" 
(removeSelectionEmitter)="removeSelection($event)"
+                                [adapter]="newAdapterFromDescription"
+                                
(updateAdapterEmitter)="updateDescriptionsAndRunningAdatpers()"></sp-new-adapter>
             </div>
 
         </div>
         <div *ngIf="selectedIndex === 1">
-            <div fxLayout="row wrap" fxLayoutAlign="start stretch" 
class="adapter-container">
-                <sp-adapter-description class="adapter-description" 
fxFlex="33" *ngFor="let adapter of filteredAdapters | filter:filterTerm"
-                    [adapter]="adapter" 
(createTemplateEmitter)="templateFromRunningAdapter(adapter)"
-                    
(updateAdapterEmitter)="updateDescriptionsAndRunningAdatpers()"></sp-adapter-description>
+            <div fxFlex="100" class="adapter-container">
+                <sp-existing-adapters [existingAdapters]="filteredAdapters"
+                                      [filterTerm]="filterTerm"
+                                      
(updateAdapterEmitter)="updateDescriptionsAndRunningAdatpers()"
+                                      
(createTemplateEmitter)="templateFromRunningAdapter($event)">
+
+                </sp-existing-adapters>
             </div>
         </div>
     </div>
-</div>
\ No newline at end of file
+</div>
diff --git 
a/ui/src/app/connect/components/data-marketplace/data-marketplace.component.ts 
b/ui/src/app/connect/components/data-marketplace/data-marketplace.component.ts
index 498e8f0..a9af635 100644
--- 
a/ui/src/app/connect/components/data-marketplace/data-marketplace.component.ts
+++ 
b/ui/src/app/connect/components/data-marketplace/data-marketplace.component.ts
@@ -23,13 +23,13 @@ import {ConnectService} from 
'../../services/connect.service';
 import {FilterPipe} from '../../filter/filter.pipe';
 import {AdapterUploadDialog} from 
'../../dialog/adapter-upload/adapter-upload-dialog.component';
 import {
-  AdapterDescription,
-  AdapterDescriptionUnion,
-  AdapterSetDescription,
-  AdapterStreamDescription,
-  EventSchema,
-  SpDataSet,
-  SpDataStream
+    AdapterDescription,
+    AdapterDescriptionUnion,
+    AdapterSetDescription,
+    AdapterStreamDescription,
+    EventSchema,
+    SpDataSet,
+    SpDataStream
 } from "../../../core-model/gen/streampipes-model";
 import {PanelType} from 
"../../../core-ui/dialog/base-dialog/base-dialog.model";
 import {DialogService} from 
"../../../core-ui/dialog/base-dialog/base-dialog.service";
@@ -169,6 +169,8 @@ export class DataMarketplaceComponent implements OnInit {
     }
 
     templateFromRunningAdapter(adapter: AdapterDescriptionUnion) {
+        adapter.couchDBId = undefined;
+        adapter._rev = undefined;
         this.selectedIndexChange(0);
         this.selectAdapter(adapter);
 
diff --git 
a/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.html
 
b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.html
new file mode 100644
index 0000000..78b0112
--- /dev/null
+++ 
b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.html
@@ -0,0 +1,126 @@
+<!--
+  ~ 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 fxFlex="100" fxLayout="column">
+    <div class="assemblyOptions sp-blue-bg mt-20" style="padding:5px;">
+        <div fxLayout="row" fxLayoutAlign="start center">
+            <h4>My adapters</h4>
+        </div>
+    </div>
+    <div class="sp-blue-border">
+        <table fxFlex="100" mat-table [dataSource]="dataSource" style="width: 
100%;" matSort>
+            <ng-container matColumnDef="start">
+                <th mat-header-cell *matHeaderCellDef> Start</th>
+                <td mat-cell *matCellDef="let adapter">
+                    <button color="primary" mat-button mat-icon-button 
matTooltip="Start adapter"
+                            matTooltipPosition="above"
+                            (click)="startAdapter(adapter)"
+                            
*ngIf="(connectService.isDataStreamDescription(adapter)) && !adapter.running">
+                        <i class="material-icons">play_arrow</i>
+                    </button>
+                    <button color="primary" mat-button mat-icon-button 
matTooltip="Stop adapter"
+                            matTooltipPosition="above"
+                            (click)="stopAdapter(adapter)"
+                            
*ngIf="(connectService.isDataStreamDescription(adapter)) && adapter.running">
+                        <i class="material-icons">stop</i>
+                    </button>
+                </td>
+            </ng-container>
+
+            <ng-container matColumnDef="name">
+                <th mat-header-cell mat-sort-header *matHeaderCellDef> 
Name</th>
+                <td mat-cell *matCellDef="let adapter">
+                    <h4 style="margin-bottom:0px;">{{adapter.name}}</h4>
+                    <h5>{{adapter.description != '' ? adapter.description : 
'-'}}</h5>
+                </td>
+            </ng-container>
+            <ng-container matColumnDef="adapterBase">
+                <th mat-header-cell *matHeaderCellDef> Adapter</th>
+                <td mat-cell *matCellDef="let adapter">
+                    <img *ngIf="getIconUrl(adapter) && !adapter.icon" 
[src]="getIconUrl(adapter)" class="adapter-icon"/>
+                    <img *ngIf="adapter.icon" [src]="adapter.icon" 
class="adapter-icon"/>
+                </td>
+            </ng-container>
+            <ng-container matColumnDef="adapterType">
+                <th mat-header-cell *matHeaderCellDef> Type</th>
+                <td mat-cell *matCellDef="let adapter">
+                    <div class="type-data" fxLayout="row" fxLayoutAlign="start 
start">
+                        <div fxLayout="row" fxLayoutAlign="center center">
+                            <mat-icon 
*ngIf="connectService.isDataSetDescription(adapter)" 
class="historic">lens</mat-icon>
+                            <mat-icon 
*ngIf="connectService.isDataStreamDescription(adapter)" class="real-time">lens
+                            </mat-icon>
+                            <div fxFlex="100" fxLayoutAlign="center center">
+                            <span 
*ngIf="connectService.isDataSetDescription(adapter)">&nbsp;Data Set</span>
+                            <span 
*ngIf="connectService.isDataStreamDescription(adapter)">&nbsp;Data Stream</span>
+                            </div>
+                        </div>
+                    </div>
+                </td>
+            </ng-container>
+            <ng-container matColumnDef="lastModified">
+                <th mat-header-cell *matHeaderCellDef> Created</th>
+                <td mat-cell *matCellDef="let adapter">
+                    <h5>{{adapter.createdAt | date:'dd.MM.yyyy HH:mm'}}</h5>
+                </td>
+            </ng-container>
+
+            <ng-container matColumnDef="action">
+                <th mat-header-cell *matHeaderCellDef> Action</th>
+                <td mat-cell *matCellDef="let adapter">
+                    <div fxLayout="row">
+<!--                <span fxFlex fxFlexOrder="1" fxLayout="row" 
fxLayoutAlign="center center">-->
+<!--                    <button color="primary" mat-button mat-icon-button 
matTooltip="Show adapter"-->
+<!--                            matTooltipPosition="above"><i-->
+<!--                            class="material-icons">search</i>-->
+<!--                    </button>-->
+<!--                </span>-->
+<!--                        <span fxFlex fxFlexOrder="2" fxLayout="row" 
fxLayoutAlign="center center">-->
+<!--                    <button color="primary" mat-button mat-icon-button 
matTooltip="Modify adapter"-->
+<!--                            matTooltipPosition="above"-->
+<!--                            [disabled]="adapter.running">-->
+<!--                        <i class="material-icons">mode_edit</i>-->
+<!--                    </button>-->
+<!--                </span>-->
+                <span fxFlex fxFlexOrder="1" fxLayout="row" 
fxLayoutAlign="center center">
+                    <button color="primary" mat-button mat-icon-button 
matTooltip="Create adapter template"
+                            matTooltipPosition="above" 
(click)="createTemplate(adapter)"><i
+                            class="material-icons">content_copy</i>
+                    </button>
+                </span>
+                <span fxFlex fxFlexOrder="3" fxLayout="row" 
fxLayoutAlign="center center">
+                    <button color="primary" mat-button mat-icon-button 
matTooltip="Delete adapter"
+                            matTooltipPosition="above" 
(click)="deleteAdapter(adapter)">
+                        <i class="material-icons">delete</i>
+                    </button>
+                </span>
+                    </div>
+                </td>
+            </ng-container>
+
+            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+            <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+
+        </table>
+    </div>
+    <div fxFlex="100" fxLayoutAlign="end end">
+        <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]" 
[pageSize]="20"></mat-paginator>
+    </div>
+    <div fxFlex="100" fxLayout="column" fxLayoutAlign="center center" 
*ngIf="existingAdapters.length == 0">
+        <h5>(no pipelines available)</h5>
+    </div>
+</div>
diff --git 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
 
b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.scss
similarity index 65%
copy from 
streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
copy to 
ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.scss
index 6909489..a249b79 100644
--- 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
+++ 
b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.scss
@@ -16,21 +16,32 @@
  *
  */
 
-package org.apache.streampipes.storage.api;
 
-import org.apache.streampipes.model.connect.adapter.AdapterDescription;
-
-import java.util.List;
-
-public interface IAdapterStorage {
-
-    List<AdapterDescription> getAllAdapters();
+.mat-table {
+  background: #FAFAFA;
+}
 
-    void storeAdapter(AdapterDescription adapter);
+.mat-paginator {
+  border-top: 1px solid rgba(0,0,0,.12);
+  background: #FAFAFA;
+}
 
-    void updateAdapter(AdapterDescription adapter);
+.mat-row:nth-child(even) {
+  background-color: #FAFAFA;
+}
+.mat-row:nth-child(odd) {
+  background-color:#ffffff;
+}
 
-    AdapterDescription getAdapter(String adapterId);
+.adapter-icon {
+  max-height:50px;
+}
 
-    void deleteAdapter(String adapterId);
+.historic {
+  cursor: pointer;
+  color: #ffa23b;
+}
+.real-time {
+  cursor: pointer;
+  color: #FFEB3B;
 }
diff --git 
a/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.ts
 
b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.ts
new file mode 100644
index 0000000..cbf50e3
--- /dev/null
+++ 
b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.ts
@@ -0,0 +1,96 @@
+/*
+ * 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 {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {AdapterDescriptionUnion} from 
"../../../../core-model/gen/streampipes-model";
+import {MatTableDataSource} from "@angular/material/table";
+import {ConnectService} from "../../../services/connect.service";
+import {DataMarketplaceService} from 
"../../../services/data-marketplace.service";
+
+@Component({
+  selector: 'sp-existing-adapters',
+  templateUrl: './existing-adapters.component.html',
+  styleUrls: ['./existing-adapters.component.scss'],
+})
+export class ExistingAdaptersComponent implements OnInit {
+
+  _existingAdapters: Array<AdapterDescriptionUnion>;
+
+  @Input()
+  filterTerm: string;
+
+  @Output()
+  updateAdapterEmitter: EventEmitter<void> = new EventEmitter<void>();
+
+  @Output()
+  createTemplateEmitter: EventEmitter<AdapterDescriptionUnion> = new 
EventEmitter<AdapterDescriptionUnion>();
+
+  displayedColumns: string[] = ['start', 'name', 'adapterBase', 'adapterType', 
'lastModified', 'action'];
+
+  dataSource: MatTableDataSource<AdapterDescriptionUnion>;
+
+  constructor(public connectService: ConnectService,
+              private dataMarketplaceService: DataMarketplaceService) {
+
+  }
+
+  ngOnInit(): void {
+    this.dataSource = new MatTableDataSource(this.existingAdapters);
+  }
+
+  startAdapter(adapter: AdapterDescriptionUnion) {
+    this.dataMarketplaceService.startAdapter(adapter).subscribe(response => {
+      this.updateAdapterEmitter.emit();
+    });
+  }
+
+  stopAdapter(adapter: AdapterDescriptionUnion) {
+    this.dataMarketplaceService.stopAdapter(adapter).subscribe(response => {
+      this.updateAdapterEmitter.emit();
+    });
+  }
+
+  getIconUrl(adapter: AdapterDescriptionUnion) {
+    if (adapter.includedAssets.length > 0) {
+      return this.dataMarketplaceService.getAssetUrl(adapter.appId) + "/icon";
+    } else {
+      return 'assets/img/connect/' + adapter.iconUrl;
+    }
+  }
+
+  deleteAdapter(adapter: AdapterDescriptionUnion): void {
+    this.dataMarketplaceService.deleteAdapter(adapter).subscribe(res => {
+      this.updateAdapterEmitter.emit();
+    });
+  }
+
+  createTemplate(adapter: AdapterDescriptionUnion): void {
+    this.createTemplateEmitter.emit(adapter);
+  }
+
+  @Input()
+  set existingAdapters(adapters: Array<AdapterDescriptionUnion>) {
+    this._existingAdapters = adapters;
+    this.dataSource = new MatTableDataSource(adapters);
+  }
+
+  get existingAdapters(): Array<AdapterDescriptionUnion> {
+    return this._existingAdapters;
+  }
+
+}
diff --git a/ui/src/app/connect/connect.module.ts 
b/ui/src/app/connect/connect.module.ts
index da25348..d27eb0d 100644
--- a/ui/src/app/connect/connect.module.ts
+++ b/ui/src/app/connect/connect.module.ts
@@ -70,6 +70,7 @@ import {EventPropertyRowComponent} from 
'./components/schema-editor/event-proper
 import {EventSchemaPreviewComponent} from 
'./components/schema-editor/event-schema-preview/event-schema-preview.component';
 import {CoreUiModule} from "../core-ui/core-ui.module";
 import {EditCorrectionValueComponent} from 
'./dialog/edit-event-property/components/edit-correction-value/edit-correction-value.component';
+import {ExistingAdaptersComponent} from 
"./components/data-marketplace/existing-adapters/existing-adapters.component";
 
 @NgModule({
     imports: [
@@ -107,6 +108,7 @@ import {EditCorrectionValueComponent} from 
'./dialog/edit-event-property/compone
         EditTimestampPropertyComponent,
         EditDataTypeComponent,
         EventSchemaPreviewComponent,
+        ExistingAdaptersComponent,
         FilterPipe,
         FormatComponent,
         FormatFormComponent,
diff --git 
a/ui/src/app/connect/dialog/delete-adapter-dialog/delete-adapter-dialog.component.html
 
b/ui/src/app/connect/dialog/delete-adapter-dialog/delete-adapter-dialog.component.html
new file mode 100644
index 0000000..ab26a9f
--- /dev/null
+++ 
b/ui/src/app/connect/dialog/delete-adapter-dialog/delete-adapter-dialog.component.html
@@ -0,0 +1,52 @@
+<!--
+  ~ 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 class="sp-dialog-container">
+    <div class="sp-dialog-content p-15">
+        <div *ngIf="!isInProgress" fxLayout="column">
+            <div fxFlex="100" fxLayoutAlign="center center" fxLayout="column">
+                <b><h4>Do you really want to delete pipeline 
{{pipeline.name}}?</h4></b>
+                <b><h4 *ngIf="pipeline.running">This pipeline is still 
running.</h4></b>
+                <b><h5>This operation cannot be undone.</h5></b>
+            </div>
+
+            <div fxFlex="100" fxLayoutAlign="center center" fxLayout="column">
+                <button mat-button mat-raised-button color="primary" 
*ngIf="!pipeline.running"
+                        (click)="deletePipeline()">Delete
+                    pipeline
+                </button>
+                <button mat-button mat-raised-button color="primary" 
*ngIf="pipeline.running"
+                        (click)="stopAndDeletePipeline()">Stop and
+                    delete pipeline
+                </button>
+            </div>
+        </div>
+        <div fxFlex="100" fxLayoutAlign="center center" fxLayout="column" 
*ngIf="isInProgress">
+            <div fxLayout="row" fxLayoutAlign="space-around">
+                <mat-spinner [mode]="'indeterminate'"></mat-spinner>
+            </div>
+            <b><h4>{{currentStatus}}</h4></b>
+        </div>
+    </div>
+    <mat-divider></mat-divider>
+    <div class="sp-dialog-actions actions-align-right">
+        <button mat-button mat-raised-button class="mat-basic" 
(click)="close(false)">
+            Close
+        </button>
+    </div>
+</div>
\ No newline at end of file
diff --git 
a/ui/src/app/connect/dialog/delete-adapter-dialog/delete-adapter-dialog.component.ts
 
b/ui/src/app/connect/dialog/delete-adapter-dialog/delete-adapter-dialog.component.ts
new file mode 100644
index 0000000..7d8fb59
--- /dev/null
+++ 
b/ui/src/app/connect/dialog/delete-adapter-dialog/delete-adapter-dialog.component.ts
@@ -0,0 +1,64 @@
+/*
+ * 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 {Component, Input} from "@angular/core";
+import {Pipeline} from "../../../core-model/gen/streampipes-model";
+import {PipelineService} from 
"../../../platform-services/apis/pipeline.service";
+import {DialogRef} from "../../../core-ui/dialog/base-dialog/dialog-ref";
+
+@Component({
+    selector: 'delete-adapter-dialog',
+    templateUrl: './delete-adapter-dialog.component.html',
+    styleUrls: ['./delete-adapter-dialog.component.scss']
+})
+export class DeleteAdapterDialogComponent {
+
+    @Input()
+    pipeline: Pipeline;
+
+    isInProgress: boolean = false;
+    currentStatus: any;
+
+    constructor(private dialogRef: DialogRef<DeleteAdapterDialogComponent>,
+                private pipelineService: PipelineService) {
+    }
+
+    close(refreshPipelines: boolean) {
+        this.dialogRef.close(refreshPipelines);
+    };
+
+    deleteAdapter() {
+        this.isInProgress = true;
+        this.currentStatus = "Deleting pipeline...";
+        this.pipelineService.deleteOwnPipeline(this.pipeline._id)
+            .subscribe(data => {
+                this.close(true);
+            });
+    }
+
+    stopAndDeleteAdapter() {
+        this.isInProgress = true;
+        this.currentStatus = "Stopping pipeline...";
+        this.pipelineService.stopPipeline(this.pipeline._id)
+            .subscribe(data => {
+               this.deleteAdapter();
+            }, data => {
+                this.deleteAdapter();
+            });
+    }
+}
diff --git 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
 
b/ui/src/app/connect/dialog/delete-adapter-dialog/delete-pipeline-dialog.component.scss
similarity index 65%
copy from 
streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
copy to 
ui/src/app/connect/dialog/delete-adapter-dialog/delete-pipeline-dialog.component.scss
index 6909489..0a776e5 100644
--- 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java
+++ 
b/ui/src/app/connect/dialog/delete-adapter-dialog/delete-pipeline-dialog.component.scss
@@ -16,21 +16,4 @@
  *
  */
 
-package org.apache.streampipes.storage.api;
-
-import org.apache.streampipes.model.connect.adapter.AdapterDescription;
-
-import java.util.List;
-
-public interface IAdapterStorage {
-
-    List<AdapterDescription> getAllAdapters();
-
-    void storeAdapter(AdapterDescription adapter);
-
-    void updateAdapter(AdapterDescription adapter);
-
-    AdapterDescription getAdapter(String adapterId);
-
-    void deleteAdapter(String adapterId);
-}
+@import '../../../../scss/sp/sp-dialog.scss';
\ No newline at end of file
diff --git a/ui/src/app/connect/services/data-marketplace.service.ts 
b/ui/src/app/connect/services/data-marketplace.service.ts
index 96255aa..391b7f1 100644
--- a/ui/src/app/connect/services/data-marketplace.service.ts
+++ b/ui/src/app/connect/services/data-marketplace.service.ts
@@ -27,7 +27,7 @@ import {
   AdapterDescriptionUnion,
   EventSchema,
   GenericAdapterSetDescription,
-  GenericAdapterStreamDescription,
+  GenericAdapterStreamDescription, Message,
   ProtocolDescription,
   ProtocolDescriptionList,
   SpDataSet,
@@ -36,6 +36,7 @@ import {
   SpecificAdapterStreamDescription
 } from "../../core-model/gen/streampipes-model";
 import {Observable, zip} from "rxjs";
+import {PlatformServicesCommons} from 
"../../platform-services/apis/commons.service";
 
 @Injectable()
 export class DataMarketplaceService {
@@ -44,7 +45,8 @@ export class DataMarketplaceService {
   constructor(
       private http: HttpClient,
       private authStatusService: AuthStatusService,
-      private connectService: ConnectService) {
+      private connectService: ConnectService,
+      private platformServicesCommons: PlatformServicesCommons) {
   }
 
 
@@ -72,20 +74,29 @@ export class DataMarketplaceService {
         .pipe(map(response => {
           let adapterDescriptionList: AdapterDescriptionList = 
AdapterDescriptionList.fromData(response as AdapterDescriptionList);
           return adapterDescriptionList.list;
-          // const res: AdapterDescriptionList = 
this.tsonLdSerializer.fromJsonLd(
-          //   response,
-          //   'sp:AdapterDescriptionList'
-          // );
-          // res.list.forEach(adapterDescription => {
-          //   adapterDescription.config.sort((a, b) => a.index - b.index);
-          //   adapterDescription.config.forEach(sp => {
-          //     this.sortStaticProperties(sp)
-          //   });
-          // });
-          // return res.list;
         }));
   }
 
+  stopAdapter(adapter: AdapterDescriptionUnion): Observable<Message> {
+    return this.http.post(this.adapterMasterUrl
+        + adapter.couchDBId
+        + "/stop", {})
+        .pipe(map(response => Message.fromData(response as any)));
+  }
+
+  startAdapter(adapter: AdapterDescriptionUnion): Observable<Message> {
+    return this.http.post(this.adapterMasterUrl
+        + adapter.couchDBId
+        + "/start", {})
+        .pipe(map(response => Message.fromData(response as any)));;
+  }
+
+  get adapterMasterUrl() {
+    return this.host
+        + this.authStatusService.email
+        + "/master/adapters/";
+  }
+
   deleteAdapter(adapter: AdapterDescription): Observable<Object> {
     return this.deleteRequest(adapter, '/master/adapters/')
   }
diff --git a/ui/src/app/core-model/gen/streampipes-model.ts 
b/ui/src/app/core-model/gen/streampipes-model.ts
index 9262cf9..084b63e 100644
--- a/ui/src/app/core-model/gen/streampipes-model.ts
+++ b/ui/src/app/core-model/gen/streampipes-model.ts
@@ -19,7 +19,7 @@
 /* tslint:disable */
 /* eslint-disable */
 // @ts-nocheck
-// Generated using typescript-generator version 2.27.744 on 2021-02-08 
23:06:08.
+// Generated using typescript-generator version 2.27.744 on 2021-05-14 
21:55:06.
 
 export class AbstractStreamPipesEntity {
     "@class": "org.apache.streampipes.model.base.AbstractStreamPipesEntity" | 
"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.AdapterStre [...]
@@ -165,6 +165,7 @@ export class AdapterDescription extends 
NamedStreamPipesEntity {
     category: string[];
     config: StaticPropertyUnion[];
     couchDBId: string;
+    createdAt: number;
     eventGrounding: EventGrounding;
     icon: string;
     rules: TransformationRuleDescriptionUnion[];
@@ -187,9 +188,10 @@ 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.createdAt = data.createdAt;
         instance.schemaRules = 
__getCopyArrayFn(__identity<any>())(data.schemaRules);
-        instance.streamRules = 
__getCopyArrayFn(__identity<any>())(data.streamRules);
         instance.valueRules = 
__getCopyArrayFn(__identity<any>())(data.valueRules);
+        instance.streamRules = 
__getCopyArrayFn(__identity<any>())(data.streamRules);
         instance.couchDBId = data.couchDBId;
         instance._rev = data._rev;
         return instance;
@@ -259,6 +261,7 @@ export class AdapterSetDescription extends 
AdapterDescription {
 export class AdapterStreamDescription extends AdapterDescription {
     "@class": 
"org.apache.streampipes.model.connect.adapter.AdapterStreamDescription" | 
"org.apache.streampipes.model.connect.adapter.GenericAdapterStreamDescription" 
| 
"org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription";
     dataStream: SpDataStreamUnion;
+    running: boolean;
 
     static fromData(data: AdapterStreamDescription, target?: 
AdapterStreamDescription): AdapterStreamDescription {
         if (!data) {
@@ -267,6 +270,7 @@ export class AdapterStreamDescription extends 
AdapterDescription {
         const instance = target || new AdapterStreamDescription();
         super.fromData(data, instance);
         instance.dataStream = SpDataStream.fromDataUnion(data.dataStream);
+        instance.running = data.running;
         return instance;
     }
 
@@ -1634,9 +1638,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.protocolDescription = 
ProtocolDescription.fromData(data.protocolDescription);
+        instance.eventSchema = EventSchema.fromData(data.eventSchema);
         return instance;
     }
 }
@@ -1653,9 +1657,9 @@ export class GenericAdapterStreamDescription extends 
AdapterStreamDescription im
         }
         const instance = target || new GenericAdapterStreamDescription();
         super.fromData(data, instance);
-        instance.eventSchema = EventSchema.fromData(data.eventSchema);
-        instance.protocolDescription = 
ProtocolDescription.fromData(data.protocolDescription);
         instance.formatDescription = 
FormatDescription.fromData(data.formatDescription);
+        instance.protocolDescription = 
ProtocolDescription.fromData(data.protocolDescription);
+        instance.eventSchema = EventSchema.fromData(data.eventSchema);
         return instance;
     }
 }

Reply via email to