You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2022/07/31 21:20:26 UTC

[incubator-streampipes] branch STREAMPIPES-545 updated (b2c30519a -> 0f37e31f3)

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

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


    from b2c30519a [hotfix] Change order in installation skript
     new 3a30261a0 [hotfix] Write tags in data explorer
     new 85eec4db2 [hotfix] Extend data explorer API, add menu layout to base css
     new eae8d4e8b [hotfix] Extend data explorer query builder
     new bfa035132 [STREAMPIPES-545] Support data source links
     new d6581497f [STREAMPIPES-545] Move adapter API to platform-services module
     new 0f37e31f3 [STREAMPIPES-565] Add data export feature

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .gitignore                                         |   2 +-
 pom.xml                                            |   4 +
 .../backend/StreamPipesResourceConfig.java         |   1 +
 streampipes-data-explorer-commons/pom.xml          |  19 ++-
 .../dataexplorer/commons/DataExplorerWriter.java   |  19 ++-
 .../dataexplorer/sdk/DataLakeQueryBuilder.java     |   8 +-
 .../dataexplorer/sdk/DataLakeQueryOrdering.java    |  18 ++
 .../pom.xml                                        |   8 +-
 .../streampipes/export/AssetLinkCollector.java     |  39 +++--
 .../streampipes/export/AssetLinkResolver.java      |  83 +++++++++
 .../apache/streampipes/export/ExportManager.java   |  33 ++--
 .../export/constants/ResolvableAssetLinks.java     |  15 +-
 .../export/generator/ExportPackageGenerator.java   | 152 +++++++++++++++++
 .../export/generator/ZipFileBuilder.java           | 113 ++++++++++++
 .../export/resolver/AbstractResolver.java          |  53 ++++++
 .../export/resolver/AdapterResolver.java           |  25 ++-
 .../export/resolver/DashboardResolver.java         |  26 ++-
 .../export/resolver/DashboardWidgetResolver.java   |  23 ++-
 .../export/resolver/DataSourceResolver.java        |  20 ++-
 .../export/resolver/DataViewResolver.java          |  27 ++-
 .../export/resolver/DataViewWidgetResolver.java    |  23 ++-
 .../export/resolver/MeasurementResolver.java       |  19 ++-
 .../export/resolver/PipelineResolver.java          |  21 ++-
 .../export/utils/SerializationUtils.java           |  17 +-
 .../sinks/internal/jvm/datalake/DataLakeUtils.java |   3 +-
 .../apache/streampipes/model/assets/AssetLink.java |  24 +++
 .../model/export/AssetExportConfiguration.java     | 120 +++++++++++++
 .../ExportConfiguration.java}                      |  36 ++--
 .../streampipes/model/export/ExportItem.java       |  33 ++--
 .../export/StreamPipesApplicationPackage.java      | 190 +++++++++++++++++++++
 .../setup/tasks/CreateAssetLinkTypeTask.java       |   4 +-
 streampipes-rest/pom.xml                           |   5 +
 ...issionResource.java => DataExportResource.java} |  46 ++---
 .../src/lib/apis/adapter.service.ts}               |  39 +----
 .../lib/apis/data-view-data-explorer.service.ts    |   6 +
 .../src/lib/model/assets/asset.model.ts            |   1 +
 .../src/lib/model/gen/streampipes-model.ts         | 102 +++++++++--
 .../platform-services/src/public-api.ts            |   1 +
 .../asset-details-panel.component.ts               |   9 +-
 .../edit-asset-link-dialog.component.html          |  24 +++
 .../edit-asset-link-dialog.component.ts            |  32 +++-
 ui/src/app/configuration/configuration-tabs.ts     |   1 +
 ui/src/app/configuration/configuration.module.ts   |  12 ++
 .../datalake-configuration.component.html          |  13 +-
 .../export/data-export-import.component.html       |  52 ++++++
 .../export/data-export-import.component.scss}      |   0
 .../export/data-export-import.component.ts         |  81 +++++++++
 .../export/data-export.service.ts}                 |  27 +--
 .../data-export-dialog.component.html              |  49 ++++++
 .../data-export-dialog.component.scss}             |   0
 .../export-dialog/data-export-dialog.component.ts  |  63 +++++++
 .../data-export-item.component.html}               |  14 +-
 .../data-export-item.component.scss}               |   0
 .../data-export-item.component.ts}                 |  20 ++-
 .../data-import-dialog.component.html}             |   2 -
 .../data-import-dialog.component.scss}             |   0
 .../import-dialog/data-import-dialog.component.ts} |  11 +-
 .../messaging-configuration.component.ts           |   2 +-
 .../pipeline-element-configuration.component.ts    |   2 +-
 .../security-configuration.component.ts            |   2 +-
 .../adapter-description.component.ts               |   5 +-
 .../data-marketplace/data-marketplace.component.ts |   5 +-
 .../existing-adapters.component.ts                 |   5 +-
 .../filter-toolbar/filter-toolbar.component.ts     |   4 +-
 .../new-adapter/new-adapter.component.ts           |   6 +-
 ui/src/app/connect/connect.module.ts               |   2 -
 .../delete-adapter-dialog.component.ts             |   5 +-
 ui/src/app/connect/services/connect.service.ts     |  21 +++
 ui/src/scss/_variables.scss                        |   3 +-
 ui/src/scss/sp/layout.scss                         |   3 +
 70 files changed, 1551 insertions(+), 302 deletions(-)
 copy {streampipes-service-discovery => streampipes-data-export}/pom.xml (88%)
 copy streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateDefaultAssetTask.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/AssetLinkCollector.java (52%)
 create mode 100644 streampipes-data-export/src/main/java/org/apache/streampipes/export/AssetLinkResolver.java
 copy streampipes-maven-plugin/src/main/java/org/apache/streampipes/smp/util/DuplicateRemover.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/ExportManager.java (51%)
 copy streampipes-client/src/main/java/org/apache/streampipes/client/credentials/CredentialsProvider.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/constants/ResolvableAssetLinks.java (66%)
 create mode 100644 streampipes-data-export/src/main/java/org/apache/streampipes/export/generator/ExportPackageGenerator.java
 create mode 100644 streampipes-data-export/src/main/java/org/apache/streampipes/export/generator/ZipFileBuilder.java
 create mode 100644 streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/AbstractResolver.java
 copy streampipes-connect/src/main/java/org/apache/streampipes/connect/adapter/model/specific/SpecificAdapter.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/AdapterResolver.java (64%)
 copy streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IDashboardStorage.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DashboardResolver.java (53%)
 copy streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IDashboardWidgetStorage.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DashboardWidgetResolver.java (62%)
 copy streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/matching/mapping/AbstractRequirementsSelectorGenerator.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataSourceResolver.java (64%)
 copy streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IDashboardStorage.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataViewResolver.java (53%)
 copy streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IDataExplorerWidgetStorage.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataViewWidgetResolver.java (62%)
 copy streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IDataLakeStorage.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/MeasurementResolver.java (64%)
 copy streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/permission/PermissionManager.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/PipelineResolver.java (65%)
 copy streampipes-serializers-json/src/main/java/org/apache/streampipes/serializers/json/JacksonSerializer.java => streampipes-data-export/src/main/java/org/apache/streampipes/export/utils/SerializationUtils.java (70%)
 create mode 100644 streampipes-model/src/main/java/org/apache/streampipes/model/export/AssetExportConfiguration.java
 copy streampipes-model/src/main/java/org/apache/streampipes/model/{message/SuccessMessage.java => export/ExportConfiguration.java} (62%)
 copy streampipes-sdk/src/main/java/org/apache/streampipes/sdk/helpers/Label.java => streampipes-model/src/main/java/org/apache/streampipes/model/export/ExportItem.java (64%)
 create mode 100644 streampipes-model/src/main/java/org/apache/streampipes/model/export/StreamPipesApplicationPackage.java
 copy streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/{PermissionResource.java => DataExportResource.java} (53%)
 rename ui/{src/app/connect/services/data-marketplace.service.ts => projects/streampipes/platform-services/src/lib/apis/adapter.service.ts} (68%)
 create mode 100644 ui/src/app/configuration/export/data-export-import.component.html
 copy ui/src/app/{apidocs/apidocs.component.scss => configuration/export/data-export-import.component.scss} (100%)
 create mode 100644 ui/src/app/configuration/export/data-export-import.component.ts
 copy ui/src/app/{login/services/restore-password.service.ts => configuration/export/data-export.service.ts} (56%)
 create mode 100644 ui/src/app/configuration/export/export-dialog/data-export-dialog.component.html
 copy ui/src/app/{connect/dialog/adapter-template/adapter-template-dialog.component.scss => configuration/export/export-dialog/data-export-dialog.component.scss} (100%)
 create mode 100644 ui/src/app/configuration/export/export-dialog/data-export-dialog.component.ts
 copy ui/src/app/{dashboard/components/widgets/image/image-widget.component.html => configuration/export/export-dialog/data-export-item/data-export-item.component.html} (74%)
 copy ui/src/app/{apidocs/apidocs.component.scss => configuration/export/export-dialog/data-export-item/data-export-item.component.scss} (100%)
 copy ui/src/app/{connect/dialog/edit-event-property/components/ep-settings-section/ep-settings-section.component.ts => configuration/export/export-dialog/data-export-item/data-export-item.component.ts} (66%)
 copy ui/src/{assets/templates/error.html => app/configuration/export/import-dialog/data-import-dialog.component.html} (98%)
 copy ui/src/app/{connect/dialog/adapter-template/adapter-template-dialog.component.scss => configuration/export/import-dialog/data-import-dialog.component.scss} (100%)
 copy ui/src/app/{data-explorer/components/widgets/utils/load-data-spinner/load-data-spinner.component.ts => configuration/export/import-dialog/data-import-dialog.component.ts} (80%)


[incubator-streampipes] 03/06: [hotfix] Extend data explorer query builder

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit eae8d4e8bb3e6e6b0a6071996d3f499fca622432
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Sun Jul 31 08:45:49 2022 +0200

    [hotfix] Extend data explorer query builder
---
 .../apache/streampipes/dataexplorer/sdk/DataLakeQueryBuilder.java | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/sdk/DataLakeQueryBuilder.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/sdk/DataLakeQueryBuilder.java
index bff07c4dd..2dfacdeb9 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/sdk/DataLakeQueryBuilder.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/sdk/DataLakeQueryBuilder.java
@@ -82,7 +82,13 @@ public class DataLakeQueryBuilder {
 
 
   public DataLakeQueryBuilder withEndTime(long endTime) {
-    this.whereClauses.add(new SimpleClause("time", "<=", endTime * 1000000));
+    return withEndTime(endTime, true);
+  }
+
+  public DataLakeQueryBuilder withEndTime(long endTime,
+                                          boolean includeEndTime) {
+    String operator = includeEndTime ? "<=" : "<";
+    this.whereClauses.add(new SimpleClause("time", operator, endTime * 1000000));
     return this;
   }
 


[incubator-streampipes] 06/06: [STREAMPIPES-565] Add data export feature

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0f37e31f3f8c82feed16e3a02d61cb8a0c1d117b
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Sun Jul 31 23:20:12 2022 +0200

    [STREAMPIPES-565] Add data export feature
---
 .gitignore                                         |   2 +-
 pom.xml                                            |   4 +
 .../backend/StreamPipesResourceConfig.java         |   1 +
 streampipes-data-explorer-commons/pom.xml          |  19 ++-
 .../dataexplorer/commons/DataExplorerWriter.java   |  17 ++
 .../dataexplorer/sdk/DataLakeQueryOrdering.java    |  18 ++
 streampipes-data-export/pom.xml                    |  44 +++++
 .../streampipes/export/AssetLinkCollector.java     |  50 ++++++
 .../streampipes/export/AssetLinkResolver.java      |  83 +++++++++
 .../apache/streampipes/export/ExportManager.java   |  46 +++++
 .../export/constants/ResolvableAssetLinks.java     |  26 +--
 .../export/generator/ExportPackageGenerator.java   | 152 +++++++++++++++++
 .../export/generator/ZipFileBuilder.java           | 113 ++++++++++++
 .../export/resolver/AbstractResolver.java          |  53 ++++++
 .../export/resolver/AdapterResolver.java           |  25 ++-
 .../export/resolver/DashboardResolver.java         |  44 +++++
 .../export/resolver/DashboardWidgetResolver.java   |  24 ++-
 .../export/resolver/DataSourceResolver.java        |  24 ++-
 .../export/resolver/DataViewResolver.java          |  45 +++++
 .../export/resolver/DataViewWidgetResolver.java    |  24 ++-
 .../export/resolver/MeasurementResolver.java       |  24 ++-
 .../export/resolver/PipelineResolver.java          |  24 ++-
 .../export/utils/SerializationUtils.java           |  26 ++-
 .../sinks/internal/jvm/datalake/DataLakeUtils.java |   3 +-
 .../apache/streampipes/model/assets/AssetLink.java |  24 +++
 .../model/export/AssetExportConfiguration.java     | 120 +++++++++++++
 .../model/export/ExportConfiguration.java          |  30 ++--
 .../AssetLink.java => export/ExportItem.java}      |  41 +++--
 .../export/StreamPipesApplicationPackage.java      | 190 +++++++++++++++++++++
 streampipes-rest/pom.xml                           |   5 +
 .../rest/impl/admin/DataExportResource.java        |  60 +++++++
 .../src/lib/model/assets/asset.model.ts            |   1 +
 .../src/lib/model/gen/streampipes-model.ts         | 102 +++++++++--
 .../asset-details-panel.component.ts               |   9 +-
 .../edit-asset-link-dialog.component.html          |  12 ++
 .../edit-asset-link-dialog.component.ts            |  22 ++-
 ui/src/app/configuration/configuration-tabs.ts     |   1 +
 ui/src/app/configuration/configuration.module.ts   |  12 ++
 .../export/data-export-import.component.html       |  52 ++++++
 .../export/data-export-import.component.scss       |  22 ---
 .../export/data-export-import.component.ts         |  81 +++++++++
 .../configuration/export/data-export.service.ts    |  46 +++++
 .../data-export-dialog.component.html              |  49 ++++++
 .../data-export-dialog.component.scss              |  22 +--
 .../export-dialog/data-export-dialog.component.ts  |  63 +++++++
 .../data-export-item.component.html                |  26 +++
 .../data-export-item.component.scss                |  22 ---
 .../data-export-item/data-export-item.component.ts |  34 ++--
 .../data-import-dialog.component.html              |  17 ++
 .../data-import-dialog.component.scss              |  22 +--
 .../import-dialog/data-import-dialog.component.ts} |  17 +-
 .../messaging-configuration.component.ts           |   2 +-
 .../pipeline-element-configuration.component.ts    |   2 +-
 .../security-configuration.component.ts            |   2 +-
 54 files changed, 1708 insertions(+), 291 deletions(-)

diff --git a/.gitignore b/.gitignore
index 4b3258fc0..324db8704 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,7 +83,7 @@ npm-debug.log
 /test_data/
 
 ui/src/assets/lib/apps/*
-
+ui/.angular
 
 # compiled output
 ui/dist
diff --git a/pom.xml b/pom.xml
index 575df68cf..be1159d57 100644
--- a/pom.xml
+++ b/pom.xml
@@ -957,6 +957,7 @@ IoT data streams.
 			<module>streampipes-resource-management</module>
 			<module>streampipes-sdk-bundle</module>
             <module>streampipes-data-explorer-commons</module>
+            <module>streampipes-data-export</module>
         </modules>
 
 		<profiles>
@@ -1273,6 +1274,9 @@ IoT data streams.
 						<!-- Exclude some UI files which we need to check in more detail -->
 						<exclude>ui/src/assets/img/svg/**</exclude>
 
+						<!-- Exclude .angular folder -->
+						<exclude>ui/.angular/**</exclude>
+
 						<!-- Exclude disclaimer and notice files -->
 						<exclude>DISCLAIMER</exclude>
 						<exclude>NOTICE-binary</exclude>
diff --git a/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesResourceConfig.java b/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesResourceConfig.java
index 0a6efad7b..4924a5352 100644
--- a/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesResourceConfig.java
+++ b/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesResourceConfig.java
@@ -62,6 +62,7 @@ public class StreamPipesResourceConfig extends ResourceConfig {
         register(ContainerProvidedOptions.class);
         register(DashboardWidget.class);
         register(Dashboard.class);
+        register(DataExportResource.class);
         register(DataLakeImageResource.class);
         register(DataLakeResourceV3.class);
         register(DataLakeMeasureResourceV3.class);
diff --git a/streampipes-data-explorer-commons/pom.xml b/streampipes-data-explorer-commons/pom.xml
index 2d14cd7e1..999370c82 100644
--- a/streampipes-data-explorer-commons/pom.xml
+++ b/streampipes-data-explorer-commons/pom.xml
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@@ -46,4 +63,4 @@
         <maven.compiler.target>11</maven.compiler.target>
     </properties>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/streampipes-data-explorer-commons/src/main/java/org/apache/streampipes/dataexplorer/commons/DataExplorerWriter.java b/streampipes-data-explorer-commons/src/main/java/org/apache/streampipes/dataexplorer/commons/DataExplorerWriter.java
index afb7387e2..a44b93b79 100644
--- a/streampipes-data-explorer-commons/src/main/java/org/apache/streampipes/dataexplorer/commons/DataExplorerWriter.java
+++ b/streampipes-data-explorer-commons/src/main/java/org/apache/streampipes/dataexplorer/commons/DataExplorerWriter.java
@@ -1,3 +1,20 @@
+/*
+ * 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.dataexplorer.commons;
 
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/sdk/DataLakeQueryOrdering.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/sdk/DataLakeQueryOrdering.java
index b187cd38a..6952d0dcc 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/sdk/DataLakeQueryOrdering.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/sdk/DataLakeQueryOrdering.java
@@ -1,3 +1,21 @@
+/*
+ * 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.dataexplorer.sdk;
 
 public enum DataLakeQueryOrdering {
diff --git a/streampipes-data-export/pom.xml b/streampipes-data-export/pom.xml
new file mode 100644
index 000000000..216981d8b
--- /dev/null
+++ b/streampipes-data-export/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>streampipes-parent</artifactId>
+        <groupId>org.apache.streampipes</groupId>
+        <version>0.70.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>streampipes-data-export</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.streampipes</groupId>
+            <artifactId>streampipes-model</artifactId>
+            <version>0.70.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.streampipes</groupId>
+            <artifactId>streampipes-storage-management</artifactId>
+            <version>0.70.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/streampipes-data-export/src/main/java/org/apache/streampipes/export/AssetLinkCollector.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/AssetLinkCollector.java
new file mode 100644
index 000000000..ba3e16df8
--- /dev/null
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/AssetLinkCollector.java
@@ -0,0 +1,50 @@
+/*
+ * 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.export;
+
+import org.apache.streampipes.model.assets.AssetLink;
+import org.apache.streampipes.model.assets.SpAsset;
+import org.apache.streampipes.model.assets.SpAssetModel;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class AssetLinkCollector {
+
+  private SpAssetModel assetModel;
+
+  public AssetLinkCollector(SpAssetModel assetModel) {
+    this.assetModel = assetModel;
+  }
+
+  public Set<AssetLink> collectAssetLinks() {
+    var assetLinks = new HashSet<>(assetModel.getAssetLinks());
+    assetModel.getAssets().forEach(asset -> addLinks(assetLinks, asset));
+
+    return assetLinks;
+  }
+
+  private void addLinks(HashSet<AssetLink> assetLinks,
+                        SpAsset asset) {
+    assetLinks.addAll(asset.getAssetLinks());
+    if (asset.getAssets() != null) {
+      asset.getAssets().forEach(a -> addLinks(assetLinks, a));
+    }
+  }
+}
diff --git a/streampipes-data-export/src/main/java/org/apache/streampipes/export/AssetLinkResolver.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/AssetLinkResolver.java
new file mode 100644
index 000000000..795c88f3e
--- /dev/null
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/AssetLinkResolver.java
@@ -0,0 +1,83 @@
+/*
+ * 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.export;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.streampipes.export.constants.ResolvableAssetLinks;
+import org.apache.streampipes.export.resolver.*;
+import org.apache.streampipes.export.utils.SerializationUtils;
+import org.apache.streampipes.model.assets.AssetLink;
+import org.apache.streampipes.model.assets.SpAssetModel;
+import org.apache.streampipes.model.export.AssetExportConfiguration;
+import org.apache.streampipes.storage.management.StorageDispatcher;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class AssetLinkResolver {
+
+  private final String assetId;
+  private final ObjectMapper mapper;
+
+  public AssetLinkResolver(String assetId) {
+    this.assetId = assetId;
+    this.mapper = SerializationUtils.getDefaultObjectMapper();
+  }
+
+  public AssetExportConfiguration resolveResources() {
+
+    try {
+      var asset = getAsset();
+      var assetLinks = new AssetLinkCollector(asset).collectAssetLinks();
+      var exportConfig = new AssetExportConfiguration();
+      exportConfig.setAssetId(this.assetId);
+      exportConfig.setAssetName(asset.getAssetName());
+      exportConfig.setAdapters(new AdapterResolver().resolve(getLinks(assetLinks, ResolvableAssetLinks.ADAPTER)));
+      exportConfig.setDashboards(new DashboardResolver().resolve(getLinks(assetLinks, ResolvableAssetLinks.DASHBOARD)));
+      exportConfig.setDataViews(new DataViewResolver().resolve(getLinks(assetLinks, ResolvableAssetLinks.DATA_VIEW)));
+      exportConfig.setDataSources(new DataSourceResolver().resolve(getLinks(assetLinks, ResolvableAssetLinks.DATA_SOURCE)));
+      exportConfig.setPipelines(new PipelineResolver().resolve(getLinks(assetLinks, ResolvableAssetLinks.PIPELINE)));
+      exportConfig.setDataLakeMeasures(new MeasurementResolver().resolve(getLinks(assetLinks, ResolvableAssetLinks.MEASUREMENT)));
+
+      return exportConfig;
+    } catch (IOException e) {
+      e.printStackTrace();
+      return new AssetExportConfiguration();
+    }
+  }
+
+  private Set<AssetLink> getLinks(Set<AssetLink> assetLinks,
+                                  String queryHint) {
+    return assetLinks
+      .stream()
+      .filter(link -> link.getQueryHint().equals(queryHint))
+      .collect(Collectors.toSet());
+  }
+
+  private SpAssetModel getAsset() throws IOException {
+    return deserialize(StorageDispatcher.INSTANCE.getNoSqlStore().getGenericStorage().findOne(this.assetId));
+  }
+
+  private SpAssetModel deserialize(Map<String, Object> asset) {
+    return this.mapper.convertValue(asset, SpAssetModel.class);
+  }
+
+}
diff --git a/streampipes-data-export/src/main/java/org/apache/streampipes/export/ExportManager.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/ExportManager.java
new file mode 100644
index 000000000..1ceaa5405
--- /dev/null
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/ExportManager.java
@@ -0,0 +1,46 @@
+/*
+ * 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.export;
+
+import org.apache.streampipes.export.generator.ExportPackageGenerator;
+import org.apache.streampipes.model.export.ExportConfiguration;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ExportManager {
+  
+  public static ExportConfiguration getExportPreview(List<String> selectedAssetIds) {
+    var exportConfig = new ExportConfiguration();
+    var assetExportConfigurations = selectedAssetIds
+      .stream()
+      .map(assetId -> new AssetLinkResolver(assetId).resolveResources())
+      .collect(Collectors.toList());
+
+    exportConfig.setAssetExportConfiguration(assetExportConfigurations);
+
+    return exportConfig;
+  }
+
+  public static byte[] getExportPackage(ExportConfiguration exportConfiguration) throws IOException {
+    return new ExportPackageGenerator(exportConfiguration).generateExportPackage();
+  }
+
+}
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/constants/ResolvableAssetLinks.java
similarity index 55%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to streampipes-data-export/src/main/java/org/apache/streampipes/export/constants/ResolvableAssetLinks.java
index 8fa1736b3..d3c9cd721 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/constants/ResolvableAssetLinks.java
@@ -16,24 +16,14 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
+package org.apache.streampipes.export.constants;
 
-public class DataLakeUtils {
+public class ResolvableAssetLinks {
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
-
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
-  }
-
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
-  }
+  public static final String DATA_VIEW = "data-view";
+  public static final String DASHBOARD = "dashboard";
+  public static final String MEASUREMENT = "measurement";
+  public static final String ADAPTER = "adapter";
+  public static final String DATA_SOURCE = "data-source";
+  public static final String PIPELINE = "pipeline";
 }
diff --git a/streampipes-data-export/src/main/java/org/apache/streampipes/export/generator/ExportPackageGenerator.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/generator/ExportPackageGenerator.java
new file mode 100644
index 000000000..832ae826b
--- /dev/null
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/generator/ExportPackageGenerator.java
@@ -0,0 +1,152 @@
+/*
+ * 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.export.generator;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.streampipes.export.resolver.*;
+import org.apache.streampipes.export.utils.SerializationUtils;
+import org.apache.streampipes.model.export.AssetExportConfiguration;
+import org.apache.streampipes.model.export.ExportConfiguration;
+import org.apache.streampipes.model.export.ExportItem;
+import org.apache.streampipes.model.export.StreamPipesApplicationPackage;
+import org.apache.streampipes.storage.management.StorageDispatcher;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+public class ExportPackageGenerator {
+
+  private final ExportConfiguration exportConfiguration;
+  private ObjectMapper defaultMapper;
+  private ObjectMapper spMapper;
+
+  public ExportPackageGenerator(ExportConfiguration exportConfiguration) {
+    this.exportConfiguration = exportConfiguration;
+    this.defaultMapper = SerializationUtils.getDefaultObjectMapper();
+    this.spMapper = SerializationUtils.getSpObjectMapper();
+  }
+
+  public byte[] generateExportPackage() throws IOException {
+    ZipFileBuilder builder = ZipFileBuilder.create();
+    var manifest = new StreamPipesApplicationPackage();
+
+    addAssets(builder, exportConfiguration
+      .getAssetExportConfiguration()
+      .stream()
+      .map(AssetExportConfiguration::getAssetId)
+      .collect(Collectors.toList()));
+
+    this.exportConfiguration.getAssetExportConfiguration().forEach(config -> {
+
+      config.getAdapters().forEach(item -> addDoc(builder,
+        item,
+        new AdapterResolver(),
+        manifest::addAdapter));
+
+      config.getDashboards().forEach(item -> {
+        var resolver = new DashboardResolver();
+        addDoc(builder,
+          item,
+          resolver,
+          manifest::addDashboard);
+
+        var widgets = resolver.getWidgets(item.getResourceId());
+        var widgetResolver = new DashboardWidgetResolver();
+        widgets.forEach(widgetId -> addDoc(builder, widgetId, widgetResolver, manifest::addDashboardWidget));
+      });
+
+      config.getDataSources().forEach(item -> addDoc(builder,
+        item,
+        new DataSourceResolver(),
+        manifest::addDataSource));
+
+      config.getDataLakeMeasures().forEach(item -> addDoc(builder,
+        item,
+        new MeasurementResolver(),
+        manifest::addDataLakeMeasure));
+
+      config.getPipelines().forEach(item -> addDoc(builder,
+        item,
+        new PipelineResolver(),
+        manifest::addPipeline));
+
+      config.getDataViews().forEach(item -> {
+        var resolver = new DataViewResolver();
+        addDoc(builder,
+          item,
+          resolver,
+          manifest::addDataView);
+
+        var widgets = resolver.getWidgets(item.getResourceId());
+        var widgetResolver = new DataViewWidgetResolver();
+        widgets.forEach(widgetId -> addDoc(builder, widgetId, widgetResolver, manifest::addDataViewWidget));
+      });
+    });
+
+    builder.addManifest(defaultMapper.writeValueAsString(manifest));
+
+
+    return builder.buildZip();
+  }
+
+  private void addDoc(ZipFileBuilder builder,
+                      String resourceId,
+                      AbstractResolver<?> resolver,
+                      Consumer<String> function) {
+    addDoc(builder, new ExportItem(resourceId, "", true), resolver, function);
+  }
+
+  private void addDoc(ZipFileBuilder builder,
+                      ExportItem exportItem,
+                      AbstractResolver<?> resolver,
+                      Consumer<String> function) {
+    try {
+      var resourceId = exportItem.getResourceId();
+      var sanitizedResourceId = sanitize(resourceId);
+      builder.addText(sanitizedResourceId, resolver.getSerializedDocument(resourceId));
+      function.accept(sanitizedResourceId);
+    } catch (JsonProcessingException e) {
+      e.printStackTrace();
+    }
+  }
+
+  private String sanitize(String resourceId) {
+    return resourceId.replaceAll(":", "").replaceAll("\\.", "");
+  }
+
+  private void addAssets(ZipFileBuilder builder,
+                         List<String> assetIds) {
+    assetIds.forEach(assetId -> {
+      try {
+        var asset = getAsset(assetId);
+        builder.addText(String.valueOf(asset.get("_id")), this.defaultMapper.writeValueAsString(asset));
+      } catch (IOException e) {
+        e.printStackTrace();
+      }
+    });
+  }
+
+  private Map<String, Object> getAsset(String assetId) throws IOException {
+    return StorageDispatcher.INSTANCE.getNoSqlStore().getGenericStorage().findOne(assetId);
+  }
+}
diff --git a/streampipes-data-export/src/main/java/org/apache/streampipes/export/generator/ZipFileBuilder.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/generator/ZipFileBuilder.java
new file mode 100644
index 000000000..ea93d03e6
--- /dev/null
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/generator/ZipFileBuilder.java
@@ -0,0 +1,113 @@
+/*
+ * 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.export.generator;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ZipFileBuilder {
+
+  private final Map<String, byte[]> binaryEntries;
+  private final Map<String, String> textEntries;
+  private final Map<String, File> fileEntries;
+  private String manifest;
+
+  public static ZipFileBuilder create() {
+    return new ZipFileBuilder();
+  }
+
+  private ZipFileBuilder() {
+    this.binaryEntries = new HashMap<>();
+    this.fileEntries = new HashMap<>();
+    this.textEntries = new HashMap<>();
+  }
+
+  public ZipFileBuilder addText(String filename,
+                                String content) {
+    this.textEntries.put(filename, content);
+
+    return this;
+  }
+
+  public ZipFileBuilder addBinary(String filename,
+                                  byte[] content) {
+    this.binaryEntries.put(filename, content);
+
+    return this;
+  }
+
+  public ZipFileBuilder addFile(String filename,
+                                File file) {
+    this.fileEntries.put(filename, file);
+
+    return this;
+  }
+
+  public ZipFileBuilder addManifest(String manifest) {
+    this.manifest = manifest;
+
+    return this;
+  }
+
+  public byte[] buildZip() throws IOException {
+    return makeZip();
+  }
+
+  private byte[] makeZip() throws IOException {
+    byte[] buffer = new byte[1024];
+
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    ZipOutputStream out = new ZipOutputStream(outputStream);
+
+    for (String documentKey : this.textEntries.keySet()) {
+      byte[] document = asBytes(this.textEntries.get(documentKey));
+      addZipEntry(documentKey + ".json", document, out, buffer);
+    }
+
+    addZipEntry("manifest.json", asBytes(manifest), out, buffer);
+    out.closeEntry();
+    out.close();
+    return outputStream.toByteArray();
+  }
+
+  private byte[] asBytes(String document) {
+    return document.getBytes(StandardCharsets.UTF_8);
+  }
+
+  private void addZipEntry(String filename,
+                           byte[] document,
+                           ZipOutputStream out,
+                           byte[] buffer) throws IOException {
+    ZipEntry ze = new ZipEntry(filename);
+    out.putNextEntry(ze);
+
+    try (InputStream in = new ByteArrayInputStream(document)) {
+      int len;
+      while ((len = in.read(buffer)) > 0) {
+        out.write(buffer, 0, len);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+}
diff --git a/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/AbstractResolver.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/AbstractResolver.java
new file mode 100644
index 000000000..be8695691
--- /dev/null
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/AbstractResolver.java
@@ -0,0 +1,53 @@
+/*
+ * 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.export.resolver;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import org.apache.streampipes.export.utils.SerializationUtils;
+import org.apache.streampipes.model.assets.AssetLink;
+import org.apache.streampipes.model.export.ExportItem;
+import org.apache.streampipes.storage.api.INoSqlStorage;
+import org.apache.streampipes.storage.management.StorageDispatcher;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public abstract class AbstractResolver<T> {
+
+
+  public Set<ExportItem> resolve(Set<AssetLink> assetLinks) {
+    return assetLinks
+      .stream()
+      .map(link -> findDocument(link.getResourceId()))
+      .map(this::convert)
+      .collect(Collectors.toSet());
+  }
+
+  public String getSerializedDocument(String resourceId) throws JsonProcessingException {
+    return SerializationUtils.getSpObjectMapper().writeValueAsString(findDocument(resourceId));
+  }
+
+  protected INoSqlStorage getNoSqlStore() {
+    return StorageDispatcher.INSTANCE.getNoSqlStore();
+  }
+
+  public abstract T findDocument(String resourceId);
+
+  public abstract ExportItem convert(T document);
+}
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/AdapterResolver.java
similarity index 56%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/AdapterResolver.java
index 8fa1736b3..45ae530c4 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/AdapterResolver.java
@@ -16,24 +16,21 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
 
-public class DataLakeUtils {
+package org.apache.streampipes.export.resolver;
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
+import org.apache.streampipes.model.connect.adapter.AdapterDescription;
+import org.apache.streampipes.model.export.ExportItem;
+
+public class AdapterResolver extends AbstractResolver<AdapterDescription> {
 
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
+  @Override
+  public AdapterDescription findDocument(String resourceId) {
+    return getNoSqlStore().getAdapterInstanceStorage().getAdapter(resourceId);
   }
 
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
+  @Override
+  public ExportItem convert(AdapterDescription document) {
+    return new ExportItem(document.getElementId(), document.getName(), true);
   }
 }
diff --git a/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DashboardResolver.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DashboardResolver.java
new file mode 100644
index 000000000..3c5c1ffa6
--- /dev/null
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DashboardResolver.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.
+ *
+ */
+
+package org.apache.streampipes.export.resolver;
+
+import org.apache.streampipes.model.dashboard.DashboardItem;
+import org.apache.streampipes.model.dashboard.DashboardModel;
+import org.apache.streampipes.model.export.ExportItem;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class DashboardResolver extends AbstractResolver<DashboardModel> {
+
+  @Override
+  public DashboardModel findDocument(String resourceId) {
+    return getNoSqlStore().getDashboardStorage().getDashboard(resourceId);
+  }
+
+  @Override
+  public ExportItem convert(DashboardModel document) {
+    return new ExportItem(document.getCouchDbId(), document.getName(), true);
+  }
+
+  public List<String> getWidgets(String resourceId) {
+    var document = findDocument(resourceId);
+    return document.getWidgets().stream().map(DashboardItem::getId).collect(Collectors.toList());
+  }
+}
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DashboardWidgetResolver.java
similarity index 56%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DashboardWidgetResolver.java
index 8fa1736b3..7cf8c7381 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DashboardWidgetResolver.java
@@ -16,24 +16,20 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
+package org.apache.streampipes.export.resolver;
 
-public class DataLakeUtils {
+import org.apache.streampipes.model.dashboard.DashboardWidgetModel;
+import org.apache.streampipes.model.export.ExportItem;
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
+public class DashboardWidgetResolver extends AbstractResolver<DashboardWidgetModel> {
 
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
+  @Override
+  public DashboardWidgetModel findDocument(String resourceId) {
+    return getNoSqlStore().getDashboardWidgetStorage().getDashboardWidget(resourceId);
   }
 
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
+  @Override
+  public ExportItem convert(DashboardWidgetModel document) {
+    return new ExportItem(document.getId(), document.getVisualizationName(), true);
   }
 }
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataSourceResolver.java
similarity index 56%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataSourceResolver.java
index 8fa1736b3..6f8083d96 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataSourceResolver.java
@@ -16,24 +16,20 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
+package org.apache.streampipes.export.resolver;
 
-public class DataLakeUtils {
+import org.apache.streampipes.model.SpDataStream;
+import org.apache.streampipes.model.export.ExportItem;
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
+public class DataSourceResolver extends AbstractResolver<SpDataStream> {
 
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
+  @Override
+  public SpDataStream findDocument(String resourceId) {
+    return getNoSqlStore().getDataStreamStorage().getElementById(resourceId);
   }
 
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
+  @Override
+  public ExportItem convert(SpDataStream document) {
+    return new ExportItem(document.getElementId(), document.getName(), true);
   }
 }
diff --git a/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataViewResolver.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataViewResolver.java
new file mode 100644
index 000000000..d5b501502
--- /dev/null
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataViewResolver.java
@@ -0,0 +1,45 @@
+/*
+ * 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.export.resolver;
+
+import org.apache.streampipes.model.dashboard.DashboardItem;
+import org.apache.streampipes.model.dashboard.DashboardModel;
+import org.apache.streampipes.model.export.ExportItem;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class DataViewResolver extends AbstractResolver<DashboardModel> {
+
+  @Override
+  public DashboardModel findDocument(String resourceId) {
+    return getNoSqlStore().getDataExplorerDashboardStorage().getDashboard(resourceId);
+  }
+
+  @Override
+  public ExportItem convert(DashboardModel document) {
+    return new ExportItem(document.getCouchDbId(), document.getName(), true);
+  }
+
+  public List<String> getWidgets(String resourceId) {
+    var document = findDocument(resourceId);
+    return document.getWidgets().stream().map(DashboardItem::getId).collect(Collectors.toList());
+  }
+}
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataViewWidgetResolver.java
similarity index 56%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataViewWidgetResolver.java
index 8fa1736b3..bdeb55031 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/DataViewWidgetResolver.java
@@ -16,24 +16,20 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
+package org.apache.streampipes.export.resolver;
 
-public class DataLakeUtils {
+import org.apache.streampipes.model.datalake.DataExplorerWidgetModel;
+import org.apache.streampipes.model.export.ExportItem;
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
+public class DataViewWidgetResolver extends AbstractResolver<DataExplorerWidgetModel> {
 
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
+  @Override
+  public DataExplorerWidgetModel findDocument(String resourceId) {
+    return getNoSqlStore().getDataExplorerWidgetStorage().getDataExplorerWidget(resourceId);
   }
 
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
+  @Override
+  public ExportItem convert(DataExplorerWidgetModel document) {
+    return new ExportItem(document.getId(), document.getWidgetId(), true);
   }
 }
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/MeasurementResolver.java
similarity index 56%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/MeasurementResolver.java
index 8fa1736b3..da155d86c 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/MeasurementResolver.java
@@ -16,24 +16,20 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
+package org.apache.streampipes.export.resolver;
 
-public class DataLakeUtils {
+import org.apache.streampipes.model.datalake.DataLakeMeasure;
+import org.apache.streampipes.model.export.ExportItem;
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
+public class MeasurementResolver extends AbstractResolver<DataLakeMeasure> {
 
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
+  @Override
+  public DataLakeMeasure findDocument(String resourceId) {
+    return getNoSqlStore().getDataLakeStorage().findOne(resourceId);
   }
 
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
+  @Override
+  public ExportItem convert(DataLakeMeasure document) {
+    return new ExportItem(document.getElementId(), document.getMeasureName(), true);
   }
 }
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/PipelineResolver.java
similarity index 56%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/PipelineResolver.java
index 8fa1736b3..93a77acf8 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/resolver/PipelineResolver.java
@@ -16,24 +16,20 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
+package org.apache.streampipes.export.resolver;
 
-public class DataLakeUtils {
+import org.apache.streampipes.model.export.ExportItem;
+import org.apache.streampipes.model.pipeline.Pipeline;
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
+public class PipelineResolver extends AbstractResolver<Pipeline> {
 
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
+  @Override
+  public Pipeline findDocument(String resourceId) {
+    return getNoSqlStore().getPipelineStorageAPI().getPipeline(resourceId);
   }
 
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
+  @Override
+  public ExportItem convert(Pipeline document) {
+    return new ExportItem(document.getPipelineId(), document.getName(), true);
   }
 }
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-data-export/src/main/java/org/apache/streampipes/export/utils/SerializationUtils.java
similarity index 56%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to streampipes-data-export/src/main/java/org/apache/streampipes/export/utils/SerializationUtils.java
index 8fa1736b3..44eae525e 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-data-export/src/main/java/org/apache/streampipes/export/utils/SerializationUtils.java
@@ -16,24 +16,22 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
+package org.apache.streampipes.export.utils;
 
-public class DataLakeUtils {
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.streampipes.serializers.json.JacksonSerializer;
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
+public class SerializationUtils {
 
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
+  public static ObjectMapper getSpObjectMapper() {
+    return JacksonSerializer.getObjectMapper();
   }
 
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
+  public static ObjectMapper getDefaultObjectMapper() {
+    var mapper = new ObjectMapper();
+    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+    return mapper;
   }
 }
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
index 8fa1736b3..e74605421 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
@@ -21,7 +21,8 @@ package org.apache.streampipes.sinks.internal.jvm.datalake;
 public class DataLakeUtils {
 
   public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
+    //return s.toLowerCase().replaceAll(" ", "_");
+    return s.replaceAll(" ", "_");
   }
 
   private static String renameReservedKeywords(String runtimeName) {
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java
index b04dee4bc..74d15f002 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java
@@ -18,11 +18,14 @@
 
 package org.apache.streampipes.model.assets;
 
+import java.util.Objects;
+
 public class AssetLink {
 
   private String resourceId;
   private String linkType;
   private String linkLabel;
+  private String queryHint;
   private boolean editingDisabled;
 
   public AssetLink() {
@@ -59,4 +62,25 @@ public class AssetLink {
   public void setEditingDisabled(boolean editingDisabled) {
     this.editingDisabled = editingDisabled;
   }
+
+  public String getQueryHint() {
+    return queryHint;
+  }
+
+  public void setQueryHint(String queryHint) {
+    this.queryHint = queryHint;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    AssetLink assetLink = (AssetLink) o;
+    return resourceId.equals(assetLink.resourceId) && queryHint.equals(assetLink.queryHint);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(resourceId, queryHint);
+  }
 }
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/export/AssetExportConfiguration.java b/streampipes-model/src/main/java/org/apache/streampipes/model/export/AssetExportConfiguration.java
new file mode 100644
index 000000000..9e17d42be
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/export/AssetExportConfiguration.java
@@ -0,0 +1,120 @@
+/*
+ * 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.export;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class AssetExportConfiguration {
+
+  private String assetId;
+  private String assetName;
+
+  private Set<ExportItem> adapters;
+  private Set<ExportItem> dashboards;
+  private Set<ExportItem> dataViews;
+  private Set<ExportItem> dataLakeMeasures;
+  private Set<ExportItem> dataSources;
+  private Set<ExportItem> pipelines;
+  private Set<ExportItem> files;
+
+  public AssetExportConfiguration() {
+    this.adapters = new HashSet<>();
+    this.dashboards = new HashSet<>();
+    this.dataViews = new HashSet<>();
+    this.dataLakeMeasures = new HashSet<>();
+    this.dataSources = new HashSet<>();
+    this.pipelines = new HashSet<>();
+    this.files = new HashSet<>();
+  }
+
+  public Set<ExportItem> getAdapters() {
+    return adapters;
+  }
+
+  public void setAdapters(Set<ExportItem> adapters) {
+    this.adapters = adapters;
+  }
+
+  public Set<ExportItem> getDashboards() {
+    return dashboards;
+  }
+
+  public void setDashboards(Set<ExportItem> dashboards) {
+    this.dashboards = dashboards;
+  }
+
+  public Set<ExportItem> getDataViews() {
+    return dataViews;
+  }
+
+  public void setDataViews(Set<ExportItem> dataViews) {
+    this.dataViews = dataViews;
+  }
+
+  public Set<ExportItem> getDataLakeMeasures() {
+    return dataLakeMeasures;
+  }
+
+  public void setDataLakeMeasures(Set<ExportItem> dataLakeMeasures) {
+    this.dataLakeMeasures = dataLakeMeasures;
+  }
+
+  public Set<ExportItem> getDataSources() {
+    return dataSources;
+  }
+
+  public void setDataSources(Set<ExportItem> dataSources) {
+    this.dataSources = dataSources;
+  }
+
+  public String getAssetId() {
+    return assetId;
+  }
+
+  public void setAssetId(String assetId) {
+    this.assetId = assetId;
+  }
+
+  public Set<ExportItem> getPipelines() {
+    return pipelines;
+  }
+
+  public void setPipelines(Set<ExportItem> pipelines) {
+    this.pipelines = pipelines;
+  }
+
+  public Set<ExportItem> getFiles() {
+    return files;
+  }
+
+  public void setFiles(Set<ExportItem> files) {
+    this.files = files;
+  }
+
+  public String getAssetName() {
+    return assetName;
+  }
+
+  public void setAssetName(String assetName) {
+    this.assetName = assetName;
+  }
+
+
+}
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/streampipes-model/src/main/java/org/apache/streampipes/model/export/ExportConfiguration.java
similarity index 56%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to streampipes-model/src/main/java/org/apache/streampipes/model/export/ExportConfiguration.java
index 8fa1736b3..2a0052ba1 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/export/ExportConfiguration.java
@@ -16,24 +16,28 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
 
-public class DataLakeUtils {
+package org.apache.streampipes.model.export;
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
+import org.apache.streampipes.model.shared.annotation.TsModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@TsModel
+public class ExportConfiguration {
+
+  private List<AssetExportConfiguration> assetExportConfiguration;
+
+  public ExportConfiguration() {
+    this.assetExportConfiguration = new ArrayList<>();
   }
 
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
+  public List<AssetExportConfiguration> getAssetExportConfiguration() {
+    return assetExportConfiguration;
   }
 
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
+  public void setAssetExportConfiguration(List<AssetExportConfiguration> assetExportConfiguration) {
+    this.assetExportConfiguration = assetExportConfiguration;
   }
 }
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java b/streampipes-model/src/main/java/org/apache/streampipes/model/export/ExportItem.java
similarity index 62%
copy from streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java
copy to streampipes-model/src/main/java/org/apache/streampipes/model/export/ExportItem.java
index b04dee4bc..cb62711a0 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/export/ExportItem.java
@@ -16,16 +16,21 @@
  *
  */
 
-package org.apache.streampipes.model.assets;
+package org.apache.streampipes.model.export;
 
-public class AssetLink {
+public class ExportItem {
 
   private String resourceId;
-  private String linkType;
-  private String linkLabel;
-  private boolean editingDisabled;
+  private String label;
+  private boolean selected;
 
-  public AssetLink() {
+  public ExportItem() {
+  }
+
+  public ExportItem(String resourceId, String label, boolean selected) {
+    this.resourceId = resourceId;
+    this.label = label;
+    this.selected = selected;
   }
 
   public String getResourceId() {
@@ -36,27 +41,19 @@ public class AssetLink {
     this.resourceId = resourceId;
   }
 
-  public String getLinkType() {
-    return linkType;
-  }
-
-  public void setLinkType(String linkType) {
-    this.linkType = linkType;
-  }
-
-  public String getLinkLabel() {
-    return linkLabel;
+  public String getLabel() {
+    return label;
   }
 
-  public void setLinkLabel(String linkLabel) {
-    this.linkLabel = linkLabel;
+  public void setLabel(String label) {
+    this.label = label;
   }
 
-  public boolean isEditingDisabled() {
-    return editingDisabled;
+  public boolean isSelected() {
+    return selected;
   }
 
-  public void setEditingDisabled(boolean editingDisabled) {
-    this.editingDisabled = editingDisabled;
+  public void setSelected(boolean selected) {
+    this.selected = selected;
   }
 }
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/export/StreamPipesApplicationPackage.java b/streampipes-model/src/main/java/org/apache/streampipes/model/export/StreamPipesApplicationPackage.java
new file mode 100644
index 000000000..c0b3f9e1b
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/export/StreamPipesApplicationPackage.java
@@ -0,0 +1,190 @@
+/*
+ * 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.export;
+
+import org.apache.streampipes.model.shared.annotation.TsModel;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@TsModel
+public class StreamPipesApplicationPackage {
+
+  private Set<String> requiredProcessorAppIds;
+  private Set<String> requiredDataSinkAppIds;
+  private Set<String> requiredAdapterAppIds;
+
+  private Set<String> adapters;
+  private Set<String> dashboards;
+  private Set<String> dashboardWidgets;
+  private Set<String> dataViews;
+  private Set<String> dataViewWidgets;
+  private Set<String> dataLakeMeasures;
+  private Set<String> dataSources;
+  private Set<String> pipelines;
+  private Set<String> files;
+
+  public StreamPipesApplicationPackage() {
+    this.requiredProcessorAppIds = new HashSet<>();
+    this.requiredDataSinkAppIds = new HashSet<>();
+    this.requiredAdapterAppIds = new HashSet<>();
+
+    this.adapters = new HashSet<>();
+    this.dashboards = new HashSet<>();
+    this.dashboardWidgets = new HashSet<>();
+    this.dataViews = new HashSet<>();
+    this.dataViewWidgets = new HashSet<>();
+    this.dataLakeMeasures = new HashSet<>();
+    this.dataSources = new HashSet<>();
+    this.pipelines = new HashSet<>();
+    this.files = new HashSet<>();
+  }
+
+  public Set<String> getRequiredProcessorAppIds() {
+    return requiredProcessorAppIds;
+  }
+
+  public void setRequiredProcessorAppIds(Set<String> requiredProcessorAppIds) {
+    this.requiredProcessorAppIds = requiredProcessorAppIds;
+  }
+
+  public Set<String> getRequiredDataSinkAppIds() {
+    return requiredDataSinkAppIds;
+  }
+
+  public void setRequiredDataSinkAppIds(Set<String> requiredDataSinkAppIds) {
+    this.requiredDataSinkAppIds = requiredDataSinkAppIds;
+  }
+
+  public Set<String> getRequiredAdapterAppIds() {
+    return requiredAdapterAppIds;
+  }
+
+  public void setRequiredAdapterAppIds(Set<String> requiredAdapterAppIds) {
+    this.requiredAdapterAppIds = requiredAdapterAppIds;
+  }
+
+  public Set<String> getAdapters() {
+    return adapters;
+  }
+
+  public void setAdapters(Set<String> adapters) {
+    this.adapters = adapters;
+  }
+
+  public void addAdapter(String adapter) {
+    this.adapters.add(adapter);
+  }
+
+  public Set<String> getDashboards() {
+    return dashboards;
+  }
+
+  public void setDashboards(Set<String> dashboards) {
+    this.dashboards = dashboards;
+  }
+
+  public void addDashboard(String dashboard) {
+    this.dashboards.add(dashboard);
+  }
+
+  public Set<String> getDashboardWidgets() {
+    return dashboardWidgets;
+  }
+
+  public void setDashboardWidgets(Set<String> dashboardWidgets) {
+    this.dashboardWidgets = dashboardWidgets;
+  }
+
+  public void addDashboardWidget(String dashboardWidget) {
+    this.dashboardWidgets.add(dashboardWidget);
+  }
+
+  public Set<String> getDataViews() {
+    return dataViews;
+  }
+
+  public void setDataViews(Set<String> dataViews) {
+    this.dataViews = dataViews;
+  }
+
+  public void addDataView(String dataView) {
+    this.dataViews.add(dataView);
+  }
+
+  public Set<String> getDataViewWidgets() {
+    return dataViewWidgets;
+  }
+
+  public void setDataViewWidgets(Set<String> dataViewWidgets) {
+    this.dataViewWidgets = dataViewWidgets;
+  }
+
+  public void addDataViewWidget(String dataViewWidget) {
+    this.dataViewWidgets.add(dataViewWidget);
+  }
+
+  public Set<String> getDataLakeMeasures() {
+    return dataLakeMeasures;
+  }
+
+  public void setDataLakeMeasures(Set<String> dataLakeMeasures) {
+    this.dataLakeMeasures = dataLakeMeasures;
+  }
+
+  public void addDataLakeMeasure(String dataLakeMeasure) {
+    this.dataLakeMeasures.add(dataLakeMeasure);
+  }
+
+  public Set<String> getDataSources() {
+    return dataSources;
+  }
+
+  public void setDataSources(Set<String> dataSources) {
+    this.dataSources = dataSources;
+  }
+
+  public void addDataSource(String dataSource) {
+    this.dataSources.add(dataSource);
+  }
+
+  public Set<String> getPipelines() {
+    return pipelines;
+  }
+
+  public void setPipelines(Set<String> pipelines) {
+    this.pipelines = pipelines;
+  }
+
+  public void addPipeline(String pipeline) {
+    this.pipelines.add(pipeline);
+  }
+
+  public Set<String> getFiles() {
+    return files;
+  }
+
+  public void setFiles(Set<String> files) {
+    this.files = files;
+  }
+
+  public void addFile(String file) {
+    this.files.add(file);
+  }
+}
diff --git a/streampipes-rest/pom.xml b/streampipes-rest/pom.xml
index 8cedd5b4d..8f2db93f4 100644
--- a/streampipes-rest/pom.xml
+++ b/streampipes-rest/pom.xml
@@ -50,6 +50,11 @@
             <artifactId>streampipes-data-explorer</artifactId>
             <version>0.70.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.streampipes</groupId>
+            <artifactId>streampipes-data-export</artifactId>
+            <version>0.70.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.streampipes</groupId>
             <artifactId>streampipes-measurement-units</artifactId>
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/DataExportResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/DataExportResource.java
new file mode 100644
index 000000000..fff79451b
--- /dev/null
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/DataExportResource.java
@@ -0,0 +1,60 @@
+/*
+ * 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.admin;
+
+import org.apache.streampipes.export.ExportManager;
+import org.apache.streampipes.model.export.ExportConfiguration;
+import org.apache.streampipes.rest.core.base.impl.AbstractAuthGuardedRestResource;
+import org.apache.streampipes.rest.security.AuthConstants;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.util.List;
+
+@Path("/v2/export")
+@Component
+@PreAuthorize(AuthConstants.IS_ADMIN_ROLE)
+public class DataExportResource extends AbstractAuthGuardedRestResource {
+
+  @Path("/preview")
+  @POST
+  @Consumes(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON)
+  public Response getExportPreview(List<String> selectedAssetIds) {
+    var exportConfig = ExportManager.getExportPreview(selectedAssetIds);
+    return ok(exportConfig);
+  }
+
+  @Path("/download")
+  @POST
+  @Consumes(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_OCTET_STREAM)
+  public Response getExportPreview(ExportConfiguration exportConfiguration) throws IOException {
+      var applicationPackage = ExportManager.getExportPackage(exportConfiguration);
+      return ok(applicationPackage);
+  }
+
+}
diff --git a/ui/projects/streampipes/platform-services/src/lib/model/assets/asset.model.ts b/ui/projects/streampipes/platform-services/src/lib/model/assets/asset.model.ts
index 511062885..626e627dd 100644
--- a/ui/projects/streampipes/platform-services/src/lib/model/assets/asset.model.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/model/assets/asset.model.ts
@@ -37,6 +37,7 @@ export interface AssetLink {
   resourceId: string;
   linkType: 'data-view' | 'dashboard' | 'adapter' | 'source' | string;
   linkLabel: string;
+  queryHint: string;
   editingDisabled: boolean;
   navigationActive: boolean;
 }
diff --git a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
index 393aa4c56..9a1a1d9b2 100644
--- a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
@@ -18,7 +18,7 @@
 /* tslint:disable */
 /* eslint-disable */
 // @ts-nocheck
-// Generated using typescript-generator version 2.27.744 on 2022-04-25 13:56:39.
+// Generated using typescript-generator version 2.27.744 on 2022-07-31 20:23:49.
 
 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 [...]
@@ -151,8 +151,8 @@ export class NamedStreamPipesEntity extends AbstractStreamPipesEntity {
         instance.applicationLinks = __getCopyArrayFn(ApplicationLink.fromData)(data.applicationLinks);
         instance.internallyManaged = data.internallyManaged;
         instance.connectedTo = __getCopyArrayFn(__identity<string>())(data.connectedTo);
-        instance.uri = data.uri;
         instance.dom = data.dom;
+        instance.uri = data.uri;
         instance._rev = data._rev;
         return instance;
     }
@@ -169,11 +169,11 @@ export class AdapterDescription extends NamedStreamPipesEntity {
     eventGrounding: EventGrounding;
     icon: string;
     rules: TransformationRuleDescriptionUnion[];
-    schemaRules: any[];
+    schemaRules: TransformationRuleDescriptionUnion[];
     selectedEndpointUrl: string;
-    streamRules: any[];
+    streamRules: TransformationRuleDescriptionUnion[];
     userName: string;
-    valueRules: any[];
+    valueRules: TransformationRuleDescriptionUnion[];
 
     static fromData(data: AdapterDescription, target?: AdapterDescription): AdapterDescription {
         if (!data) {
@@ -192,9 +192,9 @@ export class AdapterDescription extends NamedStreamPipesEntity {
         instance.selectedEndpointUrl = data.selectedEndpointUrl;
         instance.correspondingServiceGroup = data.correspondingServiceGroup;
         instance.correspondingDataStreamElementId = data.correspondingDataStreamElementId;
-        instance.valueRules = __getCopyArrayFn(__identity<any>())(data.valueRules);
-        instance.streamRules = __getCopyArrayFn(__identity<any>())(data.streamRules);
-        instance.schemaRules = __getCopyArrayFn(__identity<any>())(data.schemaRules);
+        instance.streamRules = __getCopyArrayFn(TransformationRuleDescription.fromDataUnion)(data.streamRules);
+        instance.valueRules = __getCopyArrayFn(TransformationRuleDescription.fromDataUnion)(data.valueRules);
+        instance.schemaRules = __getCopyArrayFn(TransformationRuleDescription.fromDataUnion)(data.schemaRules);
         return instance;
     }
 
@@ -588,6 +588,35 @@ export class ApplicationLink extends UnnamedStreamPipesEntity {
     }
 }
 
+export class AssetExportConfiguration {
+    adapters: ExportItem[];
+    assetId: string;
+    assetName: string;
+    dashboards: ExportItem[];
+    dataLakeMeasures: ExportItem[];
+    dataSources: ExportItem[];
+    dataViews: ExportItem[];
+    files: ExportItem[];
+    pipelines: ExportItem[];
+
+    static fromData(data: AssetExportConfiguration, target?: AssetExportConfiguration): AssetExportConfiguration {
+        if (!data) {
+            return data;
+        }
+        const instance = target || new AssetExportConfiguration();
+        instance.assetId = data.assetId;
+        instance.assetName = data.assetName;
+        instance.adapters = __getCopyArrayFn(ExportItem.fromData)(data.adapters);
+        instance.dashboards = __getCopyArrayFn(ExportItem.fromData)(data.dashboards);
+        instance.dataViews = __getCopyArrayFn(ExportItem.fromData)(data.dataViews);
+        instance.dataLakeMeasures = __getCopyArrayFn(ExportItem.fromData)(data.dataLakeMeasures);
+        instance.dataSources = __getCopyArrayFn(ExportItem.fromData)(data.dataSources);
+        instance.pipelines = __getCopyArrayFn(ExportItem.fromData)(data.pipelines);
+        instance.files = __getCopyArrayFn(ExportItem.fromData)(data.files);
+        return instance;
+    }
+}
+
 export class BoundPipelineElement extends UnnamedStreamPipesEntity {
     "@class": "org.apache.streampipes.model.template.BoundPipelineElement";
     connectedTo: BoundPipelineElement[];
@@ -1525,6 +1554,36 @@ export class EventStreamQualityRequirement extends UnnamedStreamPipesEntity {
     }
 }
 
+export class ExportConfiguration {
+    assetExportConfiguration: AssetExportConfiguration[];
+
+    static fromData(data: ExportConfiguration, target?: ExportConfiguration): ExportConfiguration {
+        if (!data) {
+            return data;
+        }
+        const instance = target || new ExportConfiguration();
+        instance.assetExportConfiguration = __getCopyArrayFn(AssetExportConfiguration.fromData)(data.assetExportConfiguration);
+        return instance;
+    }
+}
+
+export class ExportItem {
+    label: string;
+    resourceId: string;
+    selected: boolean;
+
+    static fromData(data: ExportItem, target?: ExportItem): ExportItem {
+        if (!data) {
+            return data;
+        }
+        const instance = target || new ExportItem();
+        instance.resourceId = data.resourceId;
+        instance.label = data.label;
+        instance.selected = data.selected;
+        return instance;
+    }
+}
+
 export class FileMetadata {
     createdAt: number;
     createdByUser: string;
@@ -1668,9 +1727,9 @@ export class GenericAdapterSetDescription extends AdapterSetDescription implemen
         }
         const instance = target || new GenericAdapterSetDescription();
         super.fromData(data, instance);
-        instance.formatDescription = FormatDescription.fromData(data.formatDescription);
-        instance.protocolDescription = ProtocolDescription.fromData(data.protocolDescription);
         instance.eventSchema = EventSchema.fromData(data.eventSchema);
+        instance.protocolDescription = ProtocolDescription.fromData(data.protocolDescription);
+        instance.formatDescription = FormatDescription.fromData(data.formatDescription);
         return instance;
     }
 }
@@ -1687,9 +1746,9 @@ export class GenericAdapterStreamDescription extends AdapterStreamDescription im
         }
         const instance = target || new GenericAdapterStreamDescription();
         super.fromData(data, instance);
-        instance.formatDescription = FormatDescription.fromData(data.formatDescription);
-        instance.protocolDescription = ProtocolDescription.fromData(data.protocolDescription);
         instance.eventSchema = EventSchema.fromData(data.eventSchema);
+        instance.protocolDescription = ProtocolDescription.fromData(data.protocolDescription);
+        instance.formatDescription = FormatDescription.fromData(data.formatDescription);
         return instance;
     }
 }
@@ -3007,6 +3066,25 @@ export class StaticPropertyGroup extends StaticProperty {
     }
 }
 
+export class StreamPipesApplicationPackage {
+    assetExportConfigurations: AssetExportConfiguration[];
+    requiredAdapterAppIds: string[];
+    requiredDataSinkAppIds: string[];
+    requiredProcessorAppIds: string[];
+
+    static fromData(data: StreamPipesApplicationPackage, target?: StreamPipesApplicationPackage): StreamPipesApplicationPackage {
+        if (!data) {
+            return data;
+        }
+        const instance = target || new StreamPipesApplicationPackage();
+        instance.requiredProcessorAppIds = __getCopyArrayFn(__identity<string>())(data.requiredProcessorAppIds);
+        instance.requiredDataSinkAppIds = __getCopyArrayFn(__identity<string>())(data.requiredDataSinkAppIds);
+        instance.requiredAdapterAppIds = __getCopyArrayFn(__identity<string>())(data.requiredAdapterAppIds);
+        instance.assetExportConfigurations = __getCopyArrayFn(AssetExportConfiguration.fromData)(data.assetExportConfigurations);
+        return instance;
+    }
+}
+
 export class SuccessMessage extends Message {
 
     static fromData(data: SuccessMessage, target?: SuccessMessage): SuccessMessage {
diff --git a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.ts b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.ts
index f349c3e8d..6d8e3d66b 100644
--- a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.ts
+++ b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.ts
@@ -78,7 +78,14 @@ export class SpAssetDetailsPanelComponent implements OnInit {
   }
 
   openCreateAssetLinkDialog(): void {
-    const assetLink: AssetLink = {linkLabel: '', linkType: 'data-view', editingDisabled: false, resourceId: '', navigationActive: true};
+    const assetLink: AssetLink = {
+      linkLabel: '',
+      linkType: 'data-view',
+      editingDisabled: false,
+      resourceId: '',
+      navigationActive: true,
+      queryHint: 'data-view'
+    };
     this.openEditAssetLinkDialog(assetLink, -1, true);
   }
 
diff --git a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html
index b723edd0e..480c4b6da 100644
--- a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html
+++ b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html
@@ -77,6 +77,18 @@
                     </mat-select>
                 </mat-form-field>
             </div>
+            <div *ngIf="selectedLinkType.linkQueryHint === 'adapter'" fxLayout="column" class="link-configuration">
+                <mat-form-field color="accent" fxFlex="100">
+                    <mat-label>Data Views</mat-label>
+                    <mat-select (selectionChange)="changeLabel($event.value.elementId, $event.value.name, $event.value)"
+                                [(value)]="currentResource"
+                                fxFlex
+                                required>
+                        <mat-option *ngFor="let adapter of adapters"
+                                    [value]="adapter">{{adapter.name}}</mat-option>
+                    </mat-select>
+                </mat-form-field>
+            </div>
             <div *ngIf="selectedLinkType.linkQueryHint === 'measurement'" fxLayout="column" class="link-configuration">
                 <mat-form-field color="accent" fxFlex="100">
                     <mat-label>Data Lake Storage</mat-label>
diff --git a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts
index ee42b9f4f..a989a7f64 100644
--- a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts
+++ b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts
@@ -19,6 +19,9 @@
 import { Component, Input, OnInit } from '@angular/core';
 import { DialogRef } from '@streampipes/shared-ui';
 import {
+  AdapterDescriptionUnion,
+  SpDataStream,
+  AdapterService,
   AssetLink,
   AssetLinkType,
   Dashboard,
@@ -27,16 +30,12 @@ import {
   DataViewDataExplorerService,
   GenericStorageService,
   Pipeline,
-  PipelineService
+  PipelineService,
+  PipelineElementService
 } from '@streampipes/platform-services';
 import { FormGroup } from '@angular/forms';
 import { zip } from 'rxjs';
 import { MatSelectChange } from '@angular/material/select';
-import {
-  AdapterDescriptionUnion,
-  SpDataStream
-} from '../../../../../projects/streampipes/platform-services/src/lib/model/gen/streampipes-model';
-import { PipelineElementService } from '../../../../../projects/streampipes/platform-services/src/lib/apis/pipeline-element.service';
 
 @Component({
   selector: 'sp-edit-asset-link-dialog-component',
@@ -77,7 +76,8 @@ export class EditAssetLinkDialogComponent implements OnInit {
               private dataViewService: DataViewDataExplorerService,
               private dashboardService: DashboardService,
               private dataLakeService: DatalakeRestService,
-              private pipelineElementService: PipelineElementService) {
+              private pipelineElementService: PipelineElementService,
+              private adapterService: AdapterService) {
   }
 
   ngOnInit(): void {
@@ -105,19 +105,22 @@ export class EditAssetLinkDialogComponent implements OnInit {
       this.dataViewService.getDataViews(),
       this.dashboardService.getDashboards(),
       this.pipelineElementService.getDataStreams(),
-      this.dataLakeService.getAllMeasurementSeries()).subscribe(response => {
+      this.dataLakeService.getAllMeasurementSeries(),
+      this.adapterService.getAdapters()).subscribe(response => {
       this.pipelines = response[0];
       this.dataViews = response[1];
       this.dashboards = response[2];
       this.dataSources = response[3];
       this.dataLakeMeasures = response[4];
+      this.adapters = response[5];
 
       this.allResources = [
         ...this.pipelines,
         ...this.dataViews,
         ...this.dashboards,
         ...this.dataSources,
-        ...this.dataLakeMeasures
+        ...this.dataLakeMeasures,
+        ...this.adapters
       ];
       if (!this.createMode) {
         this.currentResource = this.allResources.find(r => r._id === this.clonedAssetLink.resourceId ||
@@ -131,6 +134,7 @@ export class EditAssetLinkDialogComponent implements OnInit {
     const linkType = this.assetLinkTypes.find(a => a.linkType === this.selectedLinkType.linkType);
     this.clonedAssetLink.editingDisabled = false;
     this.clonedAssetLink.linkType = linkType.linkType;
+    this.clonedAssetLink.queryHint = linkType.linkQueryHint;
     this.clonedAssetLink.navigationActive = linkType.navigationActive;
   }
 
diff --git a/ui/src/app/configuration/configuration-tabs.ts b/ui/src/app/configuration/configuration-tabs.ts
index dba3af875..367d7a927 100644
--- a/ui/src/app/configuration/configuration-tabs.ts
+++ b/ui/src/app/configuration/configuration-tabs.ts
@@ -25,6 +25,7 @@ export class SpConfigurationTabs {
       {itemId: 'general', itemTitle: 'General', itemLink: ['configuration', 'general']},
       {itemId: 'datalake', itemTitle: 'Data Lake', itemLink: ['configuration', 'datalake']},
       {itemId: 'email', itemTitle: 'Mail', itemLink: ['configuration', 'email']},
+      {itemId: 'export', itemTitle: 'Export/Import', itemLink: ['configuration', 'export']},
       {itemId: 'messaging', itemTitle: 'Messaging', itemLink: ['configuration', 'messaging']},
       {itemId: 'pipelineelement', itemTitle: 'Pipeline Element Configuration', itemLink: ['configuration', 'pipelineelement']},
       {itemId: 'security', itemTitle: 'Security', itemLink: ['configuration', 'security']}
diff --git a/ui/src/app/configuration/configuration.module.ts b/ui/src/app/configuration/configuration.module.ts
index 9ca80b6fc..1aa5060b0 100644
--- a/ui/src/app/configuration/configuration.module.ts
+++ b/ui/src/app/configuration/configuration.module.ts
@@ -54,6 +54,10 @@ import { GeneralConfigurationComponent } from './general-configuration/general-c
 import { SecurityAuthenticationConfigurationComponent } from './security-configuration/authentication-configuration/authentication-configuration.component';
 import { RouterModule } from '@angular/router';
 import { SharedUiModule } from '@streampipes/shared-ui';
+import { SpDataExportImportComponent } from './export/data-export-import.component';
+import { SpDataExportDialogComponent } from './export/export-dialog/data-export-dialog.component';
+import { SpDataImportDialogComponent } from './export/import-dialog/data-import-dialog.component';
+import { SpDataExportItemComponent } from './export/export-dialog/data-export-item/data-export-item.component';
 
 @NgModule({
   imports: [
@@ -94,6 +98,10 @@ import { SharedUiModule } from '@streampipes/shared-ui';
             path: 'email',
             component: EmailConfigurationComponent
           },
+          {
+            path: 'export',
+            component: SpDataExportImportComponent
+          },
           {
             path: 'messaging',
             component: MessagingConfigurationComponent
@@ -131,6 +139,10 @@ import { SharedUiModule } from '@streampipes/shared-ui';
     SecurityServiceConfigComponent,
     MessagingConfigurationComponent,
     DatalakeConfigurationComponent,
+    SpDataExportImportComponent,
+    SpDataExportDialogComponent,
+    SpDataExportItemComponent,
+    SpDataImportDialogComponent
   ],
   providers: [ConfigurationService],
 })
diff --git a/ui/src/app/configuration/export/data-export-import.component.html b/ui/src/app/configuration/export/data-export-import.component.html
new file mode 100644
index 000000000..82a86a161
--- /dev/null
+++ b/ui/src/app/configuration/export/data-export-import.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.
+  ~
+  -->
+
+<sp-basic-nav-tabs [spNavigationItems]="tabs" [activeLink]="'export'">
+    <div fxLayout="column" class="page-container-padding">
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
+            <sp-split-section title="Export" subtitle="Export application data">
+                <div class="subsection-title">Export assets and all linked resources</div>
+                <div fxLayout="column" *ngFor="let asset of assets">
+                    <mat-checkbox (change)="handleSelectionChange($event, asset._id)"><h4>{{asset.assetName}}</h4></mat-checkbox>
+                </div>
+                <div class="mt-10">
+                    <button mat-button
+                            mat-raised-button
+                            color="accent"
+                            [disabled]="selectedAssets.length === 0"
+                            (click)="openExportDialog()">
+                        <i class="material-icons">file_download</i><span>&nbsp;Start export process</span>
+                    </button>
+                </div>
+            </sp-split-section>
+        </div>
+        <mat-divider></mat-divider>
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
+            <sp-split-section title="Import" subtitle="Import application data">
+                <div class="subsection-title">Import from application package</div>
+
+                <div class="mt-10">
+                    <button mat-button mat-raised-button color="accent">
+                        <i class="material-icons">save</i><span>&nbsp;Save</span>
+                    </button>
+                </div>
+            </sp-split-section>
+        </div>
+    </div>
+</sp-basic-nav-tabs>
+
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/ui/src/app/configuration/export/data-export-import.component.scss
similarity index 55%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to ui/src/app/configuration/export/data-export-import.component.scss
index 8fa1736b3..13cbc4aac 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/ui/src/app/configuration/export/data-export-import.component.scss
@@ -15,25 +15,3 @@
  * limitations under the License.
  *
  */
-
-package org.apache.streampipes.sinks.internal.jvm.datalake;
-
-public class DataLakeUtils {
-
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
-
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
-  }
-
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
-  }
-}
diff --git a/ui/src/app/configuration/export/data-export-import.component.ts b/ui/src/app/configuration/export/data-export-import.component.ts
new file mode 100644
index 000000000..32b007e2b
--- /dev/null
+++ b/ui/src/app/configuration/export/data-export-import.component.ts
@@ -0,0 +1,81 @@
+/*
+ * 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, OnInit } from '@angular/core';
+import { DialogService, PanelType, SpBreadcrumbService } from '@streampipes/shared-ui';
+import { SpConfigurationRoutes } from '../configuration.routes';
+import { SpConfigurationTabs } from '../configuration-tabs';
+import { AssetManagementService, SpAsset } from '@streampipes/platform-services';
+import { MatCheckboxChange } from '@angular/material/checkbox';
+import { SpDataExportDialogComponent } from './export-dialog/data-export-dialog.component';
+
+@Component({
+  selector: 'sp-data-export-import',
+  templateUrl: './data-export-import.component.html',
+  styleUrls: ['./data-export-import.component.scss']
+})
+export class SpDataExportImportComponent implements OnInit {
+
+  tabs = SpConfigurationTabs.getTabs();
+
+  assets: SpAsset[];
+  selectedAssets: string[] = [];
+
+  constructor(private breadcrumbService: SpBreadcrumbService,
+              private assetManagementService: AssetManagementService,
+              private dialogService: DialogService) {
+
+  }
+
+  ngOnInit(): void {
+    this.breadcrumbService
+      .updateBreadcrumb([SpConfigurationRoutes.BASE, {label: SpConfigurationTabs.getTabs()[3].itemTitle}]);
+    this.loadAssets();
+  }
+
+  loadAssets(): void {
+    this.assetManagementService
+      .getAllAssets()
+      .subscribe(assets => this.assets = assets.sort((a, b) => a.assetName.localeCompare(b.assetName)));
+  }
+
+  handleSelectionChange(event: MatCheckboxChange,
+                        assetId: string) {
+    if (event.checked) {
+      this.selectedAssets.push(assetId);
+    } else {
+      this.selectedAssets.splice(this.selectedAssets.indexOf(assetId), 1);
+    }
+  }
+
+  openExportDialog() {
+    const dialogRef = this.dialogService.open(SpDataExportDialogComponent, {
+      panelType: PanelType.SLIDE_IN_PANEL,
+      title: 'Export resources',
+      width: '50vw',
+      data: {
+        'selectedAssets': this.selectedAssets,
+      }
+    });
+
+    dialogRef.afterClosed().subscribe(() => {
+
+    });
+  }
+
+}
diff --git a/ui/src/app/configuration/export/data-export.service.ts b/ui/src/app/configuration/export/data-export.service.ts
new file mode 100644
index 000000000..14994fdb4
--- /dev/null
+++ b/ui/src/app/configuration/export/data-export.service.ts
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Injectable } from '@angular/core';
+import { PlatformServicesCommons } from '@streampipes/platform-services';
+import { HttpClient } from '@angular/common/http';
+import { Observable } from 'rxjs';
+import { ExportConfiguration } from '../../../../projects/streampipes/platform-services/src/lib/model/gen/streampipes-model';
+import { map } from 'rxjs/operators';
+
+@Injectable({providedIn: 'root'})
+export class DataExportService {
+
+  constructor(private platformServicesCommons: PlatformServicesCommons,
+              private http: HttpClient) {
+  }
+
+  getExportPreview(assetIds: string[]): Observable<ExportConfiguration> {
+    return this.http.post(this.basePath + '/preview', assetIds)
+      .pipe(map(res => res as ExportConfiguration));
+  }
+
+  triggerExport(exportConfig: ExportConfiguration): Observable<Blob> {
+    return this.http.post(this.basePath + '/download', exportConfig, {responseType: 'blob'});
+  }
+
+  private get basePath(): string {
+    return this.platformServicesCommons.apiBasePath + '/export';
+  }
+
+}
diff --git a/ui/src/app/configuration/export/export-dialog/data-export-dialog.component.html b/ui/src/app/configuration/export/export-dialog/data-export-dialog.component.html
new file mode 100644
index 000000000..bec004e3f
--- /dev/null
+++ b/ui/src/app/configuration/export/export-dialog/data-export-dialog.component.html
@@ -0,0 +1,49 @@
+<!--
+  ~ 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">
+        <div fxFlex="100" fxLayout="column" class="p-15" *ngIf="preview">
+            <div *ngFor="let config of preview.assetExportConfiguration">
+                <h4>Exported items {{config.assetName}}</h4>
+                <sp-data-export-item [exportItems]="config.adapters" sectionTitle="Adapters"></sp-data-export-item>
+                <sp-data-export-item [exportItems]="config.dashboards" sectionTitle="Dashboards"></sp-data-export-item>
+                <sp-data-export-item [exportItems]="config.dataViews" sectionTitle="Data Views"></sp-data-export-item>
+                <sp-data-export-item [exportItems]="config.dataSources" sectionTitle="Data Sources"></sp-data-export-item>
+                <sp-data-export-item [exportItems]="config.dataLakeMeasures" sectionTitle="Data Lake Storage"></sp-data-export-item>
+                <sp-data-export-item [exportItems]="config.pipelines" sectionTitle="Pipelines"></sp-data-export-item>
+            </div>
+        </div>
+    </div>
+    <mat-divider></mat-divider>
+    <div class="sp-dialog-actions">
+        <div fxLayout="column">
+            <div fxLayout="row">
+                <button mat-button
+                        mat-raised-button
+                        color="accent"
+                        style="margin-right: 10px;" (click)="generateDownloadPackage()">
+                    <i class="material-icons">file_download</i><span>&nbsp;Download export</span>
+                </button>
+                <button mat-button mat-raised-button class="mat-basic" (click)="close()">
+                    Cancel
+                </button>
+            </div>
+        </div>
+    </div>
+</div>
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/ui/src/app/configuration/export/export-dialog/data-export-dialog.component.scss
similarity index 55%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to ui/src/app/configuration/export/export-dialog/data-export-dialog.component.scss
index 8fa1736b3..fddade7bf 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/ui/src/app/configuration/export/export-dialog/data-export-dialog.component.scss
@@ -16,24 +16,4 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
-
-public class DataLakeUtils {
-
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
-
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
-  }
-
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
-  }
-}
+@import '../../../../scss/sp/sp-dialog.scss';
diff --git a/ui/src/app/configuration/export/export-dialog/data-export-dialog.component.ts b/ui/src/app/configuration/export/export-dialog/data-export-dialog.component.ts
new file mode 100644
index 000000000..33af53433
--- /dev/null
+++ b/ui/src/app/configuration/export/export-dialog/data-export-dialog.component.ts
@@ -0,0 +1,63 @@
+/*
+ * 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, OnInit } from '@angular/core';
+import { DialogRef } from '@streampipes/shared-ui';
+import { DataExportService } from '../data-export.service';
+import { ExportConfiguration } from '@streampipes/platform-services';
+
+@Component({
+  selector: 'sp-data-export-dialog',
+  templateUrl: './data-export-dialog.component.html',
+  styleUrls: ['./data-export-dialog.component.scss'],
+})
+export class SpDataExportDialogComponent implements OnInit {
+
+  @Input()
+  selectedAssets: string[];
+
+  preview: ExportConfiguration;
+
+  constructor(private dialogRef: DialogRef<SpDataExportDialogComponent>,
+              private dataExportService: DataExportService) {
+
+  }
+
+  ngOnInit(): void {
+    this.dataExportService.getExportPreview(this.selectedAssets).subscribe(preview => {
+      this.preview = preview;
+    });
+  }
+
+  close(): void {
+    this.dialogRef.close();
+  }
+
+  generateDownloadPackage(): void {
+    this.dataExportService.triggerExport(this.preview).subscribe(result => {
+      this.downloadFile(result);
+    });
+  }
+
+  downloadFile(data: any) {
+    const blob = new Blob([data], { type: 'application/zip' });
+    const url = window.URL.createObjectURL(blob);
+    window.open(url);
+  }
+
+}
diff --git a/ui/src/app/configuration/export/export-dialog/data-export-item/data-export-item.component.html b/ui/src/app/configuration/export/export-dialog/data-export-item/data-export-item.component.html
new file mode 100644
index 000000000..d9879aa15
--- /dev/null
+++ b/ui/src/app/configuration/export/export-dialog/data-export-item/data-export-item.component.html
@@ -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.
+  ~
+  -->
+
+<div fxLayout="column" fxFlex="100">
+    <h5>{{sectionTitle}}</h5>
+    <mat-checkbox *ngFor="let exportItem of exportItems; let i = index"
+                  [checked]="exportItem.selected"
+                  (change)="changeItem($event, i)">
+        {{exportItem.label}}
+    </mat-checkbox>
+</div>
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/ui/src/app/configuration/export/export-dialog/data-export-item/data-export-item.component.scss
similarity index 55%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to ui/src/app/configuration/export/export-dialog/data-export-item/data-export-item.component.scss
index 8fa1736b3..13cbc4aac 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/ui/src/app/configuration/export/export-dialog/data-export-item/data-export-item.component.scss
@@ -15,25 +15,3 @@
  * limitations under the License.
  *
  */
-
-package org.apache.streampipes.sinks.internal.jvm.datalake;
-
-public class DataLakeUtils {
-
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
-
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
-  }
-
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
-  }
-}
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/ui/src/app/configuration/export/export-dialog/data-export-item/data-export-item.component.ts
similarity index 56%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to ui/src/app/configuration/export/export-dialog/data-export-item/data-export-item.component.ts
index 8fa1736b3..1d6e68374 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/ui/src/app/configuration/export/export-dialog/data-export-item/data-export-item.component.ts
@@ -16,24 +16,30 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
+import { Component, Input, OnInit } from '@angular/core';
+import { ExportItem } from '@streampipes/platform-services';
+import { MatCheckboxChange } from '@angular/material/checkbox';
 
-public class DataLakeUtils {
+@Component({
+  selector: 'sp-data-export-item',
+  templateUrl: './data-export-item.component.html',
+  styleUrls: ['./data-export-item.component.scss'],
+})
+export class SpDataExportItemComponent implements OnInit {
 
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
+  @Input()
+  exportItems: ExportItem[];
+
+  @Input()
+  sectionTitle: string;
 
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
+  ngOnInit(): void {
   }
 
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
+  changeItem(event: MatCheckboxChange,
+             index: number) {
+    this.exportItems[index].selected = event.checked;
   }
+
+
 }
diff --git a/ui/src/app/configuration/export/import-dialog/data-import-dialog.component.html b/ui/src/app/configuration/export/import-dialog/data-import-dialog.component.html
new file mode 100644
index 000000000..fb99b649e
--- /dev/null
+++ b/ui/src/app/configuration/export/import-dialog/data-import-dialog.component.html
@@ -0,0 +1,17 @@
+<!--
+  ~ 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.
+  ~
+  -->
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java b/ui/src/app/configuration/export/import-dialog/data-import-dialog.component.scss
similarity index 55%
copy from streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
copy to ui/src/app/configuration/export/import-dialog/data-import-dialog.component.scss
index 8fa1736b3..fddade7bf 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/src/main/java/org/apache/streampipes/sinks/internal/jvm/datalake/DataLakeUtils.java
+++ b/ui/src/app/configuration/export/import-dialog/data-import-dialog.component.scss
@@ -16,24 +16,4 @@
  *
  */
 
-package org.apache.streampipes.sinks.internal.jvm.datalake;
-
-public class DataLakeUtils {
-
-  public static String prepareString(String s) {
-    return s.toLowerCase().replaceAll(" ", "_");
-  }
-
-  private static String renameReservedKeywords(String runtimeName) {
-    if (InfluxDbReservedKeywords.keywordList.stream().anyMatch(k -> k.equalsIgnoreCase(runtimeName))) {
-      return runtimeName + "_";
-    } else {
-      return runtimeName;
-    }
-  }
-
-  public static String sanitizePropertyRuntimeName(String runtimeName) {
-    String sanitizedRuntimeName = prepareString(runtimeName);
-    return renameReservedKeywords(sanitizedRuntimeName);
-  }
-}
+@import '../../../../scss/sp/sp-dialog.scss';
diff --git a/ui/src/app/configuration/security-configuration/security-configuration.component.ts b/ui/src/app/configuration/export/import-dialog/data-import-dialog.component.ts
similarity index 58%
copy from ui/src/app/configuration/security-configuration/security-configuration.component.ts
copy to ui/src/app/configuration/export/import-dialog/data-import-dialog.component.ts
index ee896a53e..5ef2a7fb6 100644
--- a/ui/src/app/configuration/security-configuration/security-configuration.component.ts
+++ b/ui/src/app/configuration/export/import-dialog/data-import-dialog.component.ts
@@ -17,23 +17,16 @@
  */
 
 import { Component, OnInit } from '@angular/core';
-import { SpConfigurationTabs } from '../configuration-tabs';
-import { SpBreadcrumbService } from '@streampipes/shared-ui';
-import { SpConfigurationRoutes } from '../configuration.routes';
 
 @Component({
-  selector: 'sp-security-configuration',
-  templateUrl: './security-configuration.component.html',
-  styleUrls: ['./security-configuration.component.scss']
+  selector: 'sp-data-import-dialog',
+  templateUrl: './data-import-dialog.component.html',
+  styleUrls: ['./data-import-dialog.component.scss'],
 })
-export class SecurityConfigurationComponent implements OnInit {
-
-  tabs = SpConfigurationTabs.getTabs();
-
-  constructor(private breadcrumbService: SpBreadcrumbService) {}
+export class SpDataImportDialogComponent implements OnInit {
 
   ngOnInit(): void {
-    this.breadcrumbService.updateBreadcrumb([SpConfigurationRoutes.BASE, {label: SpConfigurationTabs.getTabs()[5].itemTitle}]);
   }
 
+
 }
diff --git a/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.ts b/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.ts
index 0b68ae0c3..4d972b321 100644
--- a/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.ts
+++ b/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.ts
@@ -42,7 +42,7 @@ export class MessagingConfigurationComponent implements OnInit {
     }
 
     ngOnInit() {
-        this.breadcrumbService.updateBreadcrumb([SpConfigurationRoutes.BASE, {label: SpConfigurationTabs.getTabs()[3].itemTitle}]);
+        this.breadcrumbService.updateBreadcrumb([SpConfigurationRoutes.BASE, {label: SpConfigurationTabs.getTabs()[4].itemTitle}]);
         this.getMessagingSettings();
     }
 
diff --git a/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.ts b/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.ts
index 7fb8d260a..0d28979a4 100644
--- a/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.ts
+++ b/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.ts
@@ -60,7 +60,7 @@ export class PipelineElementConfigurationComponent implements OnInit {
   }
 
   ngOnInit() {
-    this.breadcrumbService.updateBreadcrumb([SpConfigurationRoutes.BASE, {label: SpConfigurationTabs.getTabs()[4].itemTitle}]);
+    this.breadcrumbService.updateBreadcrumb([SpConfigurationRoutes.BASE, {label: SpConfigurationTabs.getTabs()[5].itemTitle}]);
   }
 
   getConsulServices(): void {
diff --git a/ui/src/app/configuration/security-configuration/security-configuration.component.ts b/ui/src/app/configuration/security-configuration/security-configuration.component.ts
index ee896a53e..ca30cbab9 100644
--- a/ui/src/app/configuration/security-configuration/security-configuration.component.ts
+++ b/ui/src/app/configuration/security-configuration/security-configuration.component.ts
@@ -33,7 +33,7 @@ export class SecurityConfigurationComponent implements OnInit {
   constructor(private breadcrumbService: SpBreadcrumbService) {}
 
   ngOnInit(): void {
-    this.breadcrumbService.updateBreadcrumb([SpConfigurationRoutes.BASE, {label: SpConfigurationTabs.getTabs()[5].itemTitle}]);
+    this.breadcrumbService.updateBreadcrumb([SpConfigurationRoutes.BASE, {label: SpConfigurationTabs.getTabs()[6].itemTitle}]);
   }
 
 }


[incubator-streampipes] 01/06: [hotfix] Write tags in data explorer

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 3a30261a0d798f7f588b6d144d44a22b34f675bd
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Fri Jul 29 15:55:51 2022 +0200

    [hotfix] Write tags in data explorer
---
 .../dataexplorer/commons/DataExplorerWriter.java            |  2 +-
 .../datalake-configuration.component.html                   | 13 ++++++++++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/streampipes-data-explorer-commons/src/main/java/org/apache/streampipes/dataexplorer/commons/DataExplorerWriter.java b/streampipes-data-explorer-commons/src/main/java/org/apache/streampipes/dataexplorer/commons/DataExplorerWriter.java
index 3f3a1edc6..afb7387e2 100644
--- a/streampipes-data-explorer-commons/src/main/java/org/apache/streampipes/dataexplorer/commons/DataExplorerWriter.java
+++ b/streampipes-data-explorer-commons/src/main/java/org/apache/streampipes/dataexplorer/commons/DataExplorerWriter.java
@@ -35,7 +35,7 @@ public class DataExplorerWriter {
             } else if (data.get(key) instanceof Integer) {
                 builder.addField(key, (Integer) data.get(key));
             } else {
-                builder.addField(key, (String) data.get(key));
+                builder.tag(key, (String) data.get(key));
             }
         }
 
diff --git a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
index 07c6c0f3a..587a8b6b5 100644
--- a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
+++ b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
@@ -22,7 +22,18 @@
         <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
             <sp-split-section title="Data Lake Settings" subtitle="Truncate and delete persisted data streams">
                 <div fxFlex="100" fxLayout="column">
-                    <div class="subsection-title">Existing data lake indices</div>
+                    <div fxFlex="100" fxLayout="row">
+                        <div fxFlex fxLayoutAlign="start center" class="subsection-title">Existing data lake indices</div>
+                        <div fxLayout="row" fxLayoutAlign="end center">
+                            <button color="accent"
+                                    mat-button
+                                    mat-icon-button
+                                    matTooltip="Refresh Schema"
+                                    (click)="loadAvailableMeasurements()">
+                                <mat-icon>refresh</mat-icon>
+                            </button>
+                        </div>
+                    </div>
                     <table fxFlex="100" mat-table data-cy="datalake-settings" [dataSource]="dataSource"
                         style="width: 100%;" matSort>
 


[incubator-streampipes] 02/06: [hotfix] Extend data explorer API, add menu layout to base css

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 85eec4db2c32c99377eef6992eb842cc4ada4ab3
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Sun Jul 31 08:44:43 2022 +0200

    [hotfix] Extend data explorer API, add menu layout to base css
---
 .../src/lib/apis/data-view-data-explorer.service.ts                 | 6 ++++++
 ui/src/scss/sp/layout.scss                                          | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/data-view-data-explorer.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/data-view-data-explorer.service.ts
index ea89b7d63..3c721f074 100644
--- a/ui/projects/streampipes/platform-services/src/lib/apis/data-view-data-explorer.service.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/apis/data-view-data-explorer.service.ts
@@ -46,6 +46,12 @@ export class DataViewDataExplorerService {
     return this.sharedDatalakeRestService.getDashboards(this.dashboardUrl);
   }
 
+  getDataView(dataViewId: string): Observable<Dashboard> {
+    return this.http.get(this.dashboardUrl + '/' + dataViewId).pipe(map(data => {
+      return data as Dashboard;
+    }));
+  }
+
   updateDashboard(dashboard: Dashboard): Observable<Dashboard> {
     return this.sharedDatalakeRestService.updateDashboard(this.dashboardUrl, dashboard);
   }
diff --git a/ui/src/scss/sp/layout.scss b/ui/src/scss/sp/layout.scss
index 272feb17f..408188e4f 100644
--- a/ui/src/scss/sp/layout.scss
+++ b/ui/src/scss/sp/layout.scss
@@ -200,3 +200,6 @@ img {
   width: 20px;
   height: 20px;
 }
+
+.mat-menu-panel.large-menu { max-width: none; }
+


[incubator-streampipes] 04/06: [STREAMPIPES-545] Support data source links

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit bfa035132ec3cf41359d2f7b5c65a15bb8e7b046
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Sun Jul 31 11:21:51 2022 +0200

    [STREAMPIPES-545] Support data source links
---
 .../setup/tasks/CreateAssetLinkTypeTask.java       |  4 ++--
 .../edit-asset-link-dialog.component.html          | 12 +++++++++++
 .../edit-asset-link-dialog.component.ts            | 24 ++++++++++++++++++----
 ui/src/scss/_variables.scss                        |  3 ++-
 4 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateAssetLinkTypeTask.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateAssetLinkTypeTask.java
index 46bdc13bf..a16f86291 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateAssetLinkTypeTask.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateAssetLinkTypeTask.java
@@ -34,9 +34,9 @@ public class CreateAssetLinkTypeTask implements InstallationTask {
     new AssetLinkType("data-view", "Data View", "var(--color-data-view)", "search", "data-view", List.of("dataexplorer"), true),
     new AssetLinkType("dashboard", "Dashboard", "var(--color-dashboard)", "insert_chart", "dashboard", List.of("dashboard"), true),
     new AssetLinkType("adapter", "Adapter", "var(--color-adapter)", "power", "adapter", List.of("connect"), true),
-    new AssetLinkType("data-source", "Data Source", "var(--color-data-source)", "", "data-source", List.of(), false),
+    new AssetLinkType("data-source", "Data Source", "var(--color-data-source)", "dataset", "data-source", List.of(), false),
     new AssetLinkType("pipeline", "Pipeline", "var(--color-pipeline)", "play_arrow", "pipeline", List.of("pipeline", "details"), true),
-    new AssetLinkType("measurement", "Data Lake Storage", "var(--color-measurement)", "", "measurement", List.of(), false)
+    new AssetLinkType("measurement", "Data Lake Storage", "var(--color-measurement)", "folder", "measurement", List.of(), false)
   );
 
   @Override
diff --git a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html
index 8e1c77df1..b723edd0e 100644
--- a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html
+++ b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html
@@ -41,6 +41,18 @@
                     </mat-select>
                 </mat-form-field>
             </div>
+            <div *ngIf="selectedLinkType.linkQueryHint === 'data-source'" fxLayout="column" class="link-configuration">
+                <mat-form-field color="accent" fxFlex="100">
+                    <mat-label>Data Source</mat-label>
+                    <mat-select (selectionChange)="changeLabel($event.value.elementId, $event.value.name, $event.value)"
+                                [(value)]="currentResource"
+                                fxFlex
+                                required>
+                        <mat-option *ngFor="let source of dataSources"
+                                    [value]="source">{{source.name}}</mat-option>
+                    </mat-select>
+                </mat-form-field>
+            </div>
             <div *ngIf="selectedLinkType.linkQueryHint === 'dashboard'" fxLayout="column" class="link-configuration">
                 <mat-form-field color="accent" fxFlex="100">
                     <mat-label>Dashboards</mat-label>
diff --git a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts
index ff14435ad..ee42b9f4f 100644
--- a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts
+++ b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts
@@ -32,6 +32,11 @@ import {
 import { FormGroup } from '@angular/forms';
 import { zip } from 'rxjs';
 import { MatSelectChange } from '@angular/material/select';
+import {
+  AdapterDescriptionUnion,
+  SpDataStream
+} from '../../../../../projects/streampipes/platform-services/src/lib/model/gen/streampipes-model';
+import { PipelineElementService } from '../../../../../projects/streampipes/platform-services/src/lib/apis/pipeline-element.service';
 
 @Component({
   selector: 'sp-edit-asset-link-dialog-component',
@@ -58,6 +63,8 @@ export class EditAssetLinkDialogComponent implements OnInit {
   dataViews: Dashboard[];
   dashboards: Dashboard[];
   dataLakeMeasures: DataLakeMeasure[];
+  dataSources: SpDataStream[];
+  adapters: AdapterDescriptionUnion[];
 
   allResources: any[] = [];
   currentResource: any;
@@ -69,7 +76,8 @@ export class EditAssetLinkDialogComponent implements OnInit {
               private pipelineService: PipelineService,
               private dataViewService: DataViewDataExplorerService,
               private dashboardService: DashboardService,
-              private dataLakeService: DatalakeRestService) {
+              private dataLakeService: DatalakeRestService,
+              private pipelineElementService: PipelineElementService) {
   }
 
   ngOnInit(): void {
@@ -96,13 +104,21 @@ export class EditAssetLinkDialogComponent implements OnInit {
       this.pipelineService.getOwnPipelines(),
       this.dataViewService.getDataViews(),
       this.dashboardService.getDashboards(),
+      this.pipelineElementService.getDataStreams(),
       this.dataLakeService.getAllMeasurementSeries()).subscribe(response => {
       this.pipelines = response[0];
       this.dataViews = response[1];
       this.dashboards = response[2];
-      this.dataLakeMeasures = response[3];
-
-      this.allResources = [...this.pipelines, ...this.dataViews, ...this.dashboards, ...this.dataLakeMeasures];
+      this.dataSources = response[3];
+      this.dataLakeMeasures = response[4];
+
+      this.allResources = [
+        ...this.pipelines,
+        ...this.dataViews,
+        ...this.dashboards,
+        ...this.dataSources,
+        ...this.dataLakeMeasures
+      ];
       if (!this.createMode) {
         this.currentResource = this.allResources.find(r => r._id === this.clonedAssetLink.resourceId ||
           r.elementId === this.clonedAssetLink.resourceId);
diff --git a/ui/src/scss/_variables.scss b/ui/src/scss/_variables.scss
index 4ede67f5c..190b27ac2 100644
--- a/ui/src/scss/_variables.scss
+++ b/ui/src/scss/_variables.scss
@@ -34,7 +34,8 @@ body {
   --color-data-view: rgb(122, 206, 227);
   --color-dashboard: rgb(76, 115, 164);
   --color-adapter: rgb(182, 140, 97);
-  --color-stream: $sp-color-stream;
+  --color-data-source: #ffa23b;
   --color-pipeline: rgb(102, 185, 114);
+  --color-measurement: rgb(39, 164, 155);
 
 }


[incubator-streampipes] 05/06: [STREAMPIPES-545] Move adapter API to platform-services module

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit d6581497fa1dbdc5a1c3871ad71a58c3bf5f9505
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Sun Jul 31 11:35:19 2022 +0200

    [STREAMPIPES-545] Move adapter API to platform-services module
---
 .../src/lib/apis/adapter.service.ts}               | 39 +++-------------------
 .../platform-services/src/public-api.ts            |  1 +
 .../adapter-description.component.ts               |  5 ++-
 .../data-marketplace/data-marketplace.component.ts |  5 ++-
 .../existing-adapters.component.ts                 |  5 ++-
 .../filter-toolbar/filter-toolbar.component.ts     |  4 +--
 .../new-adapter/new-adapter.component.ts           |  6 ++--
 ui/src/app/connect/connect.module.ts               |  2 --
 .../delete-adapter-dialog.component.ts             |  5 ++-
 ui/src/app/connect/services/connect.service.ts     | 21 ++++++++++++
 10 files changed, 40 insertions(+), 53 deletions(-)

diff --git a/ui/src/app/connect/services/data-marketplace.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts
similarity index 68%
rename from ui/src/app/connect/services/data-marketplace.service.ts
rename to ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts
index a8dc5f995..d60352000 100644
--- a/ui/src/app/connect/services/data-marketplace.service.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts
@@ -19,25 +19,16 @@
 import { Injectable } from '@angular/core';
 import { HttpClient } from '@angular/common/http';
 import { map } from 'rxjs/operators';
-import { ConnectService } from './connect.service';
-import {
-  AdapterDescription,
-  AdapterDescriptionUnion,
-  GenericAdapterSetDescription,
-  GenericAdapterStreamDescription,
-  Message,
-  SpecificAdapterSetDescription,
-  SpecificAdapterStreamDescription,
-  PlatformServicesCommons
-} from '@streampipes/platform-services';
+
 import { Observable } from 'rxjs';
+import { PlatformServicesCommons } from './commons.service';
+import { AdapterDescription, AdapterDescriptionUnion, Message } from '../model/gen/streampipes-model';
 
-@Injectable()
-export class DataMarketplaceService {
+@Injectable({providedIn: 'root'})
+export class AdapterService {
 
   constructor(
       private http: HttpClient,
-      private connectService: ConnectService,
       private platformServicesCommons: PlatformServicesCommons) {
   }
 
@@ -100,26 +91,6 @@ export class DataMarketplaceService {
     );
   }
 
-  cloneAdapterDescription(toClone: AdapterDescriptionUnion): AdapterDescriptionUnion {
-    let result: AdapterDescriptionUnion;
-
-    if (this.connectService.isGenericDescription(toClone)) {
-      if (toClone instanceof GenericAdapterStreamDescription) {
-        result = GenericAdapterStreamDescription.fromData(toClone, new GenericAdapterStreamDescription());
-      } else if (toClone instanceof GenericAdapterSetDescription) {
-        result = GenericAdapterSetDescription.fromData(toClone, new GenericAdapterSetDescription());
-      }
-    } else {
-      if (toClone instanceof SpecificAdapterStreamDescription) {
-        result = SpecificAdapterStreamDescription.fromData(toClone, new SpecificAdapterStreamDescription());
-      } else if (toClone instanceof SpecificAdapterSetDescription) {
-        result = SpecificAdapterSetDescription.fromData(toClone, new SpecificAdapterSetDescription());
-      }
-    }
-
-    return result;
-  }
-
   getAssetUrl(appId) {
     return `${this.connectPath}/master/description/${appId}/assets`;
   }
diff --git a/ui/projects/streampipes/platform-services/src/public-api.ts b/ui/projects/streampipes/platform-services/src/public-api.ts
index a5415306c..e686a6e4b 100644
--- a/ui/projects/streampipes/platform-services/src/public-api.ts
+++ b/ui/projects/streampipes/platform-services/src/public-api.ts
@@ -24,6 +24,7 @@
 export * from './lib/platform-services.module';
 
 export * from './lib/apis/commons.service';
+export * from './lib/apis/adapter.service';
 export * from './lib/apis/asset-management.service';
 export * from './lib/apis/data-view-data-explorer.service';
 export * from './lib/apis/datalake-rest.service';
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 55519630d..89bea3356 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
@@ -18,10 +18,9 @@
 
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { ConnectService } from '../../../services/connect.service';
-import { DataMarketplaceService } from '../../../services/data-marketplace.service';
 import { AdapterExportDialog } from '../../../dialog/adapter-export/adapter-export-dialog.component';
 import { MatDialog } from '@angular/material/dialog';
-import { AdapterDescription } from '@streampipes/platform-services';
+import { AdapterDescription, AdapterService } from '@streampipes/platform-services';
 import { DialogService, PanelType } from '@streampipes/shared-ui';
 
 @Component({
@@ -49,7 +48,7 @@ export class AdapterDescriptionComponent implements OnInit {
   adapterLabel: string;
 
   constructor(private connectService: ConnectService,
-              private dataMarketplaceService: DataMarketplaceService,
+              private dataMarketplaceService: AdapterService,
               private dialogService: DialogService,
               public dialog: MatDialog) {
   }
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 ee19e47f4..6cf253ddd 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
@@ -17,10 +17,9 @@
  */
 
 import { Component, OnInit } from '@angular/core';
-import { DataMarketplaceService } from '../../services/data-marketplace.service';
 import { ShepherdService } from '../../../services/tour/shepherd.service';
 import { ConnectService } from '../../services/connect.service';
-import { AdapterDescriptionUnion } from '@streampipes/platform-services';
+import { AdapterDescriptionUnion, AdapterService } from '@streampipes/platform-services';
 import { DialogService, SpBreadcrumbService } from '@streampipes/shared-ui';
 import { Router } from '@angular/router';
 import { AdapterFilterSettingsModel } from '../../model/adapter-filter-settings.model';
@@ -40,7 +39,7 @@ export class DataMarketplaceComponent implements OnInit {
 
   currentFilter: AdapterFilterSettingsModel;
 
-  constructor(private dataMarketplaceService: DataMarketplaceService,
+  constructor(private dataMarketplaceService: AdapterService,
               private shepherdService: ShepherdService,
               private connectService: ConnectService,
               private dialogService: DialogService,
diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.ts b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.ts
index d6ccb3052..3a2490e3a 100644
--- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.ts
+++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.ts
@@ -17,10 +17,9 @@
  */
 
 import { Component, OnInit, ViewChild } from '@angular/core';
-import { AdapterDescriptionUnion, PipelineElementService } from '@streampipes/platform-services';
+import { AdapterDescriptionUnion, AdapterService, PipelineElementService } from '@streampipes/platform-services';
 import { MatTableDataSource } from '@angular/material/table';
 import { ConnectService } from '../../services/connect.service';
-import { DataMarketplaceService } from '../../services/data-marketplace.service';
 import { DialogRef, DialogService, PanelType, SpBreadcrumbService } from '@streampipes/shared-ui';
 import { DeleteAdapterDialogComponent } from '../../dialog/delete-adapter-dialog/delete-adapter-dialog.component';
 import { MatPaginator } from '@angular/material/paginator';
@@ -56,7 +55,7 @@ export class ExistingAdaptersComponent implements OnInit {
   isAdmin = false;
 
   constructor(public connectService: ConnectService,
-              private dataMarketplaceService: DataMarketplaceService,
+              private dataMarketplaceService: AdapterService,
               private dialogService: DialogService,
               private authService: AuthService,
               private pipelineElementService: PipelineElementService,
diff --git a/ui/src/app/connect/components/filter-toolbar/filter-toolbar.component.ts b/ui/src/app/connect/components/filter-toolbar/filter-toolbar.component.ts
index 0540be51b..7e67e7ddc 100644
--- a/ui/src/app/connect/components/filter-toolbar/filter-toolbar.component.ts
+++ b/ui/src/app/connect/components/filter-toolbar/filter-toolbar.component.ts
@@ -17,7 +17,7 @@
  */
 
 import { Component, EventEmitter, OnInit, Output } from '@angular/core';
-import { DataMarketplaceService } from '../../services/data-marketplace.service';
+import { AdapterService } from '@streampipes/platform-services';
 import { MatSelectChange } from '@angular/material/select';
 import { AdapterFilterSettingsModel } from '../../model/adapter-filter-settings.model';
 
@@ -36,7 +36,7 @@ export class SpConnectFilterToolbarComponent implements OnInit {
 
   currentFilter: AdapterFilterSettingsModel = {textFilter: '', selectedCategory: 'All', selectedType: 'All types'};
 
-  constructor(private dataMarketplaceService: DataMarketplaceService) {
+  constructor(private dataMarketplaceService: AdapterService) {
 
   }
 
diff --git a/ui/src/app/connect/components/new-adapter/new-adapter.component.ts b/ui/src/app/connect/components/new-adapter/new-adapter.component.ts
index 1c81025bf..1cdee14b4 100644
--- a/ui/src/app/connect/components/new-adapter/new-adapter.component.ts
+++ b/ui/src/app/connect/components/new-adapter/new-adapter.component.ts
@@ -21,6 +21,7 @@ import { FormBuilder, FormGroup } from '@angular/forms';
 import { MatStepper } from '@angular/material/stepper';
 import {
   AdapterDescriptionUnion,
+  AdapterService,
   EventSchema,
   GenericAdapterSetDescription,
   GenericAdapterStreamDescription,
@@ -36,7 +37,6 @@ import { EventSchemaComponent } from './schema-editor/event-schema/event-schema.
 import { TransformationRuleService } from '../../services/transformation-rule.service';
 import { IconService } from '../../services/icon.service';
 import { ActivatedRoute, Router } from '@angular/router';
-import { DataMarketplaceService } from '../../services/data-marketplace.service';
 import { SpBreadcrumbService } from '@streampipes/shared-ui';
 import { SpConnectRoutes } from '../../connect.routes';
 
@@ -94,7 +94,7 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
     private iconService: IconService,
     private changeDetectorRef: ChangeDetectorRef,
     private route: ActivatedRoute,
-    private dataMarketplaceService: DataMarketplaceService,
+    private dataMarketplaceService: AdapterService,
     private router: Router,
     private breadcrumbService: SpBreadcrumbService) {
   }
@@ -115,7 +115,7 @@ export class NewAdapterComponent implements OnInit, AfterViewInit {
 
     this.dataMarketplaceService.getAdapterDescriptions().subscribe(adapters => {
       const adapter = adapters.find(a => a.appId === this.route.snapshot.params.appId);
-      this.adapter = this.dataMarketplaceService.cloneAdapterDescription(adapter);
+      this.adapter = this.connectService.cloneAdapterDescription(adapter);
       this.breadcrumbService.updateBreadcrumb(this.breadcrumbService.makeRoute([SpConnectRoutes.BASE, SpConnectRoutes.CREATE], this.adapter.name));
       (this.adapter as any).templateTitle = this.adapter.name;
       this.adapter.name = '';
diff --git a/ui/src/app/connect/connect.module.ts b/ui/src/app/connect/connect.module.ts
index 8fb26c7d8..e7e324795 100644
--- a/ui/src/app/connect/connect.module.ts
+++ b/ui/src/app/connect/connect.module.ts
@@ -39,7 +39,6 @@ import { TransformationRuleService } from './services/transformation-rule.servic
 import { ConnectService } from './services/connect.service';
 import { AdapterDescriptionComponent } from './components/data-marketplace/adapter-description/adapter-description.component';
 import { DataMarketplaceComponent } from './components/data-marketplace/data-marketplace.component';
-import { DataMarketplaceService } from './services/data-marketplace.service';
 import { FormatItemComponent } from './components/new-adapter/format-configuration/format-item/format-item.component';
 import { FormatListComponent } from './components/new-adapter/format-configuration/format-list/format-list.component';
 import { IconService } from './services/icon.service';
@@ -170,7 +169,6 @@ import { SpAdapterTemplateDialogComponent } from './dialog/adapter-template/adap
     DataTypesService,
     TransformationRuleService,
     StaticPropertyUtilService,
-    DataMarketplaceService,
     IconService,
     UnitProviderService,
     TimestampPipe,
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
index ce05016f6..dc61d383b 100644
--- 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
@@ -17,9 +17,8 @@
  */
 
 import { Component, Input } from '@angular/core';
-import { AdapterDescriptionUnion } from '@streampipes/platform-services';
+import { AdapterDescriptionUnion, AdapterService } from '@streampipes/platform-services';
 import { DialogRef } from '@streampipes/shared-ui';
-import { DataMarketplaceService } from '../../services/data-marketplace.service';
 
 @Component({
     selector: 'sp-delete-adapter-dialog',
@@ -37,7 +36,7 @@ export class DeleteAdapterDialogComponent {
     numberOfPipelinesWithAdapter = 0;
 
     constructor(private dialogRef: DialogRef<DeleteAdapterDialogComponent>,
-                private dataMarketplaceService: DataMarketplaceService) {
+                private dataMarketplaceService: AdapterService) {
     }
 
     close(refreshAdapters: boolean) {
diff --git a/ui/src/app/connect/services/connect.service.ts b/ui/src/app/connect/services/connect.service.ts
index 1e4b73db7..740cc4319 100644
--- a/ui/src/app/connect/services/connect.service.ts
+++ b/ui/src/app/connect/services/connect.service.ts
@@ -25,6 +25,7 @@ import {
   SpecificAdapterSetDescription,
   SpecificAdapterStreamDescription
 } from '@streampipes/platform-services';
+import { AdapterDescriptionUnion } from '../../../../projects/streampipes/platform-services/src/lib/model/gen/streampipes-model';
 
 @Injectable()
 export class ConnectService {
@@ -67,5 +68,25 @@ export class ConnectService {
     }
   }
 
+  cloneAdapterDescription(toClone: AdapterDescriptionUnion): AdapterDescriptionUnion {
+    let result: AdapterDescriptionUnion;
+
+    if (this.isGenericDescription(toClone)) {
+      if (toClone instanceof GenericAdapterStreamDescription) {
+        result = GenericAdapterStreamDescription.fromData(toClone, new GenericAdapterStreamDescription());
+      } else if (toClone instanceof GenericAdapterSetDescription) {
+        result = GenericAdapterSetDescription.fromData(toClone, new GenericAdapterSetDescription());
+      }
+    } else {
+      if (toClone instanceof SpecificAdapterStreamDescription) {
+        result = SpecificAdapterStreamDescription.fromData(toClone, new SpecificAdapterStreamDescription());
+      } else if (toClone instanceof SpecificAdapterSetDescription) {
+        result = SpecificAdapterSetDescription.fromData(toClone, new SpecificAdapterSetDescription());
+      }
+    }
+
+    return result;
+  }
+
 
 }