You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ze...@apache.org on 2024/08/30 12:17:18 UTC

(streampipes) 01/02: feat: First experimental version of a simplified connect API

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

zehnder pushed a commit to branch experiment-simple-connect-api
in repository https://gitbox.apache.org/repos/asf/streampipes.git

commit c7e43871e8328ffed2ebed64c01a1185b882baee
Author: Philipp Zehnder <te...@users.noreply.github.com>
AuthorDate: Tue Aug 20 08:36:31 2024 +0200

    feat: First experimental version of a simplified connect API
---
 .../connect/adapter/simple/SimpleAdapter.java      |  44 +++++++
 .../adapter/simple/SimpleConfiguration.java        |  23 ++++
 .../adapter/simple/SimpleEventProperty.java        |  29 +++++
 .../connect/adapter/simple/SimpleEventSchema.java  |  26 ++++
 .../model/template/PipelineElementTemplate.java    |   2 +
 .../rest/impl/connect/AdapterResource.java         | 112 +++++++++++-----
 .../rest/impl/connect/SimpleAdapterManagement.java | 142 +++++++++++++++++++++
 7 files changed, 344 insertions(+), 34 deletions(-)

diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleAdapter.java b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleAdapter.java
new file mode 100644
index 0000000000..16492f7a43
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleAdapter.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * 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.
+ *
+ */
+
+package org.apache.streampipes.model.connect.adapter.simple;
+
+public record SimpleAdapter(
+    String name,
+    String description,
+    String appId,
+    SimpleConfiguration configuration
+) {}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleConfiguration.java b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleConfiguration.java
new file mode 100644
index 0000000000..399d11c671
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleConfiguration.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.streampipes.model.connect.adapter.simple;
+
+import java.util.Map;
+
+public record SimpleConfiguration(Map<String, String> values) {}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleEventProperty.java b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleEventProperty.java
new file mode 100644
index 0000000000..00f869192f
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleEventProperty.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.streampipes.model.connect.adapter.simple;
+
+public record SimpleEventProperty(
+    String runtimeType,
+    String label,
+    String description,
+    String runtimeName,
+    String propertyScope,
+    String domainProperty
+) {
+}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleEventSchema.java b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleEventSchema.java
new file mode 100644
index 0000000000..f892061705
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/simple/SimpleEventSchema.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.streampipes.model.connect.adapter.simple;
+
+import java.util.List;
+
+public record SimpleEventSchema(
+    List<SimpleEventProperty> properties
+) {
+}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/template/PipelineElementTemplate.java b/streampipes-model/src/main/java/org/apache/streampipes/model/template/PipelineElementTemplate.java
index d304b0f31e..1d398ad30f 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/template/PipelineElementTemplate.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/template/PipelineElementTemplate.java
@@ -23,6 +23,7 @@ import org.apache.streampipes.model.shared.api.Storable;
 import com.fasterxml.jackson.annotation.JsonAlias;
 import com.google.gson.annotations.SerializedName;
 
+import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 
@@ -50,6 +51,7 @@ public class PipelineElementTemplate implements Storable {
 
   public PipelineElementTemplate() {
     this.elementId = UUID.randomUUID().toString();
+    this.templateConfigs = new HashMap<>();
   }
 
   public String getTemplateName() {
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java
index 6d70b8d6e6..2dd514c87b 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java
@@ -18,15 +18,18 @@
 
 package org.apache.streampipes.rest.impl.connect;
 
+import org.apache.streampipes.commons.exceptions.NoServiceEndpointsAvailableException;
 import org.apache.streampipes.commons.exceptions.connect.AdapterException;
 import org.apache.streampipes.commons.prometheus.adapter.AdapterMetricsManager;
 import org.apache.streampipes.connect.management.management.AdapterMasterManagement;
 import org.apache.streampipes.connect.management.management.AdapterUpdateManagement;
+import org.apache.streampipes.extensions.api.connect.exception.WorkerAdapterException;
 import org.apache.streampipes.manager.pipeline.PipelineManager;
 import org.apache.streampipes.model.client.user.Permission;
 import org.apache.streampipes.model.client.user.Role;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
 import org.apache.streampipes.model.connect.adapter.PipelineUpdateInfo;
+import org.apache.streampipes.model.connect.adapter.simple.SimpleAdapter;
 import org.apache.streampipes.model.message.Message;
 import org.apache.streampipes.model.message.Notifications;
 import org.apache.streampipes.model.monitoring.SpLogMessage;
@@ -53,6 +56,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.io.IOException;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -91,9 +95,27 @@ public class AdapterResource extends AbstractAdapterResource<AdapterMasterManage
     return ok(Notifications.success(adapterId));
   }
 
-  @PutMapping(
-      produces = MediaType.APPLICATION_JSON_VALUE,
-      consumes = MediaType.APPLICATION_JSON_VALUE)
+  @PostMapping(
+      path = "simpleAdapter",
+      consumes = MediaType.APPLICATION_JSON_VALUE
+  )
+  @PreAuthorize(AuthConstants.HAS_WRITE_ADAPTER_PRIVILEGE)
+  public ResponseEntity<? extends Message> addSimpleAdapter(
+      @RequestBody SimpleAdapter simpleAdapter
+  ) throws WorkerAdapterException, NoServiceEndpointsAvailableException, IOException {
+
+    var adapterDescription = new SimpleAdapterManagement().convertToAdapterDescription(simpleAdapter);
+
+    // Add adapter
+    this.addAdapter(adapterDescription);
+
+    System.out.println("Name: " + simpleAdapter.name());
+
+    return ok(Notifications.success("It works, yeah"));
+  }
+
+
+  @PutMapping(produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
   @PreAuthorize(AuthConstants.HAS_WRITE_ADAPTER_PRIVILEGE)
   public ResponseEntity<? extends Message> updateAdapter(@RequestBody AdapterDescription adapterDescription) {
     var updateManager = new AdapterUpdateManagement(managementService);
@@ -107,13 +129,12 @@ public class AdapterResource extends AbstractAdapterResource<AdapterMasterManage
     return ok(Notifications.success(adapterDescription.getElementId()));
   }
 
-  @PutMapping(
-      path = "pipeline-migration-preflight",
-      consumes = MediaType.APPLICATION_JSON_VALUE,
-      produces = MediaType.APPLICATION_JSON_VALUE)
+  @PutMapping(path = "pipeline-migration-preflight", consumes = MediaType.APPLICATION_JSON_VALUE,
+              produces = MediaType.APPLICATION_JSON_VALUE)
   @PreAuthorize(AuthConstants.HAS_WRITE_ADAPTER_PRIVILEGE)
   public ResponseEntity<List<PipelineUpdateInfo>> performPipelineMigrationPreflight(
-      @RequestBody AdapterDescription adapterDescription) {
+      @RequestBody AdapterDescription adapterDescription
+  ) {
     var updateManager = new AdapterUpdateManagement(managementService);
     var migrations = updateManager.checkPipelineMigrations(adapterDescription);
 
@@ -160,11 +181,13 @@ public class AdapterResource extends AbstractAdapterResource<AdapterMasterManage
 
   @DeleteMapping(path = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
   @PreAuthorize(AuthConstants.HAS_DELETE_ADAPTER_PRIVILEGE)
-  public ResponseEntity<?> deleteAdapter(@PathVariable("id") String elementId,
-                                         @RequestParam(value = "deleteAssociatedPipelines", defaultValue = "false")
-                                         boolean deleteAssociatedPipelines) {
+  public ResponseEntity<?> deleteAdapter(
+      @PathVariable("id") String elementId,
+      @RequestParam(value = "deleteAssociatedPipelines", defaultValue = "false") boolean deleteAssociatedPipelines
+  ) {
     List<String> pipelinesUsingAdapter = getPipelinesUsingAdapter(elementId);
-    IPipelineStorage pipelineStorageAPI = StorageDispatcher.INSTANCE.getNoSqlStore().getPipelineStorageAPI();
+    IPipelineStorage pipelineStorageAPI = StorageDispatcher.INSTANCE.getNoSqlStore()
+                                                                    .getPipelineStorageAPI();
 
     if (pipelinesUsingAdapter.isEmpty()) {
       try {
@@ -175,22 +198,41 @@ public class AdapterResource extends AbstractAdapterResource<AdapterMasterManage
         return ok(Notifications.error(e.getMessage()));
       }
     } else if (!deleteAssociatedPipelines) {
-      List<String> namesOfPipelinesUsingAdapter =
-          pipelinesUsingAdapter.stream().map(pipelineId -> pipelineStorageAPI.getElementById(pipelineId).getName())
-              .collect(
-                  Collectors.toList());
-      return ResponseEntity.status(HttpStatus.SC_CONFLICT).body(String.join(", ", namesOfPipelinesUsingAdapter));
+      List<String> namesOfPipelinesUsingAdapter = pipelinesUsingAdapter
+          .stream()
+          .map(pipelineId -> pipelineStorageAPI.getElementById(
+                                                   pipelineId)
+                                               .getName())
+          .collect(Collectors.toList());
+      return ResponseEntity.status(HttpStatus.SC_CONFLICT)
+                           .body(String.join(", ", namesOfPipelinesUsingAdapter));
     } else {
       PermissionResourceManager permissionResourceManager = new PermissionResourceManager();
       // find out the names of pipelines that have an owner and the owner is not the current user
-      List<String> namesOfPipelinesNotOwnedByUser = pipelinesUsingAdapter.stream().filter(pipelineId ->
-              !permissionResourceManager.findForObjectId(pipelineId).stream().findFirst().map(Permission::getOwnerSid)
-                  // if a pipeline has no owner, pretend the owner is the user so the user can delete it
-                  .orElse(this.getAuthenticatedUserSid()).equals(this.getAuthenticatedUserSid()))
-          .map(pipelineId -> pipelineStorageAPI.getElementById(pipelineId).getName()).collect(Collectors.toList());
-      boolean isAdmin = SecurityContextHolder.getContext().getAuthentication().getAuthorities().stream()
-          .anyMatch(r -> r.getAuthority().equals(
-              Role.ROLE_ADMIN.name()));
+      List<String> namesOfPipelinesNotOwnedByUser = pipelinesUsingAdapter
+          .stream()
+          .filter(pipelineId -> !permissionResourceManager.findForObjectId(
+                                                              pipelineId)
+                                                          .stream()
+                                                          .findFirst()
+                                                          .map(
+                                                              Permission::getOwnerSid)
+                                                          // if a pipeline has no owner, pretend the owner
+                                                          // is the user so the user can delete it
+                                                          .orElse(
+                                                              this.getAuthenticatedUserSid())
+                                                          .equals(
+                                                              this.getAuthenticatedUserSid()))
+          .map(pipelineId -> pipelineStorageAPI.getElementById(
+                                                   pipelineId)
+                                               .getName())
+          .collect(Collectors.toList());
+      boolean isAdmin = SecurityContextHolder.getContext()
+                                             .getAuthentication()
+                                             .getAuthorities()
+                                             .stream()
+                                             .anyMatch(r -> r.getAuthority()
+                                                             .equals(Role.ROLE_ADMIN.name()));
       // if the user is admin or owns all pipelines using this adapter,
       // the user can delete all associated pipelines and this adapter
       if (isAdmin || namesOfPipelinesNotOwnedByUser.isEmpty()) {
@@ -200,15 +242,17 @@ public class AdapterResource extends AbstractAdapterResource<AdapterMasterManage
             PipelineManager.deletePipeline(pipelineId);
           }
           managementService.deleteAdapter(elementId);
-          return ok(Notifications.success(
-              "Adapter with id: " + elementId + " and all pipelines using the adapter are deleted."));
+          return ok(Notifications.success("Adapter with id: " + elementId
+                                              + " and all pipelines using the adapter are deleted."));
         } catch (Exception e) {
-          LOG.error("Error while deleting adapter with id " + elementId + " and all pipelines using the adapter", e);
+          LOG.error("Error while deleting adapter with id "
+                        + elementId + " and all pipelines using the adapter", e);
           return ok(Notifications.error(e.getMessage()));
         }
       } else {
         // otherwise, hint the user the names of pipelines using the adapter but not owned by the user
-        return ResponseEntity.status(HttpStatus.SC_CONFLICT).body(String.join(", ", namesOfPipelinesNotOwnedByUser));
+        return ResponseEntity.status(HttpStatus.SC_CONFLICT)
+                             .body(String.join(", ", namesOfPipelinesNotOwnedByUser));
       }
     }
   }
@@ -220,7 +264,8 @@ public class AdapterResource extends AbstractAdapterResource<AdapterMasterManage
       return ok(managementService.getAllAdapterInstances());
     } catch (AdapterException e) {
       LOG.error("Error while getting all adapters", e);
-      return ResponseEntity.status(500).build();
+      return ResponseEntity.status(500)
+                           .build();
     }
   }
 
@@ -229,10 +274,9 @@ public class AdapterResource extends AbstractAdapterResource<AdapterMasterManage
   }
 
   private List<String> getPipelinesUsingAdapter(String adapterId) {
-    return StorageDispatcher.INSTANCE
-        .getNoSqlStore()
-        .getPipelineStorageAPI()
-        .getPipelinesUsingAdapter(adapterId);
+    return StorageDispatcher.INSTANCE.getNoSqlStore()
+                                     .getPipelineStorageAPI()
+                                     .getPipelinesUsingAdapter(adapterId);
   }
 
 }
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/SimpleAdapterManagement.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/SimpleAdapterManagement.java
new file mode 100644
index 0000000000..1084a11993
--- /dev/null
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/SimpleAdapterManagement.java
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.streampipes.rest.impl.connect;
+
+import org.apache.streampipes.commons.exceptions.NoServiceEndpointsAvailableException;
+import org.apache.streampipes.connect.management.management.GuessManagement;
+import org.apache.streampipes.extensions.api.connect.exception.WorkerAdapterException;
+import org.apache.streampipes.manager.template.AdapterTemplateHandler;
+import org.apache.streampipes.model.connect.adapter.AdapterDescription;
+import org.apache.streampipes.model.connect.adapter.simple.SimpleAdapter;
+import org.apache.streampipes.model.connect.adapter.simple.SimpleEventProperty;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventPropertyPrimitive;
+import org.apache.streampipes.model.template.PipelineElementTemplate;
+import org.apache.streampipes.model.template.PipelineElementTemplateConfig;
+import org.apache.streampipes.storage.api.IAdapterStorage;
+import org.apache.streampipes.storage.couchdb.CouchDbStorageManager;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+
+public class SimpleAdapterManagement {
+  public AdapterDescription convertToAdapterDescription(SimpleAdapter simpleAdapter)
+      throws WorkerAdapterException,
+             NoServiceEndpointsAvailableException,
+             IOException {
+
+    // Get the adapter description from the registed adapters
+    var adapterDescription = findAdapterDescription(simpleAdapter.appId());
+
+    // Set basic configurations
+    setNameAndDescription(adapterDescription, simpleAdapter);
+
+    // Fill out user configurations
+    applyUserConfiguraition(adapterDescription, simpleAdapter);
+
+    // Set event schema
+    addEventSchema(adapterDescription);
+
+    return adapterDescription;
+  }
+
+  private void addEventSchema(
+      AdapterDescription adapterDescription) throws WorkerAdapterException, NoServiceEndpointsAvailableException, IOException {
+
+    var guessManagement = new GuessManagement();
+    GuessSchema result = guessManagement.guessSchema(adapterDescription);
+    adapterDescription.getDataStream().setEventSchema(result.getEventSchema());
+
+//    var eventProperties = simpleAdapter.eventSchema()
+//                                       .properties()
+//                                       .stream()
+//                                       .map(simpleEventProperty -> simpleEventPropertyToEventProperty(
+//                                           simpleEventProperty))
+//                                       .toList();
+//
+//    var eventSchema = new EventSchema(eventProperties);
+//    adapterDescription.getDataStream()
+//                      .setEventSchema(eventSchema);
+  }
+
+
+  private EventProperty simpleEventPropertyToEventProperty(
+      SimpleEventProperty simpleEventProperty
+  ) {
+    var eventPropertyPrimitive = new EventPropertyPrimitive();
+    eventPropertyPrimitive.setRuntimeType(simpleEventProperty.runtimeType());
+    eventPropertyPrimitive.setLabel(simpleEventProperty.label());
+    eventPropertyPrimitive.setDescription(simpleEventProperty.description());
+    eventPropertyPrimitive.setRuntimeName(simpleEventProperty.runtimeName());
+    eventPropertyPrimitive.setPropertyScope(simpleEventProperty.propertyScope());
+    if (simpleEventProperty.domainProperty() != null && !simpleEventProperty.domainProperty()
+                                                                            .equals("")) {
+      var url = URI.create(simpleEventProperty.domainProperty());
+      eventPropertyPrimitive.setDomainProperties(List.of(url));
+    }
+
+    return eventPropertyPrimitive;
+  }
+
+  private void applyUserConfiguraition(
+      AdapterDescription adapterDescription,
+      SimpleAdapter simpleAdapter
+  ) {
+
+    var adapterTemplate = new PipelineElementTemplate();
+    var templateConfigs = simpleAdapter.configuration();
+
+    templateConfigs.values()
+                   .forEach((key, value) -> {
+                     PipelineElementTemplateConfig config = new PipelineElementTemplateConfig();
+                     // Assuming PipelineElementTemplateConfig has a method to set key and value
+                     config.setValue(value);
+                     adapterTemplate.getTemplateConfigs()
+                                    .put(key, config);
+                   });
+
+    new AdapterTemplateHandler(
+        adapterTemplate, adapterDescription,
+        false
+    )
+        .applyTemplateOnPipelineElement();
+  }
+
+  private void setNameAndDescription(
+      AdapterDescription adapterDescription,
+      SimpleAdapter simpleAdapter
+  ) {
+    adapterDescription.setName(simpleAdapter.name());
+    adapterDescription.setDescription(simpleAdapter.description());
+  }
+
+  private AdapterDescription findAdapterDescription(String appId) {
+    IAdapterStorage adapterStorage = CouchDbStorageManager.INSTANCE.getAdapterDescriptionStorage();
+    return adapterStorage.findAll()
+                         .stream()
+                         .filter(desc -> desc.getAppId()
+                                             .equals(appId))
+                         .findFirst()
+                         .get();
+
+  }
+
+}