From ba65ecfb7b9ff1e2100dfebb3ea0e6bc8cab5c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 12 Sep 2025 08:54:44 +0200 Subject: [PATCH 001/113] added a vire creation --- .../storage/couchdb/utils/CouchDbViewGenerator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/CouchDbViewGenerator.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/CouchDbViewGenerator.java index 2fb1c026ff..d368b5beb7 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/CouchDbViewGenerator.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/CouchDbViewGenerator.java @@ -64,7 +64,10 @@ private void createViews() throws IOException { + "\"views\": {\n" + "\"appDocType\": {\n" + "\"map\": \"function (doc) {\\nif (doc._id) {\\nemit([doc.appDocType, doc._id], 1)\\n}\\n}\"\n" - + "}\n" + + "},\n" + + "\"by_created_at\": {\n" + + "\"map\": \"function (doc) {\\nif (doc.created_at) {\\nemit(doc.created_at, null);\\n}\\n}\"\n" + + "}\n" + "},\n" + "\"language\": \"javascript\"\n" + "}"; From 245e10711e9bd299bcc655d8488537f1650bc762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 12 Sep 2025 11:00:43 +0200 Subject: [PATCH 002/113] Paginator created by in backend working with curl --- .../setup/CouchDbInstallationStep.java | 19 ++++++++++++++++++- .../couchdb/utils/CouchDbViewGenerator.java | 5 +---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index 1e627973c6..83aafde6de 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -79,6 +79,7 @@ private void createViews() { addNotificationView(); addPipelineView(); addDataLakeMeasureView(); + addPaginatorView(); } private void addNotificationView() { @@ -125,7 +126,23 @@ private void addNotificationView() { logFailure(PREPARING_NOTIFICATIONS_TEXT, e); } } - +private void addPaginatorView(){ + //TODO flexibilise ? + DesignDocument paginatorDocument = prepareDocument("_design/paginator"); + Map paginatorViews = new HashMap<>(); + + MapReduce paginationFunction = new MapReduce(); + paginationFunction.setMap("function (doc) {\n" + + " if (doc.created_at) {\n" + + " emit(doc.created_at, doc);\n" + + " }\n" + + "}"); + + paginatorViews.put("by_created_at", paginationFunction); + paginatorDocument.setViews(paginatorViews); + // Configure here where the views go + Utils.getCouchDbAdapterInstanceClient().design().synchronizeWithDb(paginatorDocument); + } private void addPipelineView() { DesignDocument pipelineDocument = prepareDocument("_design/adapters"); DesignDocument allPipelinesDocument = prepareDocument("_design/pipelines"); diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/CouchDbViewGenerator.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/CouchDbViewGenerator.java index d368b5beb7..2fb1c026ff 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/CouchDbViewGenerator.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/CouchDbViewGenerator.java @@ -64,10 +64,7 @@ private void createViews() throws IOException { + "\"views\": {\n" + "\"appDocType\": {\n" + "\"map\": \"function (doc) {\\nif (doc._id) {\\nemit([doc.appDocType, doc._id], 1)\\n}\\n}\"\n" - + "},\n" - + "\"by_created_at\": {\n" - + "\"map\": \"function (doc) {\\nif (doc.created_at) {\\nemit(doc.created_at, null);\\n}\\n}\"\n" - + "}\n" + + "}\n" + "},\n" + "\"language\": \"javascript\"\n" + "}"; From 3e6d95ecf96cc1cd2f85f5852828dabecb3a87fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 12 Sep 2025 11:38:43 +0200 Subject: [PATCH 003/113] curl after date working --- .../streampipes/manager/setup/CouchDbInstallationStep.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index 83aafde6de..62b11abca2 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -133,12 +133,12 @@ private void addPaginatorView(){ MapReduce paginationFunction = new MapReduce(); paginationFunction.setMap("function (doc) {\n" - + " if (doc.created_at) {\n" - + " emit(doc.created_at, doc);\n" + + " if (doc.properties.createdAt) {\n" + + " emit(doc.properties.createdAt, doc);\n" + " }\n" + "}"); - paginatorViews.put("by_created_at", paginationFunction); + paginatorViews.put("by_createdAt", paginationFunction); paginatorDocument.setViews(paginatorViews); // Configure here where the views go Utils.getCouchDbAdapterInstanceClient().design().synchronizeWithDb(paginatorDocument); From 714db3e39562afc6161c9b4a8a11d87ad0e48128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 12 Sep 2025 15:30:38 +0200 Subject: [PATCH 004/113] fix for findAll not working after introducing design view --- .../impl/AdapterInstanceStorageImpl.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 9b9f68eb3f..233cbc5888 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -21,12 +21,18 @@ import org.apache.streampipes.model.connect.adapter.AdapterDescription; import org.apache.streampipes.storage.api.IAdapterStorage; import org.apache.streampipes.storage.couchdb.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; + public class AdapterInstanceStorageImpl extends DefaultCrudStorage implements IAdapterStorage { + private static final Logger LOG = LoggerFactory.getLogger(AdapterInstanceStorageImpl.class.getCanonicalName()); + public AdapterInstanceStorageImpl() { super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); } @@ -47,4 +53,25 @@ public List getAdaptersByAppId(String appId) { .filter(p -> p.getAppId().equals(appId)) .toList(); } + @Override +public List findAll() { + LOG.info("GOING INTO FIND ALL "); + List adapters = findAll("paginator/non_design_docs"); +LOG.info(adapters.toString()); + // Filter out any malformed or incomplete AdapterDescriptions + return adapters.stream() + .filter(adapter -> adapter.getDescription() != null) + .toList(); +} + + public List getAdapterPaginator(String startitem, int limit) { + //TODO Fix this implementation + List pipelinesWithAdapter = + couchDbClientSupplier + .get() + .view("paginator") + .key(startitem) + .query(AdapterDescription.class); + return pipelinesWithAdapter;//.stream().map(p -> p.get("value").getAsString()).collect(Collectors.toList()); + } } From 3c48b9291370f9dcfc68a5a1f583a264126f106e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 12 Sep 2025 15:31:59 +0200 Subject: [PATCH 005/113] eliminated prints --- .../storage/couchdb/impl/AdapterInstanceStorageImpl.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 233cbc5888..ff2104677b 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -55,10 +55,7 @@ public List getAdaptersByAppId(String appId) { } @Override public List findAll() { - LOG.info("GOING INTO FIND ALL "); List adapters = findAll("paginator/non_design_docs"); -LOG.info(adapters.toString()); - // Filter out any malformed or incomplete AdapterDescriptions return adapters.stream() .filter(adapter -> adapter.getDescription() != null) .toList(); From 7edded72b668bff6331fe1faed64e728aef67fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 12 Sep 2025 16:15:26 +0200 Subject: [PATCH 006/113] first step to working paginator API in Adapter --- .../management/AdapterMasterManagement.java | 9 ++++ .../setup/CouchDbInstallationStep.java | 53 +++++++++++++------ .../rest/impl/connect/AdapterResource.java | 12 +++++ .../storage/api/IAdapterStorage.java | 2 + .../impl/AdapterDescriptionStorageImpl.java | 6 +++ .../impl/AdapterInstanceStorageImpl.java | 33 ++++++------ 6 files changed, 82 insertions(+), 33 deletions(-) diff --git a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java index 9b1002c527..128df0fce8 100644 --- a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java +++ b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java @@ -145,6 +145,15 @@ public List getAllAdapterInstances() { return adapterInstanceStorage.findAll(); } + public List getPaginatedAdapterInstances(String startkey, int limit){ + return adapterInstanceStorage.getAdapterPaginator(startkey, limit); + } + + //public List getPagedAdapterInstances(String startKey, int limit) { + // LOG.info("Get Paged"); + //return adapterInstanceStorage.findAll(); + //} + public void stopStreamAdapter(String elementId, boolean forceStop) throws AdapterException { AdapterDescription ad = adapterInstanceStorage.getElementById(elementId); diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index 62b11abca2..928b694e65 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -126,23 +126,42 @@ private void addNotificationView() { logFailure(PREPARING_NOTIFICATIONS_TEXT, e); } } -private void addPaginatorView(){ - //TODO flexibilise ? - DesignDocument paginatorDocument = prepareDocument("_design/paginator"); - Map paginatorViews = new HashMap<>(); - - MapReduce paginationFunction = new MapReduce(); - paginationFunction.setMap("function (doc) {\n" - + " if (doc.properties.createdAt) {\n" - + " emit(doc.properties.createdAt, doc);\n" - + " }\n" - + "}"); - - paginatorViews.put("by_createdAt", paginationFunction); - paginatorDocument.setViews(paginatorViews); - // Configure here where the views go - Utils.getCouchDbAdapterInstanceClient().design().synchronizeWithDb(paginatorDocument); - } +private void addPaginatorView() { + DesignDocument paginatorDocument = prepareDocument("_design/paginator"); + + Map paginatorViews = new HashMap<>(); + + // View to paginate documents by creation time + MapReduce paginationFunction = new MapReduce(); + paginationFunction.setMap( + "function (doc) {\n" + + " if (doc.properties && doc.properties.createdAt) {\n" + + " emit(doc.properties.createdAt, doc);\n" + + " }\n" + + "}" + ); + + // View to list all non-design documents + MapReduce nonDesignDocsView = new MapReduce(); + nonDesignDocsView.setMap( + "function (doc) {\n" + + " if (!doc._id.startsWith(\"_design/\")) {\n" + + " emit(doc._id, null);\n" + + " }\n" + + "}" + ); + + // Add views to the document + paginatorViews.put("by_createdAt", paginationFunction); + paginatorViews.put("non_design_docs", nonDesignDocsView); + + paginatorDocument.setViews(paginatorViews); + + // Push the design document to CouchDB + Utils.getCouchDbAdapterInstanceClient() + .design() + .synchronizeWithDb(paginatorDocument); +} private void addPipelineView() { DesignDocument pipelineDocument = prepareDocument("_design/adapters"); DesignDocument allPipelinesDocument = prepareDocument("_design/pipelines"); diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java index cf046735b1..c71bda6191 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java @@ -296,9 +296,21 @@ public ResponseEntity deleteAdapter( @PreAuthorize("this.hasReadAuthority()") @PostFilter("hasPermission(filterObject.correspondingDataStreamElementId, 'READ')") public List getAllAdapters() { + LOG.info("GET ALL ADAPTERS"); return managementService.getAllAdapterInstances(); } + @GetMapping(path = "/paginator", produces = MediaType.APPLICATION_JSON_VALUE) +@PreAuthorize("this.hasReadAuthority()") +@PostFilter("hasPermission(filterObject.correspondingDataStreamElementId, 'READ')") +public List getAllAdaptersPaginated( + @RequestParam(required = false) String startkey, + @RequestParam(defaultValue = "10") int limit) { + + LOG.info("GET Paginated ADAPTERS: startkey={}, limit={}", startkey, limit); + return managementService.getPaginatedAdapterInstances(startkey, limit); +} + private AdapterDescription getAdapterDescription(String elementId) throws AdapterException { return managementService.getAdapter(elementId); } diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java index 36ecb20ac8..f170125b32 100644 --- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java +++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java @@ -27,4 +27,6 @@ public interface IAdapterStorage extends CRUDStorage { AdapterDescription getFirstAdapterByAppId(String appId); List getAdaptersByAppId(String appId); + + List getAdapterPaginator(String startitem, int limit); } diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java index cd78b5af69..d3ebcb984a 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java @@ -59,4 +59,10 @@ public AdapterDescription updateElement(AdapterDescription element) { private String getCurrentRev(String elementId) { return find(elementId).get().getRev(); } + + @Override + public List getAdapterPaginator(String startitem, int limit) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getAdapterPaginator'"); + } } diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index ff2104677b..d60a4104c0 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -28,10 +28,9 @@ import java.util.List; import java.util.NoSuchElementException; - public class AdapterInstanceStorageImpl extends DefaultCrudStorage implements IAdapterStorage { - private static final Logger LOG = LoggerFactory.getLogger(AdapterInstanceStorageImpl.class.getCanonicalName()); + private static final Logger LOG = LoggerFactory.getLogger(AdapterInstanceStorageImpl.class.getCanonicalName()); public AdapterInstanceStorageImpl() { super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); @@ -53,22 +52,24 @@ public List getAdaptersByAppId(String appId) { .filter(p -> p.getAppId().equals(appId)) .toList(); } + @Override -public List findAll() { + public List findAll() { List adapters = findAll("paginator/non_design_docs"); return adapters.stream() - .filter(adapter -> adapter.getDescription() != null) - .toList(); -} - - public List getAdapterPaginator(String startitem, int limit) { - //TODO Fix this implementation - List pipelinesWithAdapter = - couchDbClientSupplier - .get() - .view("paginator") - .key(startitem) - .query(AdapterDescription.class); - return pipelinesWithAdapter;//.stream().map(p -> p.get("value").getAsString()).collect(Collectors.toList()); + .filter(adapter -> adapter.getDescription() != null) + .toList(); + } + @Override + public List getAdapterPaginator(String startItem, int limit) { + + return couchDbClientSupplier + .get() + .view("paginator/by_createdAt") + .includeDocs(true) + .limit(limit) + .startKey(startItem) + .descending(false) + .query(AdapterDescription.class); } } From 9886a86d83d270b0fc5dedd049e1734e2471fbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 08:23:45 +0200 Subject: [PATCH 007/113] startkey working --- .../couchdb/impl/AdapterInstanceStorageImpl.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index d60a4104c0..c4bc2737d0 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -60,15 +60,29 @@ public List findAll() { .filter(adapter -> adapter.getDescription() != null) .toList(); } + @Override public List getAdapterPaginator(String startItem, int limit) { + long startItemLong = 0L; // default value + try { + startItemLong = Long.parseLong(startItem); + + } catch (Exception e) { + return couchDbClientSupplier + .get() + .view("paginator/by_createdAt") + .includeDocs(true) + .limit(limit) + .descending(false) + .query(AdapterDescription.class); + } return couchDbClientSupplier .get() .view("paginator/by_createdAt") .includeDocs(true) .limit(limit) - .startKey(startItem) + .startKey(startItemLong) .descending(false) .query(AdapterDescription.class); } From 255338679fd29ae905f65b6196bb9276ce040d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 09:09:21 +0200 Subject: [PATCH 008/113] small fix in migration v093 to make it runnable with design docs --- .../service/core/migrations/v093/AdapterMigration.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v093/AdapterMigration.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v093/AdapterMigration.java index 0e488db656..93759d64cd 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v093/AdapterMigration.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v093/AdapterMigration.java @@ -67,9 +67,8 @@ public boolean shouldExecute() { findDocsToMigrate(adapterInstanceClient, adapterInstanceUri, adaptersToMigrate); findDocsToMigrate(adapterDescriptionClient, adapterDescriptionUri, adapterDescriptionsToRemove); - return !adaptersToMigrate.isEmpty() || !adapterDescriptionsToRemove.isEmpty(); + return !adaptersToMigrate.isEmpty() || !adapterDescriptionsToRemove.isEmpty(); } - private void findDocsToMigrate(CouchDbClient adapterClient, String uri, List collector) { @@ -78,6 +77,11 @@ private void findDocsToMigrate(CouchDbClient adapterClient, var rows = existingAdapters.get(ROWS); rows.getAsJsonArray().forEach(row -> { var doc = row.getAsJsonObject().get("doc").getAsJsonObject(); + var id = doc.get("_id").getAsString(); + // Skip design documents + if (id.startsWith("_design/")) { + return; + } var docType = doc.get("type").getAsString(); if (AdapterModels.shouldMigrate(docType)) { collector.add(doc); @@ -135,7 +139,7 @@ public String getDescription() { return "Migrate all adapters to new data model"; } - private String getAllDocsUri(CouchDbClient client) { + private String getAllDocsUri(CouchDbClient client) { return client.getDBUri().toString() + "_all_docs" + "?include_docs=true"; } From b6e7b7924c4a85ede52232b77681cfc2d14f6af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 09:44:58 +0200 Subject: [PATCH 009/113] additional views and adapter migration --- .../setup/CouchDbInstallationStep.java | 28 +++++++++++++++++-- .../migrations/v093/AdapterMigration.java | 4 +-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index 928b694e65..4335312d23 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -132,8 +132,8 @@ private void addPaginatorView() { Map paginatorViews = new HashMap<>(); // View to paginate documents by creation time - MapReduce paginationFunction = new MapReduce(); - paginationFunction.setMap( + MapReduce paginationFunctionByCreate = new MapReduce(); + paginationFunctionByCreate.setMap( "function (doc) {\n" + " if (doc.properties && doc.properties.createdAt) {\n" + " emit(doc.properties.createdAt, doc);\n" @@ -141,6 +141,26 @@ private void addPaginatorView() { + "}" ); + // View to paginate documents by name + MapReduce paginationFunctionByName = new MapReduce(); + paginationFunctionByName.setMap( + "function (doc) {\n" + + " if (doc.properties && doc.properties.name) {\n" + + " emit(doc.properties.name, doc);\n" + + " }\n" + + "}" + ); + + // View to paginate documents by running + MapReduce paginationFunctionByRunning = new MapReduce(); + paginationFunctionByRunning.setMap( + "function (doc) {\n" + + " if (doc.properties && doc.properties.running) {\n" + + " emit(doc.properties.running, doc);\n" + + " }\n" + + "}" + ); + // View to list all non-design documents MapReduce nonDesignDocsView = new MapReduce(); nonDesignDocsView.setMap( @@ -152,7 +172,9 @@ private void addPaginatorView() { ); // Add views to the document - paginatorViews.put("by_createdAt", paginationFunction); + paginatorViews.put("by_createdAt", paginationFunctionByCreate); + paginatorViews.put("by_name", paginationFunctionByName); + paginatorViews.put("by_running", paginationFunctionByRunning); paginatorViews.put("non_design_docs", nonDesignDocsView); paginatorDocument.setViews(paginatorViews); diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v093/AdapterMigration.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v093/AdapterMigration.java index 93759d64cd..01247b68cb 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v093/AdapterMigration.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v093/AdapterMigration.java @@ -77,7 +77,7 @@ private void findDocsToMigrate(CouchDbClient adapterClient, var rows = existingAdapters.get(ROWS); rows.getAsJsonArray().forEach(row -> { var doc = row.getAsJsonObject().get("doc").getAsJsonObject(); - var id = doc.get("_id").getAsString(); + var id = doc.get("_id").getAsString(); // Skip design documents if (id.startsWith("_design/")) { return; @@ -139,7 +139,7 @@ public String getDescription() { return "Migrate all adapters to new data model"; } - private String getAllDocsUri(CouchDbClient client) { +private String getAllDocsUri(CouchDbClient client) { return client.getDBUri().toString() + "_all_docs" + "?include_docs=true"; } From 35d08f8f9d21d12af6148d6f42b5defe64b7dde6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 09:59:52 +0200 Subject: [PATCH 010/113] drafted UI Component --- .../basic-view-pagination.component.html | 54 +++++++++++++++++ .../basic-view-pagination.component.scss | 59 +++++++++++++++++++ .../basic-view-pagination.component.ts | 42 +++++++++++++ .../basic-view/basic-view.component.ts | 16 ++--- .../shared-ui/src/lib/shared-ui.module.ts | 2 + 5 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.html create mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.scss create mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.ts diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.html b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.html new file mode 100644 index 0000000000..84264219ee --- /dev/null +++ b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.html @@ -0,0 +1,54 @@ + + +
+
+
+
+ +
+ +
+
+ +
+ +
+
diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.scss b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.scss new file mode 100644 index 0000000000..ac8e22cd4b --- /dev/null +++ b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.scss @@ -0,0 +1,59 @@ +/* + * 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. + * + */ + +.fixed-height { + flex-direction: row; + box-sizing: border-box; + display: flex; + flex: 1 1 100%; + max-height: 100%; + overflow-y: auto; +} + +.page-container-nav { + line-height: 24px; + height: 44px; + border-bottom: 1px solid var(--color-bg-3); +} + +.sp-bg-lightgray { + background-color: var(--color-bg-main-panel-header); +} + +.sp-tab-bg { + background-color: var(--color-bg-main-panel-header); +} + +.page-container { + margin: 10px; + border: 1px solid var(--color-bg-3); + min-height: calc(100vh - 90px); + background-color: var(--color-bg-main-panel-content); +} + +.page-container-padding-inner { + margin: 20px; +} + +.pl-5 { + padding-left: 5px; +} + +.pr-5 { + padding-right: 5px; +} diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.ts new file mode 100644 index 0000000000..7d884b9aca --- /dev/null +++ b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.ts @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { Component, input } from '@angular/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'sp-basic-view-pagination', + templateUrl: './basic-view-pagination.component.html', + styleUrls: ['./basic-view-pagination.component.scss'], + standalone: false, +}) +export class SpBasicViewPaginationComponent { + padding = input(false); + + showBackLink = input(false); + + backLinkTarget = input(); + + hideNavbar = input(false); + + constructor(private router: Router) {} + + navigateBack() { + this.router.navigate(this.backLinkTarget()); + } +} diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view/basic-view.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view/basic-view.component.ts index fb5ffcf2b1..a44f805a52 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view/basic-view.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view/basic-view.component.ts @@ -16,7 +16,7 @@ * */ -import { Component, Input } from '@angular/core'; +import { Component, input } from '@angular/core'; import { Router } from '@angular/router'; @Component({ @@ -26,21 +26,17 @@ import { Router } from '@angular/router'; standalone: false, }) export class SpBasicViewComponent { - @Input() - padding = false; + padding = input(false); - @Input() - showBackLink = false; + showBackLink = input(false); - @Input() - backLinkTarget: string[]; + backLinkTarget = input(); - @Input() - hideNavbar = false; + hideNavbar = input(false); constructor(private router: Router) {} navigateBack() { - this.router.navigate(this.backLinkTarget); + this.router.navigate(this.backLinkTarget()); } } diff --git a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts index 0ead4013e3..f79dba92aa 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts @@ -98,6 +98,7 @@ import { InputSchemaPropertyComponent } from './components/input-schema-panel/in import { MatExpansionModule } from '@angular/material/expansion'; import { SortByRuntimeNamePipe } from './pipes/sort-by-runtime-name.pipe'; import { DragDropModule } from '@angular/cdk/drag-drop'; +import { SpBasicViewPaginationComponent } from './components/basic-view-pagination/basic-view-pagination.component'; @NgModule({ declarations: [ @@ -121,6 +122,7 @@ import { DragDropModule } from '@angular/cdk/drag-drop'; SpBasicInnerPanelComponent, SpBasicHeaderTitleComponent, SpBasicViewComponent, + SpBasicViewPaginationComponent, SpBasicNavTabsComponent, SpExceptionMessageComponent, SpExceptionDetailsComponent, From 7d77ef6b063a2283eef07187bd834fe77e5ac1b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 10:21:33 +0200 Subject: [PATCH 011/113] first draft paginator service --- .../src/lib/apis/adapter.service.ts | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index fcd293a0ff..7a7d9c2e1d 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -17,7 +17,7 @@ */ import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { map } from 'rxjs/operators'; import { Observable } from 'rxjs'; @@ -48,6 +48,18 @@ export class AdapterService { return this.requestAdapterDescriptions('/master/adapters'); } + getAdaptersPaginated( + path: string, + startid: string | null, + limit: number, + ): Observable { + return this.requestAdapterDescriptionsPaginated( + '/master/adapters/paginator', + startid, + limit, + ); + } + getAdapter(id: string): Observable { return this.http .get(this.connectPath + `/master/adapters/${id}`) @@ -65,6 +77,28 @@ export class AdapterService { ); } + requestAdapterDescriptionsPaginated( + path: string, + startid: string | null, + limit: number, + ): Observable { + let params = new HttpParams().set('limit', limit.toString()); + + if (startid) { + params = params.set('startkey', startid); + } + + const url = `${this.connectPath}${path}`; + + return this.http.get(url, { params }).pipe( + map(response => { + return (response as any[]).map(p => + AdapterDescription.fromData(p), + ); + }), + ); + } + requestAdapterDescriptions(path: string): Observable { return this.http.get(this.connectPath + path).pipe( map(response => { From c26d1f1299000a424b9d7111c2dd2c77b9dbcf26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 13:57:35 +0200 Subject: [PATCH 012/113] deleted some stuff --- .../basic-view-pagination.component.html | 54 ----------------- .../basic-view-pagination.component.scss | 59 ------------------- .../basic-view-pagination.component.ts | 42 ------------- 3 files changed, 155 deletions(-) delete mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.html delete mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.scss delete mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.ts diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.html b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.html deleted file mode 100644 index 84264219ee..0000000000 --- a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.html +++ /dev/null @@ -1,54 +0,0 @@ - - -
-
-
-
- -
- -
-
- -
- -
-
diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.scss b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.scss deleted file mode 100644 index ac8e22cd4b..0000000000 --- a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.scss +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - * - */ - -.fixed-height { - flex-direction: row; - box-sizing: border-box; - display: flex; - flex: 1 1 100%; - max-height: 100%; - overflow-y: auto; -} - -.page-container-nav { - line-height: 24px; - height: 44px; - border-bottom: 1px solid var(--color-bg-3); -} - -.sp-bg-lightgray { - background-color: var(--color-bg-main-panel-header); -} - -.sp-tab-bg { - background-color: var(--color-bg-main-panel-header); -} - -.page-container { - margin: 10px; - border: 1px solid var(--color-bg-3); - min-height: calc(100vh - 90px); - background-color: var(--color-bg-main-panel-content); -} - -.page-container-padding-inner { - margin: 20px; -} - -.pl-5 { - padding-left: 5px; -} - -.pr-5 { - padding-right: 5px; -} diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.ts deleted file mode 100644 index 7d884b9aca..0000000000 --- a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view-pagination/basic-view-pagination.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { Component, input } from '@angular/core'; -import { Router } from '@angular/router'; - -@Component({ - selector: 'sp-basic-view-pagination', - templateUrl: './basic-view-pagination.component.html', - styleUrls: ['./basic-view-pagination.component.scss'], - standalone: false, -}) -export class SpBasicViewPaginationComponent { - padding = input(false); - - showBackLink = input(false); - - backLinkTarget = input(); - - hideNavbar = input(false); - - constructor(private router: Router) {} - - navigateBack() { - this.router.navigate(this.backLinkTarget()); - } -} From bb93ab394b70ead12395a17c5dd8db7a1153611a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 14:49:50 +0200 Subject: [PATCH 013/113] first page table ui --- .../src/lib/apis/adapter.service.ts | 5 +- .../sp-table-pagination.component.html | 44 +++++++ .../sp-table-pagination.component.scss | 30 +++++ .../sp-table-pagination.component.ts | 107 ++++++++++++++++++ .../shared-ui/src/lib/shared-ui.module.ts | 5 +- .../existing-adapters.component.html | 5 +- .../existing-adapters.component.ts | 14 +-- 7 files changed, 195 insertions(+), 15 deletions(-) create mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html create mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.scss create mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index 7a7d9c2e1d..e4f0796db0 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -49,8 +49,7 @@ export class AdapterService { } getAdaptersPaginated( - path: string, - startid: string | null, + startid: string | number | null, limit: number, ): Observable { return this.requestAdapterDescriptionsPaginated( @@ -79,7 +78,7 @@ export class AdapterService { requestAdapterDescriptionsPaginated( path: string, - startid: string | null, + startid: string | number | null, limit: number, ): Observable { let params = new HttpParams().set('limit', limit.toString()); diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html new file mode 100644 index 0000000000..c9134d4a7f --- /dev/null +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html @@ -0,0 +1,44 @@ + + +
+ + + + + + + + + +
+ {{ 'No entries available.' | translate }} +
+
+ +
+
diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.scss b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.scss new file mode 100644 index 0000000000..d390c087f5 --- /dev/null +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.scss @@ -0,0 +1,30 @@ +/*! + * 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. + * + */ + +.paginator-container { + border-top: 1px solid rgba(0, 0, 0, 0.12); +} + +.mat-mdc-row:hover { + background-color: var(--color-bg-1); +} + +.mat-mdc-no-data-row { + height: var(--mat-table-row-item-container-height, 52px); + text-align: center; +} diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts new file mode 100644 index 0000000000..c094f0a562 --- /dev/null +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -0,0 +1,107 @@ +/* + * 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 { + AfterViewInit, + Component, + Input, + ViewChild, + ContentChildren, + ContentChild, + QueryList, +} from '@angular/core'; +import { + MatColumnDef, + MatHeaderRowDef, + MatNoDataRow, + MatRowDef, + MatTable, + MatTableDataSource, +} from '@angular/material/table'; +import { MatPaginator } from '@angular/material/paginator'; +import { AdapterService } from '@streampipes/platform-services'; +import { AdapterDescription } from '@streampipes/platform-services'; + +@Component({ + selector: 'sp-table-pagination', + templateUrl: './sp-table-pagination.component.html', + styleUrls: ['./sp-table-pagination.component.scss'], + standalone: false, +}) +export class SpTablePaginationComponent implements AfterViewInit { + @ContentChildren(MatHeaderRowDef) headerRowDefs: QueryList; + @ContentChildren(MatRowDef) rowDefs: QueryList< + MatRowDef + >; + @ContentChildren(MatColumnDef) columnDefs: QueryList; + @ContentChild(MatNoDataRow) noDataRow: MatNoDataRow; + + @ViewChild(MatTable, { static: true }) table: MatTable; + @Input() columns: string[] = []; + + //@ViewChild('paginator') paginator: MatPaginator; + + dataSource = new MatTableDataSource([]); + pageSize = 20; + totalItems = 0; // Optional: Use if backend returns total count + + constructor(private adapterService: AdapterService) { + console.log('[SpTablePagination] Constructor'); + } + + ngOnInit() { + console.log('[SpTablePagination] ngOnInit'); + } + + ngAfterViewInit() { + console.log('INIT'); + //this.paginator.page.subscribe(() => this.loadData()); + this.loadData(); // Initial load + } + + ngAfterContentInit() { + this.columnDefs.forEach(columnDef => + this.table.addColumnDef(columnDef), + ); + this.rowDefs.forEach(rowDef => this.table.addRowDef(rowDef)); + this.headerRowDefs.forEach(headerRowDef => + this.table.addHeaderRowDef(headerRowDef), + ); + this.table.setNoDataRow(this.noDataRow); + } + loadData() { + console.log('LOAD DATA'); + //const pageSize = this.paginator.pageSize; + //const pageIndex = this.paginator.pageIndex; + + // NOTE: Replace with actual offset logic if needed (e.g., startkey) + const offset = undefined; + + this.adapterService.getAdaptersPaginated(offset, 10).subscribe({ + next: (data: AdapterDescription[]) => { + this.dataSource.data = data; + console.log(data); + // TODO: If your backend provides total item count, set it here + // this.totalItems = response.totalCount; + // this.paginator.length = this.totalItems; + }, + error: err => { + console.error('Failed to fetch paginated data', err); + }, + }); + } +} diff --git a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts index f79dba92aa..a66eb5c46f 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts @@ -98,7 +98,7 @@ import { InputSchemaPropertyComponent } from './components/input-schema-panel/in import { MatExpansionModule } from '@angular/material/expansion'; import { SortByRuntimeNamePipe } from './pipes/sort-by-runtime-name.pipe'; import { DragDropModule } from '@angular/cdk/drag-drop'; -import { SpBasicViewPaginationComponent } from './components/basic-view-pagination/basic-view-pagination.component'; +import { SpTablePaginationComponent } from './components/sp-table-pagination/sp-table-pagination.component'; @NgModule({ declarations: [ @@ -122,7 +122,6 @@ import { SpBasicViewPaginationComponent } from './components/basic-view-paginati SpBasicInnerPanelComponent, SpBasicHeaderTitleComponent, SpBasicViewComponent, - SpBasicViewPaginationComponent, SpBasicNavTabsComponent, SpExceptionMessageComponent, SpExceptionDetailsComponent, @@ -151,6 +150,7 @@ import { SpBasicViewPaginationComponent } from './components/basic-view-paginati InputSchemaPanelComponent, InputSchemaPropertyComponent, SortByRuntimeNamePipe, + SpTablePaginationComponent, ], imports: [ CommonModule, @@ -206,6 +206,7 @@ import { SpBasicViewPaginationComponent } from './components/basic-view-paginati SpExceptionDetailsDialogComponent, SpLabelComponent, SpTableComponent, + SpTablePaginationComponent, SplitSectionComponent, SpWarningBoxComponent, CustomTimeRangeSelectionComponent, diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html index 73f8efa9cd..26fd755a40 100644 --- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html +++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html @@ -97,10 +97,9 @@ title="Adapters" >
- @@ -289,7 +288,7 @@
- + 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 34cc2adb65..a85af59bb5 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 @@ -73,8 +73,8 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { 'action', ]; - dataSource: MatTableDataSource = - new MatTableDataSource(); + //dataSource: MatTableDataSource = + // new MatTableDataSource(); isAdmin = false; adapterMetrics: Record = {}; @@ -274,7 +274,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.operationInProgressAdapterId = undefined; this.getMonitoringInfos(adapters); setTimeout(() => { - this.dataSource.sort = this.sort; + // this.dataSource.sort = this.sort; }); }); } @@ -290,7 +290,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { return elementIds.has(a.elementId); } }); - this.dataSource.data = this.filteredAdapters; + //this.dataSource.data = this.filteredAdapters; } startAdapterTutorial() { @@ -305,9 +305,9 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { applyFilter(filter: AdapterFilterSettingsModel) { this.currentFilter = filter; - if (this.dataSource) { - this.applyAdapterFilters(this.currentFilterIds); - } + //if (this.dataSource) { + // this.applyAdapterFilters(this.currentFilterIds); + //} } navigateToDetailsOverviewPage(adapter: AdapterDescription): void { From 585d7a838b0ad9cc342ef77ece9066b8a1581f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 15:07:40 +0200 Subject: [PATCH 014/113] first draft working --- .../sp-table-pagination.component.html | 10 ++-- .../sp-table-pagination.component.ts | 56 +++++++++++++------ 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html index c9134d4a7f..5773548bc5 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html @@ -36,9 +36,11 @@
+ [length]="totalItems" + [pageSize]="pageSize" + [pageSizeOptions]="[5, 10, 20]" + (page)="onPageChange($event)" + > +
diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index c094f0a562..7f19f785f3 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -32,7 +32,7 @@ import { MatTable, MatTableDataSource, } from '@angular/material/table'; -import { MatPaginator } from '@angular/material/paginator'; +import { MatPaginator, PageEvent } from '@angular/material/paginator'; import { AdapterService } from '@streampipes/platform-services'; import { AdapterDescription } from '@streampipes/platform-services'; @@ -53,11 +53,16 @@ export class SpTablePaginationComponent implements AfterViewInit { @ViewChild(MatTable, { static: true }) table: MatTable; @Input() columns: string[] = []; - //@ViewChild('paginator') paginator: MatPaginator; + @ViewChild('paginator') paginator: MatPaginator; dataSource = new MatTableDataSource([]); pageSize = 20; - totalItems = 0; // Optional: Use if backend returns total count + totalItems = 1000000; // Optional: Use if backend returns total count + last_key = undefined; + currentPage = 0; + + // Keep track of keys for pagination + startKeyMap: Map = new Map(); constructor(private adapterService: AdapterService) { console.log('[SpTablePagination] Constructor'); @@ -70,7 +75,13 @@ export class SpTablePaginationComponent implements AfterViewInit { ngAfterViewInit() { console.log('INIT'); //this.paginator.page.subscribe(() => this.loadData()); - this.loadData(); // Initial load + this.loadData(0); // Initial load + } + + onPageChange(event: PageEvent) { + this.pageSize = event.pageSize; + this.currentPage = event.pageIndex; + this.loadData(this.currentPage); } ngAfterContentInit() { @@ -83,25 +94,34 @@ export class SpTablePaginationComponent implements AfterViewInit { ); this.table.setNoDataRow(this.noDataRow); } - loadData() { + loadData(pageIndex: number) { console.log('LOAD DATA'); //const pageSize = this.paginator.pageSize; //const pageIndex = this.paginator.pageIndex; // NOTE: Replace with actual offset logic if needed (e.g., startkey) - const offset = undefined; + //const offset = undefined; + const startkey = this.startKeyMap.get(pageIndex) || null; + + this.adapterService + .getAdaptersPaginated(startkey, this.pageSize + 1) + .subscribe({ + next: (data: AdapterDescription[]) => { + this.dataSource.data = data; + console.log(data); + this.last_key = data[data.length - 1].createdAt; + console.log(this.last_key); - this.adapterService.getAdaptersPaginated(offset, 10).subscribe({ - next: (data: AdapterDescription[]) => { - this.dataSource.data = data; - console.log(data); - // TODO: If your backend provides total item count, set it here - // this.totalItems = response.totalCount; - // this.paginator.length = this.totalItems; - }, - error: err => { - console.error('Failed to fetch paginated data', err); - }, - }); + if (data.length > this.pageSize) { + const nextStartKey = data[this.pageSize - 1].createdAt; + this.startKeyMap.set(pageIndex + 1, nextStartKey); + console.log(this.startKeyMap); + data = data.slice(0, this.pageSize); // Trim the extra item + } + }, + error: err => { + console.error('Failed to fetch paginated data', err); + }, + }); } } From bfdf00a7208b33a1a27298379c775f3e39e9143a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 15:19:20 +0200 Subject: [PATCH 015/113] Before Flex --- .../sp-table-pagination.component.scss | 4 ++++ .../sp-table-pagination.component.ts | 15 ++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.scss b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.scss index d390c087f5..ef1fb3c79c 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.scss +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.scss @@ -28,3 +28,7 @@ height: var(--mat-table-row-item-container-height, 52px); text-align: center; } + +::ng-deep .mat-paginator-range-label { + display: none !important; +} diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 7f19f785f3..8d84c67366 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -18,6 +18,7 @@ import { AfterViewInit, Component, + NgModule, Input, ViewChild, ContentChildren, @@ -96,24 +97,24 @@ export class SpTablePaginationComponent implements AfterViewInit { } loadData(pageIndex: number) { console.log('LOAD DATA'); - //const pageSize = this.paginator.pageSize; - //const pageIndex = this.paginator.pageIndex; - - // NOTE: Replace with actual offset logic if needed (e.g., startkey) - //const offset = undefined; const startkey = this.startKeyMap.get(pageIndex) || null; this.adapterService .getAdaptersPaginated(startkey, this.pageSize + 1) .subscribe({ next: (data: AdapterDescription[]) => { - this.dataSource.data = data; + if (data.length < this.pageSize) { + this.dataSource.data = data; + } else { + const trimmedData = data.slice(0, this.pageSize); + this.dataSource.data = trimmedData; + } console.log(data); this.last_key = data[data.length - 1].createdAt; console.log(this.last_key); if (data.length > this.pageSize) { - const nextStartKey = data[this.pageSize - 1].createdAt; + const nextStartKey = data[this.pageSize].createdAt; this.startKeyMap.set(pageIndex + 1, nextStartKey); console.log(this.startKeyMap); data = data.slice(0, this.pageSize); // Trim the extra item From 466bac546a8a9a4d580f27ae331586d8721d59db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 15:32:23 +0200 Subject: [PATCH 016/113] flexibilised everything a bit --- .../sp-table-pagination.component.ts | 64 ++++++++++--------- .../existing-adapters.component.html | 1 + .../existing-adapters.component.ts | 8 +++ 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 8d84c67366..b7eca9fff1 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -35,7 +35,7 @@ import { } from '@angular/material/table'; import { MatPaginator, PageEvent } from '@angular/material/paginator'; import { AdapterService } from '@streampipes/platform-services'; -import { AdapterDescription } from '@streampipes/platform-services'; +import { Observable } from 'rxjs'; @Component({ selector: 'sp-table-pagination', @@ -43,24 +43,28 @@ import { AdapterDescription } from '@streampipes/platform-services'; styleUrls: ['./sp-table-pagination.component.scss'], standalone: false, }) -export class SpTablePaginationComponent implements AfterViewInit { +export class SpTablePaginationComponent implements AfterViewInit { @ContentChildren(MatHeaderRowDef) headerRowDefs: QueryList; - @ContentChildren(MatRowDef) rowDefs: QueryList< - MatRowDef - >; + @ContentChildren(MatRowDef) rowDefs: QueryList>; @ContentChildren(MatColumnDef) columnDefs: QueryList; @ContentChild(MatNoDataRow) noDataRow: MatNoDataRow; - @ViewChild(MatTable, { static: true }) table: MatTable; + @ViewChild(MatTable, { static: true }) table: MatTable; @Input() columns: string[] = []; @ViewChild('paginator') paginator: MatPaginator; - dataSource = new MatTableDataSource([]); + @Input() fetchDataFn: ( + startKey?: any, + pageSize?: number, + ) => Observable; + + dataSource = new MatTableDataSource([]); pageSize = 20; totalItems = 1000000; // Optional: Use if backend returns total count last_key = undefined; currentPage = 0; + propertyName = 'createdAt'; // Keep track of keys for pagination startKeyMap: Map = new Map(); @@ -99,30 +103,28 @@ export class SpTablePaginationComponent implements AfterViewInit { console.log('LOAD DATA'); const startkey = this.startKeyMap.get(pageIndex) || null; - this.adapterService - .getAdaptersPaginated(startkey, this.pageSize + 1) - .subscribe({ - next: (data: AdapterDescription[]) => { - if (data.length < this.pageSize) { - this.dataSource.data = data; - } else { - const trimmedData = data.slice(0, this.pageSize); - this.dataSource.data = trimmedData; - } - console.log(data); - this.last_key = data[data.length - 1].createdAt; - console.log(this.last_key); + this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ + next: (data: T[]) => { + if (data.length < this.pageSize) { + this.dataSource.data = data; + } else { + const trimmedData = data.slice(0, this.pageSize); + this.dataSource.data = trimmedData; + } + console.log(data); + this.last_key = data[data.length - 1][this.propertyName]; + console.log(this.last_key); - if (data.length > this.pageSize) { - const nextStartKey = data[this.pageSize].createdAt; - this.startKeyMap.set(pageIndex + 1, nextStartKey); - console.log(this.startKeyMap); - data = data.slice(0, this.pageSize); // Trim the extra item - } - }, - error: err => { - console.error('Failed to fetch paginated data', err); - }, - }); + if (data.length > this.pageSize) { + const nextStartKey = data[this.pageSize][this.propertyName]; + this.startKeyMap.set(pageIndex + 1, nextStartKey); + console.log(this.startKeyMap); + data = data.slice(0, this.pageSize); // Trim the extra item + } + }, + error: err => { + console.error('Failed to fetch paginated data', err); + }, + }); } } diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html index 26fd755a40..1934fbe12a 100644 --- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html +++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html @@ -100,6 +100,7 @@ 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 a85af59bb5..20b3c322b1 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 @@ -26,6 +26,7 @@ import { SpMetricsEntry, } from '@streampipes/platform-services'; import { MatTableDataSource } from '@angular/material/table'; +import { Observable } from 'rxjs'; import { CurrentUserService, DialogRef, @@ -318,4 +319,11 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.userSubscription?.unsubscribe(); this.tutorialActiveSubscription?.unsubscribe(); } + + fetchAdapters = ( + startKey?: number, + pageSize?: number, + ): Observable => { + return this.adapterService.getAdaptersPaginated(startKey, pageSize); + }; } From 0ff2a49543093ca289a18a02da705b9f9ac713b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 15:52:58 +0200 Subject: [PATCH 017/113] overwrite paginator --- .../custom-paginator-intl.ts | 13 +++ .../sp-table-pagination.module.ts | 83 +++++++++++++++++++ .../shared-ui/src/lib/shared-ui.module.ts | 5 +- 3 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts create mode 100644 ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.module.ts diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts new file mode 100644 index 0000000000..4c5179d65e --- /dev/null +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts @@ -0,0 +1,13 @@ +import { MatPaginatorIntl } from '@angular/material/paginator'; + +export function getCustomPaginatorIntl(): MatPaginatorIntl { + const paginatorIntl = new MatPaginatorIntl(); + + paginatorIntl.itemsPerPageLabel = 'Items per page:'; + paginatorIntl.nextPageLabel = 'Next'; + paginatorIntl.previousPageLabel = 'Previous'; + + paginatorIntl.getRangeLabel = () => ''; + + return paginatorIntl; +} diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.module.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.module.ts new file mode 100644 index 0000000000..8234e8d3b2 --- /dev/null +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.module.ts @@ -0,0 +1,83 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SpTablePaginationComponent } from './sp-table-pagination.component'; +import { + MatPaginatorIntl, + MatPaginatorModule, +} from '@angular/material/paginator'; +import { getCustomPaginatorIntl } from './custom-paginator-intl'; + +// Angular Material modules +import { MatTableModule } from '@angular/material/table'; +import { MatSortModule } from '@angular/material/sort'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatIconModule } from '@angular/material/icon'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatButtonModule } from '@angular/material/button'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatSelectModule } from '@angular/material/select'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatTreeModule } from '@angular/material/tree'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatStepperModule } from '@angular/material/stepper'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; + +import { FlexLayoutModule } from '@ngbracket/ngx-layout'; +import { FormsModule } from '@angular/forms'; +import { PortalModule } from '@angular/cdk/portal'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { DragDropModule } from '@angular/cdk/drag-drop'; + +import { TranslateModule } from '@ngx-translate/core'; +import { MarkdownModule } from 'ngx-markdown'; + +@NgModule({ + declarations: [SpTablePaginationComponent], + imports: [ + CommonModule, + FormsModule, + FlexLayoutModule, + + // Angular Material modules + MatTableModule, + MatPaginatorModule, + MatSortModule, + MatDividerModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatIconModule, + MatCheckboxModule, + MatButtonModule, + MatTabsModule, + MatMenuModule, + MatSelectModule, + MatDatepickerModule, + MatTooltipModule, + MatTreeModule, + MatExpansionModule, + MatStepperModule, + MatRadioModule, + MatProgressSpinnerModule, + + // CDK and other modules + PortalModule, + OverlayModule, + DragDropModule, + + // i18n and markdown + TranslateModule.forChild({}), + MarkdownModule.forRoot(), + ], + providers: [ + { provide: MatPaginatorIntl, useFactory: getCustomPaginatorIntl }, + ], + exports: [SpTablePaginationComponent], +}) +export class SpTablePaginationModule {} diff --git a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts index a66eb5c46f..5817908879 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts @@ -98,7 +98,7 @@ import { InputSchemaPropertyComponent } from './components/input-schema-panel/in import { MatExpansionModule } from '@angular/material/expansion'; import { SortByRuntimeNamePipe } from './pipes/sort-by-runtime-name.pipe'; import { DragDropModule } from '@angular/cdk/drag-drop'; -import { SpTablePaginationComponent } from './components/sp-table-pagination/sp-table-pagination.component'; +import { SpTablePaginationModule } from './components/sp-table-pagination/sp-table-pagination.module'; @NgModule({ declarations: [ @@ -150,7 +150,6 @@ import { SpTablePaginationComponent } from './components/sp-table-pagination/sp- InputSchemaPanelComponent, InputSchemaPropertyComponent, SortByRuntimeNamePipe, - SpTablePaginationComponent, ], imports: [ CommonModule, @@ -206,7 +205,6 @@ import { SpTablePaginationComponent } from './components/sp-table-pagination/sp- SpExceptionDetailsDialogComponent, SpLabelComponent, SpTableComponent, - SpTablePaginationComponent, SplitSectionComponent, SpWarningBoxComponent, CustomTimeRangeSelectionComponent, @@ -219,6 +217,7 @@ import { SpTablePaginationComponent } from './components/sp-table-pagination/sp- PipelineElementComponent, InputSchemaPanelComponent, SidebarResizeComponent, + SpTablePaginationModule, ], }) export class SharedUiModule {} From 8c81b5c355de9cfe693af6e21f0d07cf81e1e2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 16:32:18 +0200 Subject: [PATCH 018/113] First draft for flexible view in pagination --- .../management/AdapterMasterManagement.java | 4 +-- .../rest/impl/connect/AdapterResource.java | 9 ++++-- .../storage/api/IAdapterStorage.java | 2 +- .../impl/AdapterDescriptionStorageImpl.java | 2 +- .../impl/AdapterInstanceStorageImpl.java | 32 +++++++++++-------- 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java index 128df0fce8..78407f1db2 100644 --- a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java +++ b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java @@ -145,8 +145,8 @@ public List getAllAdapterInstances() { return adapterInstanceStorage.findAll(); } - public List getPaginatedAdapterInstances(String startkey, int limit){ - return adapterInstanceStorage.getAdapterPaginator(startkey, limit); + public List getPaginatedAdapterInstances(String startkey, int limit, String view, boolean descending){ + return adapterInstanceStorage.getAdapterPaginator(startkey, limit, view,descending); } //public List getPagedAdapterInstances(String startKey, int limit) { diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java index c71bda6191..3cc0883b8a 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java @@ -305,10 +305,13 @@ public List getAllAdapters() { @PostFilter("hasPermission(filterObject.correspondingDataStreamElementId, 'READ')") public List getAllAdaptersPaginated( @RequestParam(required = false) String startkey, - @RequestParam(defaultValue = "10") int limit) { + @RequestParam(defaultValue = "10") int limit, + @RequestParam(defaultValue = "createdAt") String view, + @RequestParam(defaultValue = "false") boolean descending + ) { - LOG.info("GET Paginated ADAPTERS: startkey={}, limit={}", startkey, limit); - return managementService.getPaginatedAdapterInstances(startkey, limit); + LOG.info("GET Paginated ADAPTERS: startkey={}, limit={} view={} descending={}", startkey, limit, view, descending); + return managementService.getPaginatedAdapterInstances(startkey, limit, view,descending); } private AdapterDescription getAdapterDescription(String elementId) throws AdapterException { diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java index f170125b32..d6b063b7ba 100644 --- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java +++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java @@ -28,5 +28,5 @@ public interface IAdapterStorage extends CRUDStorage { List getAdaptersByAppId(String appId); - List getAdapterPaginator(String startitem, int limit); + List getAdapterPaginator(String startitem, int limit, String view, boolean descending); } diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java index d3ebcb984a..28a2329f0c 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java @@ -61,7 +61,7 @@ private String getCurrentRev(String elementId) { } @Override - public List getAdapterPaginator(String startitem, int limit) { + public List getAdapterPaginator(String startitem, int limit, String view, boolean descending) { // TODO Auto-generated method stub throw new UnsupportedOperationException("Unimplemented method 'getAdapterPaginator'"); } diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index c4bc2737d0..2b2401fbf5 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -21,10 +21,10 @@ import org.apache.streampipes.model.connect.adapter.AdapterDescription; import org.apache.streampipes.storage.api.IAdapterStorage; import org.apache.streampipes.storage.couchdb.utils.Utils; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; @@ -62,28 +62,32 @@ public List findAll() { } @Override - public List getAdapterPaginator(String startItem, int limit) { + public List getAdapterPaginator(String startItem, int limit, String view, boolean descending) { long startItemLong = 0L; // default value - try { - startItemLong = Long.parseLong(startItem); + String uri = "paginator/by_" + view; + + if ("createdAt".equals(view)) { + try { + startItemLong = Long.parseLong(startItem); - } catch (Exception e) { - return couchDbClientSupplier - .get() - .view("paginator/by_createdAt") - .includeDocs(true) - .limit(limit) - .descending(false) - .query(AdapterDescription.class); + } catch (NumberFormatException e) { + return couchDbClientSupplier + .get() + .view(uri) + .includeDocs(true) + .limit(limit) + .descending(descending) + .query(AdapterDescription.class); + } } return couchDbClientSupplier .get() - .view("paginator/by_createdAt") + .view(uri) .includeDocs(true) .limit(limit) .startKey(startItemLong) - .descending(false) + .descending(descending) .query(AdapterDescription.class); } } From f5113e8ba3bf747a7431ace9896ffa07064a10c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 15 Sep 2025 16:40:20 +0200 Subject: [PATCH 019/113] added lisence --- .../custom-paginator-intl.ts | 17 +++++++++++++++++ .../sp-table-pagination.module.ts | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts index 4c5179d65e..2a23c83e7e 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts @@ -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. + * + */ import { MatPaginatorIntl } from '@angular/material/paginator'; export function getCustomPaginatorIntl(): MatPaginatorIntl { diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.module.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.module.ts index 8234e8d3b2..7a20e2aa6d 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.module.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.module.ts @@ -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. + * + */ + import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SpTablePaginationComponent } from './sp-table-pagination.component'; From 7c6e070c969ab77a8b13936904b87f45f578e9ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 09:52:51 +0200 Subject: [PATCH 020/113] first draft for multiple sort options --- .../src/lib/apis/adapter.service.ts | 11 ++++++++ .../sp-table-pagination.component.ts | 25 +++++++++++++++++ .../existing-adapters.component.html | 4 ++- .../existing-adapters.component.ts | 28 +++++++++++++++---- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index e4f0796db0..db05ca9cca 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -28,6 +28,8 @@ import { Message, PipelineUpdateInfo, } from '../model/gen/streampipes-model'; +import { property } from 'cypress/types/lodash'; +import { descending } from 'd3-array'; @Injectable({ providedIn: 'root' }) export class AdapterService { @@ -51,11 +53,15 @@ export class AdapterService { getAdaptersPaginated( startid: string | number | null, limit: number, + property: string = 'createdAt', + descending: boolean = false, ): Observable { return this.requestAdapterDescriptionsPaginated( '/master/adapters/paginator', startid, limit, + property, + descending, ); } @@ -80,6 +86,8 @@ export class AdapterService { path: string, startid: string | number | null, limit: number, + property: string, + descending: boolean, ): Observable { let params = new HttpParams().set('limit', limit.toString()); @@ -87,6 +95,9 @@ export class AdapterService { params = params.set('startkey', startid); } + params = params.set('view', property); + params = params.set('descending', descending); + console.log('params', params); const url = `${this.connectPath}${path}`; return this.http.get(url, { params }).pipe( diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index b7eca9fff1..ca4f27d0dc 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -36,6 +36,7 @@ import { import { MatPaginator, PageEvent } from '@angular/material/paginator'; import { AdapterService } from '@streampipes/platform-services'; import { Observable } from 'rxjs'; +import { MatSort, MatSortHeader } from '@angular/material/sort'; @Component({ selector: 'sp-table-pagination', @@ -50,6 +51,10 @@ export class SpTablePaginationComponent implements AfterViewInit { @ContentChild(MatNoDataRow) noDataRow: MatNoDataRow; @ViewChild(MatTable, { static: true }) table: MatTable; + @ContentChild(MatSort) sort: MatSort; + + @ContentChild(MatSortHeader) sort2: MatSortHeader; + @Input() columns: string[] = []; @ViewChild('paginator') paginator: MatPaginator; @@ -80,6 +85,23 @@ export class SpTablePaginationComponent implements AfterViewInit { ngAfterViewInit() { console.log('INIT'); //this.paginator.page.subscribe(() => this.loadData()); + //this.loadData(0); // Initial load + //console.log('AFTER DATA LOAD') + if (this.sort) { + this.sort.sortChange.subscribe(sortEvent => { + console.log('Sort changed:', sortEvent); + + // Set the property name based on the active column + this.propertyName = sortEvent.active; + + // Optionally: Handle direction if your backend supports it + // You might want to use this.sort.direction somewhere too + + // Reload data when sorting changes + this.loadData(0); + }); + } + this.loadData(0); // Initial load } @@ -98,6 +120,9 @@ export class SpTablePaginationComponent implements AfterViewInit { this.table.addHeaderRowDef(headerRowDef), ); this.table.setNoDataRow(this.noDataRow); + + console.log('Sort received:', this.sort); + console.log('Sort received:', this.sort2); } loadData(pageIndex: number) { console.log('LOAD DATA'); diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html index 1934fbe12a..b99bc6705b 100644 --- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html +++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html @@ -191,7 +191,9 @@ - Created + + Created +
{{ 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 20b3c322b1..d4e14ed320 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 @@ -25,7 +25,7 @@ import { SpLogMessage, SpMetricsEntry, } from '@streampipes/platform-services'; -import { MatTableDataSource } from '@angular/material/table'; +import { MatSortHeader } from '@angular/material/sort'; import { Observable } from 'rxjs'; import { CurrentUserService, @@ -63,6 +63,8 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { @ViewChild(MatSort) sort: MatSort; + //@ViewChild('sortHeaderName') sortHeaderName: MatSortHeader; + displayedColumns: string[] = [ 'status', 'start', @@ -306,9 +308,9 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { applyFilter(filter: AdapterFilterSettingsModel) { this.currentFilter = filter; - //if (this.dataSource) { - // this.applyAdapterFilters(this.currentFilterIds); - //} + // if (this.dataSource) { + // this.applyAdapterFilters(this.currentFilterIds); + // } } navigateToDetailsOverviewPage(adapter: AdapterDescription): void { @@ -324,6 +326,22 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { startKey?: number, pageSize?: number, ): Observable => { - return this.adapterService.getAdaptersPaginated(startKey, pageSize); + console.log('FROM FETCH ADAPTER', this.sort); + console.log('FROM FETCH ADAPTER', this.sort?.active); + console.log('FROM FETCH ADAPTER', this.sort?.direction); + console.log(this.sort?.direction == 'desc'); + let view = 'createdAt'; + if (this.sort?.active == 'lastModified') { + view = 'createdAt'; + } else { + view = this.sort?.active; + } + + return this.adapterService.getAdaptersPaginated( + startKey, + pageSize, + view, + this.sort?.direction == 'desc', + ); }; } From c937843b6034ed64a50c0039504e5c0c2272d4e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 10:34:00 +0200 Subject: [PATCH 021/113] seems to be working --- .../sp-table-pagination.component.ts | 53 ++++++++++--------- .../streampipes/shared-ui/src/public-api.ts | 2 + .../existing-adapters.component.html | 1 + .../existing-adapters.component.ts | 8 +++ 4 files changed, 40 insertions(+), 24 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index ca4f27d0dc..55deaebdc6 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -24,6 +24,7 @@ import { ContentChildren, ContentChild, QueryList, + SimpleChanges, } from '@angular/core'; import { MatColumnDef, @@ -36,7 +37,7 @@ import { import { MatPaginator, PageEvent } from '@angular/material/paginator'; import { AdapterService } from '@streampipes/platform-services'; import { Observable } from 'rxjs'; -import { MatSort, MatSortHeader } from '@angular/material/sort'; +import { MatSort, Sort } from '@angular/material/sort'; @Component({ selector: 'sp-table-pagination', @@ -51,14 +52,12 @@ export class SpTablePaginationComponent implements AfterViewInit { @ContentChild(MatNoDataRow) noDataRow: MatNoDataRow; @ViewChild(MatTable, { static: true }) table: MatTable; - @ContentChild(MatSort) sort: MatSort; - - @ContentChild(MatSortHeader) sort2: MatSortHeader; @Input() columns: string[] = []; @ViewChild('paginator') paginator: MatPaginator; - + //@ViewChild(MatSort) sort: MatSort; + @Input() sort: MatSort; @Input() fetchDataFn: ( startKey?: any, pageSize?: number, @@ -74,6 +73,19 @@ export class SpTablePaginationComponent implements AfterViewInit { // Keep track of keys for pagination startKeyMap: Map = new Map(); + private sortInitialized = false; + + ngOnChanges(changes: SimpleChanges): void { + if (changes['sort'] && this.sort && !this.sortInitialized) { + this.sort.sortChange.subscribe((sortChange: Sort) => { + console.log('[Sort Changed]', sortChange); + this.resetPagination(); + this.loadData(0); + }); + this.sortInitialized = true; + } + } + constructor(private adapterService: AdapterService) { console.log('[SpTablePagination] Constructor'); } @@ -84,27 +96,23 @@ export class SpTablePaginationComponent implements AfterViewInit { ngAfterViewInit() { console.log('INIT'); - //this.paginator.page.subscribe(() => this.loadData()); - //this.loadData(0); // Initial load - //console.log('AFTER DATA LOAD') - if (this.sort) { - this.sort.sortChange.subscribe(sortEvent => { - console.log('Sort changed:', sortEvent); - // Set the property name based on the active column - this.propertyName = sortEvent.active; - - // Optionally: Handle direction if your backend supports it - // You might want to use this.sort.direction somewhere too - - // Reload data when sorting changes + this.loadData(0); // Initial load + console.log('Sorting', this.sort); + if (this.sort) { + this.sort.sortChange.subscribe((sortChange: Sort) => { + console.log('[Sort Changed]', sortChange); + this.resetPagination(); this.loadData(0); }); } - - this.loadData(0); // Initial load } - + resetPagination() { + this.startKeyMap.clear(); + this.currentPage = 0; + this.last_key = null; + this.paginator.firstPage(); + } onPageChange(event: PageEvent) { this.pageSize = event.pageSize; this.currentPage = event.pageIndex; @@ -120,9 +128,6 @@ export class SpTablePaginationComponent implements AfterViewInit { this.table.addHeaderRowDef(headerRowDef), ); this.table.setNoDataRow(this.noDataRow); - - console.log('Sort received:', this.sort); - console.log('Sort received:', this.sort2); } loadData(pageIndex: number) { console.log('LOAD DATA'); diff --git a/ui/projects/streampipes/shared-ui/src/public-api.ts b/ui/projects/streampipes/shared-ui/src/public-api.ts index ae6cdd29c1..afcc2780cb 100644 --- a/ui/projects/streampipes/shared-ui/src/public-api.ts +++ b/ui/projects/streampipes/shared-ui/src/public-api.ts @@ -53,6 +53,8 @@ export * from './lib/components/pipeline-element-documentation/pipeline-element- export * from './lib/components/pipeline-element/pipeline-element.component'; export * from './lib/components/input-schema-panel/input-schema-panel.component'; export * from './lib/components/sidebar-resize/sidebar-resize.component'; +export * from './lib/components/sp-table-pagination/sp-table-pagination.module'; +export * from './lib/components/sp-table-pagination/sp-table-pagination.component'; export * from './lib/models/sp-navigation.model'; diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html index b99bc6705b..0489eb012d 100644 --- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html +++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html @@ -102,6 +102,7 @@ [columns]="displayedColumns" [fetchDataFn]="fetchAdapters" data-cy="all-adapters-table" + [sort]="sort" matSort > 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 d4e14ed320..169c5ee4fb 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 @@ -103,6 +103,14 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { + if (this.sort) { + this.sort.sort({ + id: 'lastModified', + start: 'desc', + disableClear: false, + }); // default sort + } + this.breadcrumbService.updateBreadcrumb( this.breadcrumbService.getRootLink(SpConnectRoutes.BASE), ); From d2727bfe6ef677861e052c2674964f9930a1edb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 11:18:59 +0200 Subject: [PATCH 022/113] fixed the numbering --- .../sp-table-pagination/custom-paginator-intl.ts | 10 +++++++++- .../sp-table-pagination.component.html | 2 +- .../sp-table-pagination.component.ts | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts index 2a23c83e7e..47f0eae791 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts @@ -24,7 +24,15 @@ export function getCustomPaginatorIntl(): MatPaginatorIntl { paginatorIntl.nextPageLabel = 'Next'; paginatorIntl.previousPageLabel = 'Previous'; - paginatorIntl.getRangeLabel = () => ''; + paginatorIntl.getRangeLabel = ( + page: number, + pageSize: number, + length: number, + ) => { + const start = page * pageSize + 1; + const end = Math.min((page + 1) * pageSize, length); + return `Showing documents ${start} - ${end}`; + }; return paginatorIntl; } diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html index 5773548bc5..5cae91d411 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html @@ -38,7 +38,7 @@ #paginator [length]="totalItems" [pageSize]="pageSize" - [pageSizeOptions]="[5, 10, 20]" + [pageSizeOptions]="[5, 10, 20, 50]" (page)="onPageChange($event)" > diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 55deaebdc6..dd5cd51291 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -69,6 +69,7 @@ export class SpTablePaginationComponent implements AfterViewInit { last_key = undefined; currentPage = 0; propertyName = 'createdAt'; + isNextDisabled: boolean = false; // Keep track of keys for pagination startKeyMap: Map = new Map(); @@ -137,9 +138,12 @@ export class SpTablePaginationComponent implements AfterViewInit { next: (data: T[]) => { if (data.length < this.pageSize) { this.dataSource.data = data; + //this.isNextDisabled=true; + this.totalItems = data.length + pageIndex * this.pageSize; } else { const trimmedData = data.slice(0, this.pageSize); this.dataSource.data = trimmedData; + this.totalItems = data.length + pageIndex * this.pageSize; } console.log(data); this.last_key = data[data.length - 1][this.propertyName]; From 6a18d447961f69030e1a3a6719cbe76601dfe4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 12:29:53 +0200 Subject: [PATCH 023/113] running --- .../streampipes/manager/setup/CouchDbInstallationStep.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index 4335312d23..64a4476661 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -155,9 +155,7 @@ private void addPaginatorView() { MapReduce paginationFunctionByRunning = new MapReduce(); paginationFunctionByRunning.setMap( "function (doc) {\n" - + " if (doc.properties && doc.properties.running) {\n" - + " emit(doc.properties.running, doc);\n" - + " }\n" + + " emit(doc.properties.running ? 1 : 0, doc);\n" + "}" ); From 4973153f4a557c28cb3d78fe25e0da10cf0f3ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 13:20:47 +0200 Subject: [PATCH 024/113] fix for property --- .../sp-table-pagination/custom-paginator-intl.ts | 2 +- .../sp-table-pagination.component.ts | 13 ++++++++++++- .../existing-adapters.component.ts | 9 ++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts index 47f0eae791..16d5e48725 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/custom-paginator-intl.ts @@ -30,7 +30,7 @@ export function getCustomPaginatorIntl(): MatPaginatorIntl { length: number, ) => { const start = page * pageSize + 1; - const end = Math.min((page + 1) * pageSize, length); + const end = Math.min((page + 1) * pageSize); return `Showing documents ${start} - ${end}`; }; diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index dd5cd51291..ddd574351a 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -80,6 +80,7 @@ export class SpTablePaginationComponent implements AfterViewInit { if (changes['sort'] && this.sort && !this.sortInitialized) { this.sort.sortChange.subscribe((sortChange: Sort) => { console.log('[Sort Changed]', sortChange); + this.propertyName = sortChange.active; this.resetPagination(); this.loadData(0); }); @@ -103,16 +104,23 @@ export class SpTablePaginationComponent implements AfterViewInit { if (this.sort) { this.sort.sortChange.subscribe((sortChange: Sort) => { console.log('[Sort Changed]', sortChange); + this.propertyName = sortChange.active; + console.log('[Sort Change ]Property Name', this.propertyName); this.resetPagination(); this.loadData(0); }); } } resetPagination() { + console.log('RESET Pagination'); this.startKeyMap.clear(); + console.log(this.startKeyMap); this.currentPage = 0; this.last_key = null; - this.paginator.firstPage(); + //this.paginator.firstPage(); + this.loadData(this.currentPage); + this.isNextDisabled = false; + this.totalItems = 1000000; } onPageChange(event: PageEvent) { this.pageSize = event.pageSize; @@ -133,9 +141,12 @@ export class SpTablePaginationComponent implements AfterViewInit { loadData(pageIndex: number) { console.log('LOAD DATA'); const startkey = this.startKeyMap.get(pageIndex) || null; + console.log(pageIndex); + console.log(startkey); this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ next: (data: T[]) => { + console.log('PROPERTY KEY', this.propertyName); if (data.length < this.pageSize) { this.dataSource.data = data; //this.isNextDisabled=true; 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 169c5ee4fb..ec32eb5795 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 @@ -342,14 +342,17 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { if (this.sort?.active == 'lastModified') { view = 'createdAt'; } else { - view = this.sort?.active; + if (this.sort?.active == 'status') { + view = 'running'; + } else { + view = this.sort?.active; + } } - return this.adapterService.getAdaptersPaginated( startKey, pageSize, view, - this.sort?.direction == 'desc', + this.sort?.direction != 'asc', ); }; } From 611140e3dfb5350da98a3beaf39f1d86048c9051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 13:59:37 +0200 Subject: [PATCH 025/113] small fix in backend --- .../impl/AdapterInstanceStorageImpl.java | 16 ++++++++++++- .../sp-table-pagination.component.ts | 24 ++++++------------- .../existing-adapters.component.html | 1 + .../existing-adapters.component.ts | 10 ++++++++ 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 2b2401fbf5..7eae884941 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -66,11 +66,25 @@ public List getAdapterPaginator(String startItem, int limit, long startItemLong = 0L; // default value String uri = "paginator/by_" + view; + LOG.info(uri); + if ("createdAt".equals(view)) { try { + LOG.info("PARSE LONG"); startItemLong = Long.parseLong(startItem); + return couchDbClientSupplier + .get() + .view(uri) + .includeDocs(true) + .limit(limit) + .startKey(startItemLong) + .descending(descending) + .query(AdapterDescription.class); + + } catch (NumberFormatException e) { + LOG.info("Number format"); return couchDbClientSupplier .get() .view(uri) @@ -86,7 +100,7 @@ public List getAdapterPaginator(String startItem, int limit, .view(uri) .includeDocs(true) .limit(limit) - .startKey(startItemLong) + .startKey(startItem) .descending(descending) .query(AdapterDescription.class); } diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index ddd574351a..40382df18b 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -63,6 +63,8 @@ export class SpTablePaginationComponent implements AfterViewInit { pageSize?: number, ) => Observable; + @Input() getViewFn: (sort: string) => string; + dataSource = new MatTableDataSource([]); pageSize = 20; totalItems = 1000000; // Optional: Use if backend returns total count @@ -80,9 +82,9 @@ export class SpTablePaginationComponent implements AfterViewInit { if (changes['sort'] && this.sort && !this.sortInitialized) { this.sort.sortChange.subscribe((sortChange: Sort) => { console.log('[Sort Changed]', sortChange); - this.propertyName = sortChange.active; + this.propertyName = this.getViewFn(sortChange.active); this.resetPagination(); - this.loadData(0); + //this.loadData(0); }); this.sortInitialized = true; } @@ -98,18 +100,7 @@ export class SpTablePaginationComponent implements AfterViewInit { ngAfterViewInit() { console.log('INIT'); - this.loadData(0); // Initial load - console.log('Sorting', this.sort); - if (this.sort) { - this.sort.sortChange.subscribe((sortChange: Sort) => { - console.log('[Sort Changed]', sortChange); - this.propertyName = sortChange.active; - console.log('[Sort Change ]Property Name', this.propertyName); - this.resetPagination(); - this.loadData(0); - }); - } } resetPagination() { console.log('RESET Pagination'); @@ -117,7 +108,7 @@ export class SpTablePaginationComponent implements AfterViewInit { console.log(this.startKeyMap); this.currentPage = 0; this.last_key = null; - //this.paginator.firstPage(); + this.paginator.firstPage(); this.loadData(this.currentPage); this.isNextDisabled = false; this.totalItems = 1000000; @@ -141,15 +132,14 @@ export class SpTablePaginationComponent implements AfterViewInit { loadData(pageIndex: number) { console.log('LOAD DATA'); const startkey = this.startKeyMap.get(pageIndex) || null; - console.log(pageIndex); - console.log(startkey); + console.log('PageIndex', pageIndex); + console.log('StartKey', startkey); this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ next: (data: T[]) => { console.log('PROPERTY KEY', this.propertyName); if (data.length < this.pageSize) { this.dataSource.data = data; - //this.isNextDisabled=true; this.totalItems = data.length + pageIndex * this.pageSize; } else { const trimmedData = data.slice(0, this.pageSize); diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html index 0489eb012d..2be1320a3e 100644 --- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html +++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html @@ -101,6 +101,7 @@ fxFlex="100" [columns]="displayedColumns" [fetchDataFn]="fetchAdapters" + [getViewFn]="getViewForSort" data-cy="all-adapters-table" [sort]="sort" matSort 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 ec32eb5795..65faa15f78 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 @@ -330,6 +330,16 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.tutorialActiveSubscription?.unsubscribe(); } + getViewForSort(sortActive: string | undefined): string { + const sortMap: { [key: string]: string } = { + lastModified: 'createdAt', + status: 'running', + }; + + // If the sortActive key exists in the map, return its value, otherwise return the original value. + return sortMap[sortActive ?? ''] || sortActive || ''; + } + fetchAdapters = ( startKey?: number, pageSize?: number, From d1c2e50bfdfb2a12d75cb5f64dc7986fe1aedc46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 15:21:17 +0200 Subject: [PATCH 026/113] error --- .../manager/setup/CouchDbInstallationStep.java | 2 +- .../couchdb/impl/AdapterInstanceStorageImpl.java | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index 64a4476661..e6e3a19b0a 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -145,7 +145,7 @@ private void addPaginatorView() { MapReduce paginationFunctionByName = new MapReduce(); paginationFunctionByName.setMap( "function (doc) {\n" - + " if (doc.properties && doc.properties.name) {\n" + + " if (doc.properties && doc.properties.name && typeof doc.properties.name === 'string') {\n" + " emit(doc.properties.name, doc);\n" + " }\n" + "}" diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 7eae884941..3b7433480f 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -67,6 +67,8 @@ public List getAdapterPaginator(String startItem, int limit, String uri = "paginator/by_" + view; LOG.info(uri); + LOG.info(startItem); + LOG.info("Is active: {}", descending); if ("createdAt".equals(view)) { try { @@ -95,13 +97,20 @@ public List getAdapterPaginator(String startItem, int limit, } } - return couchDbClientSupplier + LOG.info("Default return"); + + var request = couchDbClientSupplier .get() .view(uri) .includeDocs(true) .limit(limit) .startKey(startItem) - .descending(descending) - .query(AdapterDescription.class); + .descending(true); + + LOG.info(request.toString()); + //.query(AdapterDescription.class); + + + return request.query(AdapterDescription.class); } } From 7129022b531ce2c8d3308a33a3de73e4a7894ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 16:05:27 +0200 Subject: [PATCH 027/113] first part in backendquery fixed --- .../impl/AdapterInstanceStorageImpl.java | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 3b7433480f..cb89743c52 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -70,8 +70,21 @@ public List getAdapterPaginator(String startItem, int limit, LOG.info(startItem); LOG.info("Is active: {}", descending); + if (startItem == null){ + + return couchDbClientSupplier + .get() + .view(uri) + .includeDocs(true) + .limit(limit) + .descending(descending) + .query(AdapterDescription.class); + + } + + if ("createdAt".equals(view)) { - try { + LOG.info("PARSE LONG"); startItemLong = Long.parseLong(startItem); @@ -83,34 +96,16 @@ public List getAdapterPaginator(String startItem, int limit, .startKey(startItemLong) .descending(descending) .query(AdapterDescription.class); - - - } catch (NumberFormatException e) { - LOG.info("Number format"); - return couchDbClientSupplier - .get() - .view(uri) - .includeDocs(true) - .limit(limit) - .descending(descending) - .query(AdapterDescription.class); - } - } + LOG.info("Default return"); - var request = couchDbClientSupplier + return couchDbClientSupplier .get() .view(uri) .includeDocs(true) .limit(limit) .startKey(startItem) - .descending(true); - - LOG.info(request.toString()); - //.query(AdapterDescription.class); - - - return request.query(AdapterDescription.class); + .descending(descending).query(AdapterDescription.class); } } From d975683e88bd2ec1497379fa3008d26daef8ebd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 16:18:37 +0200 Subject: [PATCH 028/113] reverted signals --- .../basic-view/basic-view.component.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view/basic-view.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view/basic-view.component.ts index a44f805a52..fb5ffcf2b1 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/basic-view/basic-view.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/basic-view/basic-view.component.ts @@ -16,7 +16,7 @@ * */ -import { Component, input } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; @Component({ @@ -26,17 +26,21 @@ import { Router } from '@angular/router'; standalone: false, }) export class SpBasicViewComponent { - padding = input(false); + @Input() + padding = false; - showBackLink = input(false); + @Input() + showBackLink = false; - backLinkTarget = input(); + @Input() + backLinkTarget: string[]; - hideNavbar = input(false); + @Input() + hideNavbar = false; constructor(private router: Router) {} navigateBack() { - this.router.navigate(this.backLinkTarget()); + this.router.navigate(this.backLinkTarget); } } From 6a871368d5ee66a933871eab780bd6319a6f1114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 17:09:40 +0200 Subject: [PATCH 029/113] First working draft --- .../setup/CouchDbInstallationStep.java | 2 +- .../impl/AdapterInstanceStorageImpl.java | 61 +++++++++++++------ .../sp-table-pagination.component.ts | 31 +++++++++- .../existing-adapters.component.ts | 7 +-- 4 files changed, 73 insertions(+), 28 deletions(-) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index e6e3a19b0a..f92df0acf4 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -155,7 +155,7 @@ private void addPaginatorView() { MapReduce paginationFunctionByRunning = new MapReduce(); paginationFunctionByRunning.setMap( "function (doc) {\n" - + " emit(doc.properties.running ? 1 : 0, doc);\n" + + " emit([doc.properties.running ? 1 : 0, doc._id], doc);\n" + "}" ); diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index cb89743c52..903c7cfc37 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -22,6 +22,8 @@ import org.apache.streampipes.storage.api.IAdapterStorage; import org.apache.streampipes.storage.couchdb.utils.Utils; +import com.fasterxml.jackson.databind.ObjectMapper; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,35 +72,54 @@ public List getAdapterPaginator(String startItem, int limit, LOG.info(startItem); LOG.info("Is active: {}", descending); - if (startItem == null){ + if (startItem == null) { + + return couchDbClientSupplier + .get() + .view(uri) + .includeDocs(true) + .limit(limit) + .descending(descending) + .query(AdapterDescription.class); + + } + + if ("createdAt".equals(view)) { + + LOG.info("PARSE LONG"); + startItemLong = Long.parseLong(startItem); + + return couchDbClientSupplier + .get() + .view(uri) + .includeDocs(true) + .limit(limit) + .startKey(startItemLong) + .descending(descending) + .query(AdapterDescription.class); + } + + if (startItem.startsWith("[") && startItem.endsWith("]")) { + try { + // Assuming the startItem is a JSON array in string form, we will parse it + ObjectMapper objectMapper = new ObjectMapper(); + Object[] startKeyArray = objectMapper.readValue(startItem, Object[].class); - return couchDbClientSupplier + return couchDbClientSupplier .get() .view(uri) .includeDocs(true) .limit(limit) + .startKey(startKeyArray) .descending(descending) .query(AdapterDescription.class); - + } catch (Exception e) { + LOG.error("Failed to parse startItem as JSON array", e); + throw new IllegalArgumentException("Invalid startItem format for compound key"); } - + } - if ("createdAt".equals(view)) { - - LOG.info("PARSE LONG"); - startItemLong = Long.parseLong(startItem); - - return couchDbClientSupplier - .get() - .view(uri) - .includeDocs(true) - .limit(limit) - .startKey(startItemLong) - .descending(descending) - .query(AdapterDescription.class); - } - - LOG.info("Default return"); + LOG.info("Default return"); return couchDbClientSupplier .get() diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 40382df18b..6299f8a0ac 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -138,6 +138,8 @@ export class SpTablePaginationComponent implements AfterViewInit { this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ next: (data: T[]) => { console.log('PROPERTY KEY', this.propertyName); + + // Handle pagination logic based on the page size if (data.length < this.pageSize) { this.dataSource.data = data; this.totalItems = data.length + pageIndex * this.pageSize; @@ -146,15 +148,38 @@ export class SpTablePaginationComponent implements AfterViewInit { this.dataSource.data = trimmedData; this.totalItems = data.length + pageIndex * this.pageSize; } + console.log(data); + // Get the last key for the current page this.last_key = data[data.length - 1][this.propertyName]; console.log(this.last_key); if (data.length > this.pageSize) { - const nextStartKey = data[this.pageSize][this.propertyName]; - this.startKeyMap.set(pageIndex + 1, nextStartKey); + // Build the next start key for pagination + let nextStartKey; + + // If propertyName is an array, handle as a composite key + if (Array.isArray(this.propertyName)) { + nextStartKey = this.propertyName.map( + prop => data[this.pageSize][prop], + ); + } else { + nextStartKey = data[this.pageSize][this.propertyName]; + } + + // Convert the next start key to a string (if it's an array, stringify it) + const nextStartKeyString = Array.isArray(nextStartKey) + ? JSON.stringify(nextStartKey) + : nextStartKey; + + console.log('NEXT KEY AS ARRAY ? ', nextStartKeyString); + + // Update the startKeyMap with the new start key for the next page + this.startKeyMap.set(pageIndex + 1, nextStartKeyString); console.log(this.startKeyMap); - data = data.slice(0, this.pageSize); // Trim the extra item + + // Trim the extra item to maintain consistent page size + data = data.slice(0, this.pageSize); } }, error: err => { 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 65faa15f78..f251648491 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 @@ -330,13 +330,12 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.tutorialActiveSubscription?.unsubscribe(); } - getViewForSort(sortActive: string | undefined): string { - const sortMap: { [key: string]: string } = { + getViewForSort(sortActive: string | undefined): string | string[] { + const sortMap: { [key: string]: string | string[] } = { lastModified: 'createdAt', - status: 'running', + status: ['running', 'elementId'], }; - // If the sortActive key exists in the map, return its value, otherwise return the original value. return sortMap[sortActive ?? ''] || sortActive || ''; } From 82c3094dc9e5a5e0036bc8be75ba5325dd76518e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 17:14:59 +0200 Subject: [PATCH 030/113] deleted Logs in sp-table-pagination --- .../setup/CouchDbInstallationStep.java | 2 +- .../sp-table-pagination.component.ts | 40 ++----------------- 2 files changed, 5 insertions(+), 37 deletions(-) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index f92df0acf4..1e673dec04 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -155,7 +155,7 @@ private void addPaginatorView() { MapReduce paginationFunctionByRunning = new MapReduce(); paginationFunctionByRunning.setMap( "function (doc) {\n" - + " emit([doc.properties.running ? 1 : 0, doc._id], doc);\n" + + " emit([doc.properties.running, doc._id], doc);\n" + "}" ); diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 6299f8a0ac..a0163c4cec 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -56,7 +56,7 @@ export class SpTablePaginationComponent implements AfterViewInit { @Input() columns: string[] = []; @ViewChild('paginator') paginator: MatPaginator; - //@ViewChild(MatSort) sort: MatSort; + @Input() sort: MatSort; @Input() fetchDataFn: ( startKey?: any, @@ -67,13 +67,12 @@ export class SpTablePaginationComponent implements AfterViewInit { dataSource = new MatTableDataSource([]); pageSize = 20; - totalItems = 1000000; // Optional: Use if backend returns total count + totalItems = 1000000; last_key = undefined; currentPage = 0; propertyName = 'createdAt'; isNextDisabled: boolean = false; - // Keep track of keys for pagination startKeyMap: Map = new Map(); private sortInitialized = false; @@ -81,31 +80,20 @@ export class SpTablePaginationComponent implements AfterViewInit { ngOnChanges(changes: SimpleChanges): void { if (changes['sort'] && this.sort && !this.sortInitialized) { this.sort.sortChange.subscribe((sortChange: Sort) => { - console.log('[Sort Changed]', sortChange); this.propertyName = this.getViewFn(sortChange.active); this.resetPagination(); - //this.loadData(0); }); this.sortInitialized = true; } } - constructor(private adapterService: AdapterService) { - console.log('[SpTablePagination] Constructor'); - } - - ngOnInit() { - console.log('[SpTablePagination] ngOnInit'); - } + constructor(private adapterService: AdapterService) {} ngAfterViewInit() { - console.log('INIT'); - this.loadData(0); // Initial load + this.loadData(0); } resetPagination() { - console.log('RESET Pagination'); this.startKeyMap.clear(); - console.log(this.startKeyMap); this.currentPage = 0; this.last_key = null; this.paginator.firstPage(); @@ -130,16 +118,10 @@ export class SpTablePaginationComponent implements AfterViewInit { this.table.setNoDataRow(this.noDataRow); } loadData(pageIndex: number) { - console.log('LOAD DATA'); const startkey = this.startKeyMap.get(pageIndex) || null; - console.log('PageIndex', pageIndex); - console.log('StartKey', startkey); this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ next: (data: T[]) => { - console.log('PROPERTY KEY', this.propertyName); - - // Handle pagination logic based on the page size if (data.length < this.pageSize) { this.dataSource.data = data; this.totalItems = data.length + pageIndex * this.pageSize; @@ -149,16 +131,11 @@ export class SpTablePaginationComponent implements AfterViewInit { this.totalItems = data.length + pageIndex * this.pageSize; } - console.log(data); - // Get the last key for the current page this.last_key = data[data.length - 1][this.propertyName]; - console.log(this.last_key); if (data.length > this.pageSize) { - // Build the next start key for pagination let nextStartKey; - // If propertyName is an array, handle as a composite key if (Array.isArray(this.propertyName)) { nextStartKey = this.propertyName.map( prop => data[this.pageSize][prop], @@ -166,19 +143,10 @@ export class SpTablePaginationComponent implements AfterViewInit { } else { nextStartKey = data[this.pageSize][this.propertyName]; } - - // Convert the next start key to a string (if it's an array, stringify it) const nextStartKeyString = Array.isArray(nextStartKey) ? JSON.stringify(nextStartKey) : nextStartKey; - - console.log('NEXT KEY AS ARRAY ? ', nextStartKeyString); - - // Update the startKeyMap with the new start key for the next page this.startKeyMap.set(pageIndex + 1, nextStartKeyString); - console.log(this.startKeyMap); - - // Trim the extra item to maintain consistent page size data = data.slice(0, this.pageSize); } }, From cf65525467d4fe430abd820e74384ff48001f5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 17:18:23 +0200 Subject: [PATCH 031/113] deleted more logs --- .../platform-services/src/lib/apis/adapter.service.ts | 1 - .../existing-adapters/existing-adapters.component.ts | 4 ---- 2 files changed, 5 deletions(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index db05ca9cca..bc2ca38033 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -97,7 +97,6 @@ export class AdapterService { params = params.set('view', property); params = params.set('descending', descending); - console.log('params', params); const url = `${this.connectPath}${path}`; return this.http.get(url, { params }).pipe( 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 f251648491..599f02cbfb 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 @@ -343,10 +343,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { startKey?: number, pageSize?: number, ): Observable => { - console.log('FROM FETCH ADAPTER', this.sort); - console.log('FROM FETCH ADAPTER', this.sort?.active); - console.log('FROM FETCH ADAPTER', this.sort?.direction); - console.log(this.sort?.direction == 'desc'); let view = 'createdAt'; if (this.sort?.active == 'lastModified') { view = 'createdAt'; From aae8542b17cc2710418a6bda5d6c34460f5384b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 16 Sep 2025 17:27:29 +0200 Subject: [PATCH 032/113] last fix --- .../sp-table-pagination/sp-table-pagination.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index a0163c4cec..6539805de3 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -148,6 +148,7 @@ export class SpTablePaginationComponent implements AfterViewInit { : nextStartKey; this.startKeyMap.set(pageIndex + 1, nextStartKeyString); data = data.slice(0, this.pageSize); + this.dataSource.data = data; } }, error: err => { From a8198c99aeb758b25501d62e842ee40e06b8d706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 07:59:36 +0200 Subject: [PATCH 033/113] minor --- .../sp-table-pagination.component.ts | 3 +-- .../existing-adapters.component.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 6539805de3..7ca962d45e 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -147,8 +147,7 @@ export class SpTablePaginationComponent implements AfterViewInit { ? JSON.stringify(nextStartKey) : nextStartKey; this.startKeyMap.set(pageIndex + 1, nextStartKeyString); - data = data.slice(0, this.pageSize); - this.dataSource.data = data; + this.dataSource.data = data.slice(0, this.pageSize); } }, error: err => { 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 599f02cbfb..0cfb9940d8 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 @@ -103,13 +103,13 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { - if (this.sort) { - this.sort.sort({ - id: 'lastModified', - start: 'desc', - disableClear: false, - }); // default sort - } + // if (this.sort) { + // this.sort.sort({ + // id: 'lastModified', + // start: 'asc', + // disableClear: false, + // }); // default sort + // } this.breadcrumbService.updateBreadcrumb( this.breadcrumbService.getRootLink(SpConnectRoutes.BASE), From 5a15a6f0ccd95213d0cba6bd92a187ccc13e2e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 09:03:47 +0200 Subject: [PATCH 034/113] save reload --- .../sp-table-pagination.component.ts | 10 ++- .../existing-adapters.component.html | 1 + .../existing-adapters.component.ts | 72 ++++++++++++------- 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 7ca962d45e..7d05b566a2 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -38,7 +38,7 @@ import { MatPaginator, PageEvent } from '@angular/material/paginator'; import { AdapterService } from '@streampipes/platform-services'; import { Observable } from 'rxjs'; import { MatSort, Sort } from '@angular/material/sort'; - +import { BehaviorSubject } from 'rxjs'; @Component({ selector: 'sp-table-pagination', templateUrl: './sp-table-pagination.component.html', @@ -58,6 +58,7 @@ export class SpTablePaginationComponent implements AfterViewInit { @ViewChild('paginator') paginator: MatPaginator; @Input() sort: MatSort; + @Input() refresh: BehaviorSubject; @Input() fetchDataFn: ( startKey?: any, pageSize?: number, @@ -85,6 +86,13 @@ export class SpTablePaginationComponent implements AfterViewInit { }); this.sortInitialized = true; } + + if (changes.refresh) { + this.refresh.subscribe(() => { + console.log('Trigger Data Load'); + this.loadData(this.currentPage); + }); + } } constructor(private adapterService: AdapterService) {} diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html index 2be1320a3e..ef5775340d 100644 --- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html +++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html @@ -102,6 +102,7 @@ [columns]="displayedColumns" [fetchDataFn]="fetchAdapters" [getViewFn]="getViewForSort" + [refresh]="refreshSwitch" data-cy="all-adapters-table" [sort]="sort" matSort 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 0cfb9940d8..6c7f0e4a8a 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 @@ -46,6 +46,8 @@ import { AdapterFilterPipe } from '../../filter/adapter-filter.pipe'; import { SpConnectRoutes } from '../../connect.routes'; import { Subscription, zip } from 'rxjs'; import { ShepherdService } from '../../../services/tour/shepherd.service'; +import { BehaviorSubject } from 'rxjs'; +import { tap } from 'rxjs/operators'; @Component({ selector: 'sp-existing-adapters', @@ -79,6 +81,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { //dataSource: MatTableDataSource = // new MatTableDataSource(); isAdmin = false; + refreshSwitch = new BehaviorSubject(false); adapterMetrics: Record = {}; tutorialActive = false; @@ -278,16 +281,22 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } getAdaptersRunning(): void { - this.adapterService.getAdapters().subscribe(adapters => { - this.existingAdapters = adapters; - this.existingAdapters.sort((a, b) => a.name.localeCompare(b.name)); - this.applyAdapterFilters(this.currentFilterIds); - this.operationInProgressAdapterId = undefined; - this.getMonitoringInfos(adapters); - setTimeout(() => { - // this.dataSource.sort = this.sort; - }); - }); + this.operationInProgressAdapterId = undefined; + console.log('Trigger Switch'); + console.log(this.refreshSwitch.value); + this.refreshSwitch.next(!this.refreshSwitch.value); + console.log(this.refreshSwitch.value); + //this.adapterService.getAdapters().subscribe(adapters => { + // this.existingAdapters = adapters; + // this.existingAdapters.sort((a, b) => a.name.localeCompare(b.name)); + // this.applyAdapterFilters(this.currentFilterIds); + // this.operationInProgressAdapterId = undefined; + // this.getMonitoringInfos(adapters); + // setTimeout(() => { + + // this.dataSource.sort = this.sort; + // }); + //}); } applyAdapterFilters(elementIds: Set): void { @@ -343,21 +352,32 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { startKey?: number, pageSize?: number, ): Observable => { - let view = 'createdAt'; - if (this.sort?.active == 'lastModified') { - view = 'createdAt'; - } else { - if (this.sort?.active == 'status') { - view = 'running'; - } else { - view = this.sort?.active; - } - } - return this.adapterService.getAdaptersPaginated( - startKey, - pageSize, - view, - this.sort?.direction != 'asc', - ); + const sortBy = this.getSortView(); // Refactor the sorting logic into a separate method. + + return this.adapterService + .getAdaptersPaginated( + startKey, + pageSize, + sortBy, + this.sort?.direction !== 'asc', // Use strict inequality for clarity + ) + .pipe( + tap(adapters => { + this.existingAdapters = adapters; + this.applyAdapterFilters(this.currentFilterIds); + this.operationInProgressAdapterId = undefined; + this.getMonitoringInfos(adapters); + }), + ); }; + + // Refactor the sorting logic into a separate method. + private getSortView(): string { + if (this.sort?.active === 'lastModified') { + return 'createdAt'; + } else if (this.sort?.active === 'status') { + return 'running'; + } + return this.sort?.active || 'createdAt'; // Default to 'createdAt' if no sort is specified + } } From ea3156a121038a3548dfed83110a97773ca60f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 09:16:06 +0200 Subject: [PATCH 035/113] some cleanup --- .../sp-table-pagination.component.ts | 1 - .../existing-adapters.component.ts | 26 ++++--------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 7d05b566a2..d92294f798 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -89,7 +89,6 @@ export class SpTablePaginationComponent implements AfterViewInit { if (changes.refresh) { this.refresh.subscribe(() => { - console.log('Trigger Data Load'); this.loadData(this.currentPage); }); } 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 6c7f0e4a8a..04f10c6e5a 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 @@ -106,13 +106,11 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { - // if (this.sort) { - // this.sort.sort({ - // id: 'lastModified', - // start: 'asc', - // disableClear: false, - // }); // default sort - // } + //this.sort.sort({ + // id: 'lastModified', + // start: 'asc', + // disableClear: false, + // }); // default sort this.breadcrumbService.updateBreadcrumb( this.breadcrumbService.getRootLink(SpConnectRoutes.BASE), @@ -282,21 +280,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { getAdaptersRunning(): void { this.operationInProgressAdapterId = undefined; - console.log('Trigger Switch'); - console.log(this.refreshSwitch.value); this.refreshSwitch.next(!this.refreshSwitch.value); - console.log(this.refreshSwitch.value); - //this.adapterService.getAdapters().subscribe(adapters => { - // this.existingAdapters = adapters; - // this.existingAdapters.sort((a, b) => a.name.localeCompare(b.name)); - // this.applyAdapterFilters(this.currentFilterIds); - // this.operationInProgressAdapterId = undefined; - // this.getMonitoringInfos(adapters); - // setTimeout(() => { - - // this.dataSource.sort = this.sort; - // }); - //}); } applyAdapterFilters(elementIds: Set): void { From 6c9af3688552d041c0d0db6723d60940b4cbfaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 09:27:49 +0200 Subject: [PATCH 036/113] error fixed --- .../existing-adapters.component.ts | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) 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 04f10c6e5a..a372c4720f 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 @@ -16,7 +16,13 @@ * */ -import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { + Component, + OnDestroy, + OnInit, + ViewChild, + ChangeDetectorRef, +} from '@angular/core'; import { AdapterDescription, AdapterMonitoringService, @@ -94,6 +100,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { stopAdapterErrorText = 'Could not stop adapter'; constructor( + private cdRef: ChangeDetectorRef, private adapterService: AdapterService, private dialogService: DialogService, private currentUserService: CurrentUserService, @@ -125,6 +132,26 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.shepherdService.tutorialActive$.subscribe(tutorialActive => { this.tutorialActive = tutorialActive; }); + + this.setDefaultSort(); + } + + ngAfterViewInit(): void { + // Ensure MatSort is initialized before interacting with it + this.setDefaultSort(); + } + + // Method to set the default sort + private setDefaultSort(): void { + if (this.sort) { + // Set default sort by 'lastModified' (for example) in ascending order + this.sort.sort({ + id: 'lastModified', + start: 'asc', // Or 'desc' for descending + disableClear: false, + }); + } + this.cdRef.detectChanges(); } startAdapter(adapter: AdapterDescription) { From 1aa39566e3f92aeb9b76201d6f01672c351803fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 09:32:12 +0200 Subject: [PATCH 037/113] added some comments --- .../existing-adapters.component.html | 2 +- .../existing-adapters.component.ts | 30 +++++-------------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html index ef5775340d..777f347f37 100644 --- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html +++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html @@ -101,7 +101,7 @@ fxFlex="100" [columns]="displayedColumns" [fetchDataFn]="fetchAdapters" - [getViewFn]="getViewForSort" + [getViewFn]="getViewKeysForSort" [refresh]="refreshSwitch" data-cy="all-adapters-table" [sort]="sort" 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 a372c4720f..31ee814de4 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 @@ -71,8 +71,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { @ViewChild(MatSort) sort: MatSort; - //@ViewChild('sortHeaderName') sortHeaderName: MatSortHeader; - displayedColumns: string[] = [ 'status', 'start', @@ -84,8 +82,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { 'action', ]; - //dataSource: MatTableDataSource = - // new MatTableDataSource(); isAdmin = false; refreshSwitch = new BehaviorSubject(false); @@ -113,12 +109,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { - //this.sort.sort({ - // id: 'lastModified', - // start: 'asc', - // disableClear: false, - // }); // default sort - this.breadcrumbService.updateBreadcrumb( this.breadcrumbService.getRootLink(SpConnectRoutes.BASE), ); @@ -137,17 +127,14 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } ngAfterViewInit(): void { - // Ensure MatSort is initialized before interacting with it this.setDefaultSort(); } - // Method to set the default sort private setDefaultSort(): void { if (this.sort) { - // Set default sort by 'lastModified' (for example) in ascending order this.sort.sort({ id: 'lastModified', - start: 'asc', // Or 'desc' for descending + start: 'asc', disableClear: false, }); } @@ -336,9 +323,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { applyFilter(filter: AdapterFilterSettingsModel) { this.currentFilter = filter; - // if (this.dataSource) { - // this.applyAdapterFilters(this.currentFilterIds); - // } } navigateToDetailsOverviewPage(adapter: AdapterDescription): void { @@ -350,7 +334,8 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.tutorialActiveSubscription?.unsubscribe(); } - getViewForSort(sortActive: string | undefined): string | string[] { + getViewKeysForSort(sortActive: string | undefined): string | string[] { + // This is necessary in case the element names in the HTML and the keys used for sorting follow different naming conventions or are composite keys. (E.g., created in HTML and the database key is createdAt) const sortMap: { [key: string]: string | string[] } = { lastModified: 'createdAt', status: ['running', 'elementId'], @@ -363,14 +348,13 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { startKey?: number, pageSize?: number, ): Observable => { - const sortBy = this.getSortView(); // Refactor the sorting logic into a separate method. - + const sortBy = this.getSortView(); return this.adapterService .getAdaptersPaginated( startKey, pageSize, sortBy, - this.sort?.direction !== 'asc', // Use strict inequality for clarity + this.sort?.direction !== 'asc', ) .pipe( tap(adapters => { @@ -382,13 +366,13 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { ); }; - // Refactor the sorting logic into a separate method. private getSortView(): string { + // Parse naming of the view if (this.sort?.active === 'lastModified') { return 'createdAt'; } else if (this.sort?.active === 'status') { return 'running'; } - return this.sort?.active || 'createdAt'; // Default to 'createdAt' if no sort is specified + return this.sort?.active || 'createdAt'; } } From 41f38aef30e83f0e88b4b36aaf51894d6ebb6a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 09:36:28 +0200 Subject: [PATCH 038/113] added some comments --- .../sp-table-pagination/sp-table-pagination.component.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index d92294f798..e8dcda2134 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -58,12 +58,15 @@ export class SpTablePaginationComponent implements AfterViewInit { @ViewChild('paginator') paginator: MatPaginator; @Input() sort: MatSort; + //Necessary if other refreshs than based on sort are crucial @Input() refresh: BehaviorSubject; + @Input() fetchDataFn: ( startKey?: any, pageSize?: number, ) => Observable; - + // This is necessary in case the element names in the HTML and the keys used for sorting follow different naming conventions or are composite keys. (E.g., created in HTML and the database key is createdAt) + // Provide the information as sortmap @Input() getViewFn: (sort: string) => string; dataSource = new MatTableDataSource([]); @@ -94,8 +97,6 @@ export class SpTablePaginationComponent implements AfterViewInit { } } - constructor(private adapterService: AdapterService) {} - ngAfterViewInit() { this.loadData(0); } From c769309c0b3544f26fa76fbe5081600793e67567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 09:58:17 +0200 Subject: [PATCH 039/113] started writing migration --- .../v099/AddAdapterPaginatorViewsToDB.java | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java new file mode 100644 index 0000000000..cf085e0c04 --- /dev/null +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java @@ -0,0 +1,134 @@ +/* + * 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.service.core.migrations.v099; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.streampipes.service.core.migrations.Migration; +import org.apache.streampipes.storage.couchdb.utils.Utils; +import org.lightcouch.DesignDocument; +import org.lightcouch.DesignDocument.MapReduce; + +import org.lightcouch.CouchDbClient; +import org.lightcouch.CouchDbProperties; +import org.lightcouch.CouchDbException; +import org.lightcouch.Document; + +import static org.apache.streampipes.manager.setup.design.DesignDocumentUtils.prepareDocument; + +public class AddAdapterPaginatorViewsToDB implements Migration { + + @Override + public boolean shouldExecute() { + //Check weather Database exists + + CouchDbClient client = Utils.getCouchDbAdapterInstanceClient(); + + // Design document ID you want to check for + String designDocId = "_design/paginator"; // Design document ID + + // Check if the design document exists + if (doesDesignDocumentExist(client, designDocId)) { + return false; + } else { + return true; + } + } + + public static boolean doesDesignDocumentExist(CouchDbClient client, String designDocId) { + try { + // Try to fetch the design document + Document doc = client.find(Document.class, designDocId); + return doc != null; // If found, return true + } catch (CouchDbException e) { + return false; // Design document not found + } + } + + @Override + public void executeMigration() throws IOException { + // Add View if not exists + + //TODO CALL ORIGINAL CODE + + DesignDocument paginatorDocument = prepareDocument("_design/paginator"); + + Map paginatorViews = new HashMap<>(); + + // View to paginate documents by creation time + MapReduce paginationFunctionByCreate = new MapReduce(); + paginationFunctionByCreate.setMap( + "function (doc) {\n" + + " if (doc.properties && doc.properties.createdAt) {\n" + + " emit(doc.properties.createdAt, doc);\n" + + " }\n" + + "}" + ); + + // View to paginate documents by name + MapReduce paginationFunctionByName = new MapReduce(); + paginationFunctionByName.setMap( + "function (doc) {\n" + + " if (doc.properties && doc.properties.name && typeof doc.properties.name === 'string') {\n" + + " emit(doc.properties.name, doc);\n" + + " }\n" + + "}" + ); + + // View to paginate documents by running + MapReduce paginationFunctionByRunning = new MapReduce(); + paginationFunctionByRunning.setMap( + "function (doc) {\n" + + " emit([doc.properties.running, doc._id], doc);\n" + + "}" + ); + + // View to list all non-design documents + MapReduce nonDesignDocsView = new MapReduce(); + nonDesignDocsView.setMap( + "function (doc) {\n" + + " if (!doc._id.startsWith(\"_design/\")) {\n" + + " emit(doc._id, null);\n" + + " }\n" + + "}" + ); + + // Add views to the document + paginatorViews.put("by_createdAt", paginationFunctionByCreate); + paginatorViews.put("by_name", paginationFunctionByName); + paginatorViews.put("by_running", paginationFunctionByRunning); + paginatorViews.put("non_design_docs", nonDesignDocsView); + + paginatorDocument.setViews(paginatorViews); + + Utils.getCouchDbAdapterInstanceClient() + .design() + .synchronizeWithDb(paginatorDocument); +} + + + @Override + public String getDescription() { + return "Check for Paginator view in AdapterInstances, if it does not exist, add the Paginatorview."; + + } + +} From 646b687dd85637328c2f0b2d0b239363d3ad00bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 10:07:02 +0200 Subject: [PATCH 040/113] migration working --- .../service/core/migrations/AvailableMigrations.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java index b547059f59..19991038f9 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java @@ -29,6 +29,7 @@ import org.apache.streampipes.service.core.migrations.v0980.AddDataLakeMeasureViewMigration; import org.apache.streampipes.service.core.migrations.v0980.ModifyAssetLinkTypesMigration; import org.apache.streampipes.service.core.migrations.v0980.ModifyAssetLinksMigration; +import org.apache.streampipes.service.core.migrations.v099.AddAdapterPaginatorViewsToDB; import org.apache.streampipes.service.core.migrations.v970.AddDataLakePipelineTemplateMigration; import org.apache.streampipes.service.core.migrations.v970.AddLinkSettingsMigration; import org.apache.streampipes.service.core.migrations.v970.AddRolesToUserDbMigration; @@ -36,6 +37,7 @@ import org.apache.streampipes.service.core.migrations.v970.ModifyAssetLinkTypeMigration; import org.apache.streampipes.service.core.migrations.v970.RemoveNodesFromOpcUaAdaptersMigration; + import java.util.Arrays; import java.util.List; @@ -43,6 +45,7 @@ public class AvailableMigrations { public List getAvailableMigrations() { return Arrays.asList( + new AddAdapterPaginatorViewsToDB(), new CreateAssetLinkTypeMigration(), new CreateDefaultAssetMigration(), new CreateFileAssetTypeMigration(), From 291803faacc5bbda6181da6dbc6740992c5208b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 10:10:42 +0200 Subject: [PATCH 041/113] migration order fix --- .../v099/AddAdapterPaginatorViewsToDB.java | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java index cf085e0c04..1d7039784d 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java @@ -18,32 +18,31 @@ package org.apache.streampipes.service.core.migrations.v099; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - import org.apache.streampipes.service.core.migrations.Migration; import org.apache.streampipes.storage.couchdb.utils.Utils; -import org.lightcouch.DesignDocument; -import org.lightcouch.DesignDocument.MapReduce; import org.lightcouch.CouchDbClient; -import org.lightcouch.CouchDbProperties; import org.lightcouch.CouchDbException; +import org.lightcouch.DesignDocument; +import org.lightcouch.DesignDocument.MapReduce; import org.lightcouch.Document; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + + + + import static org.apache.streampipes.manager.setup.design.DesignDocumentUtils.prepareDocument; public class AddAdapterPaginatorViewsToDB implements Migration { @Override public boolean shouldExecute() { - //Check weather Database exists - + CouchDbClient client = Utils.getCouchDbAdapterInstanceClient(); - - // Design document ID you want to check for - String designDocId = "_design/paginator"; // Design document ID + String designDocId = "_design/paginator"; // Check if the design document exists if (doesDesignDocumentExist(client, designDocId)) { @@ -55,18 +54,15 @@ public boolean shouldExecute() { public static boolean doesDesignDocumentExist(CouchDbClient client, String designDocId) { try { - // Try to fetch the design document Document doc = client.find(Document.class, designDocId); - return doc != null; // If found, return true + return doc != null; } catch (CouchDbException e) { - return false; // Design document not found + return false; } } @Override public void executeMigration() throws IOException { - // Add View if not exists - //TODO CALL ORIGINAL CODE DesignDocument paginatorDocument = prepareDocument("_design/paginator"); From f48abb5711ea4fce61bfd46e0da7021438be82a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 10:12:11 +0200 Subject: [PATCH 042/113] removed logger in AdapterStorageImpl --- .../couchdb/impl/AdapterInstanceStorageImpl.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 903c7cfc37..9ee3f2200d 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -24,16 +24,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.List; import java.util.NoSuchElementException; public class AdapterInstanceStorageImpl extends DefaultCrudStorage implements IAdapterStorage { - private static final Logger LOG = LoggerFactory.getLogger(AdapterInstanceStorageImpl.class.getCanonicalName()); - public AdapterInstanceStorageImpl() { super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); } @@ -67,11 +62,6 @@ public List findAll() { public List getAdapterPaginator(String startItem, int limit, String view, boolean descending) { long startItemLong = 0L; // default value String uri = "paginator/by_" + view; - - LOG.info(uri); - LOG.info(startItem); - LOG.info("Is active: {}", descending); - if (startItem == null) { return couchDbClientSupplier @@ -114,12 +104,10 @@ public List getAdapterPaginator(String startItem, int limit, .descending(descending) .query(AdapterDescription.class); } catch (Exception e) { - LOG.error("Failed to parse startItem as JSON array", e); throw new IllegalArgumentException("Invalid startItem format for compound key"); } } - LOG.info("Default return"); return couchDbClientSupplier .get() From 811bdf58be7c1964c1ec0a03c8b128ec78587318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 10:12:34 +0200 Subject: [PATCH 043/113] removed logger in AdapterStorageImpl --- .../storage/couchdb/impl/AdapterInstanceStorageImpl.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 9ee3f2200d..f278276dba 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -75,8 +75,6 @@ public List getAdapterPaginator(String startItem, int limit, } if ("createdAt".equals(view)) { - - LOG.info("PARSE LONG"); startItemLong = Long.parseLong(startItem); return couchDbClientSupplier @@ -108,7 +106,6 @@ public List getAdapterPaginator(String startItem, int limit, } } - return couchDbClientSupplier .get() .view(uri) From e9b01909c5f3a6344a80c1ae88c5345400baeabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 10:13:58 +0200 Subject: [PATCH 044/113] AdapterMasterManagement --- .../management/AdapterMasterManagement.java | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java index 78407f1db2..82895da319 100644 --- a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java +++ b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java @@ -41,7 +41,8 @@ import java.util.NoSuchElementException; /** - * This class is responsible for managing all the adapter instances which are executed on worker nodes + * This class is responsible for managing all the adapter instances which are + * executed on worker nodes */ public class AdapterMasterManagement { @@ -57,8 +58,7 @@ public AdapterMasterManagement( IAdapterStorage adapterInstanceStorage, AdapterResourceManager adapterResourceManager, DataStreamResourceManager dataStreamResourceManager, - AdapterMetrics adapterMetrics - ) { + AdapterMetrics adapterMetrics) { this.adapterInstanceStorage = adapterInstanceStorage; this.adapterMetrics = adapterMetrics; this.adapterResourceManager = adapterResourceManager; @@ -68,8 +68,7 @@ public AdapterMasterManagement( public void addAdapter( AdapterDescription adapterDescription, String adapterId, - String principalSid - ) + String principalSid) throws AdapterException { // Create elementId for datastream @@ -92,8 +91,7 @@ private void createDataStreamForAdapter( AdapterDescription adapterDescription, String adapterId, String streamId, - String principalSid - ) throws AdapterException { + String principalSid) throws AdapterException { var storedDescription = new SourcesManagement() .createAdapterDataStream(adapterDescription, streamId); storedDescription.setCorrespondingAdapterId(adapterId); @@ -116,7 +114,8 @@ public AdapterDescription getAdapter(String elementId) throws AdapterException { } /** - * First the adapter is stopped removed, then the corresponding data source is deleted + * First the adapter is stopped removed, then the corresponding data source is + * deleted * * @param elementId The elementId of the adapter instance * @throws AdapterException when adapter can not be stopped @@ -145,17 +144,13 @@ public List getAllAdapterInstances() { return adapterInstanceStorage.findAll(); } - public List getPaginatedAdapterInstances(String startkey, int limit, String view, boolean descending){ - return adapterInstanceStorage.getAdapterPaginator(startkey, limit, view,descending); + public List getPaginatedAdapterInstances(String startKey, int limit, String view, + boolean descending) { + return adapterInstanceStorage.getAdapterPaginator(startKey, limit, view, descending); } - //public List getPagedAdapterInstances(String startKey, int limit) { - // LOG.info("Get Paged"); - //return adapterInstanceStorage.findAll(); - //} - public void stopStreamAdapter(String elementId, - boolean forceStop) throws AdapterException { + boolean forceStop) throws AdapterException { AdapterDescription ad = adapterInstanceStorage.getElementById(elementId); try { @@ -190,8 +185,7 @@ public void startStreamAdapter(String elementId) throws AdapterException { ad.getAppId(), SpServiceUrlProvider.ADAPTER, ad.getDeploymentConfiguration() - .getDesiredServiceTags() - ); + .getDesiredServiceTags()); // Update selected endpoint URL of adapter ad.setSelectedEndpointUrl(baseUrl); @@ -200,7 +194,8 @@ public void startStreamAdapter(String elementId) throws AdapterException { // Invoke adapter instance WorkerRestClient.invokeStreamAdapter(baseUrl, elementId); - // register the adapter at the metrics manager so that the AdapterHealthCheck can send metrics + // register the adapter at the metrics manager so that the AdapterHealthCheck + // can send metrics adapterMetrics.register(ad.getElementId(), ad.getName()); LOG.info("Started adapter " + elementId + " on: " + baseUrl); @@ -211,8 +206,7 @@ public void startStreamAdapter(String elementId) throws AdapterException { private void installDataSource( SpDataStream stream, - String principalSid - ) throws AdapterException { + String principalSid) throws AdapterException { try { new DataStreamVerifier(stream).verifyAndAdd(principalSid, false); } catch (SepaParseException e) { From 6bf1ba9e93f7f190c1ff507ad95cf3ecdc4f5187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 10:16:17 +0200 Subject: [PATCH 045/113] Formated Adapter Resources --- .../rest/impl/connect/AdapterResource.java | 127 ++++++++---------- 1 file changed, 58 insertions(+), 69 deletions(-) diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java index 3cc0883b8a..8142d38f2b 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java @@ -72,11 +72,10 @@ public class AdapterResource extends AbstractAdapterResource new AdapterMasterManagement( StorageDispatcher.INSTANCE.getNoSqlStore() - .getAdapterInstanceStorage(), + .getAdapterInstanceStorage(), new SpResourceManager().manageAdapters(), new SpResourceManager().manageDataStreams(), - AdapterMetricsManager.INSTANCE.getAdapterMetrics() - )); + AdapterMetricsManager.INSTANCE.getAdapterMetrics())); } @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) @@ -99,7 +98,7 @@ public ResponseEntity addAdapter(@RequestBody AdapterDescript return ok(Notifications.success(adapterId)); } - @PostMapping(path = "compact", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = { + @PostMapping(path = "compact", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, SpMediaType.YAML, SpMediaType.YML @@ -124,36 +123,32 @@ public ResponseEntity updateAdapter(@RequestBody AdapterDescr return ok(Notifications.success(adapterDescription.getElementId())); } - @PutMapping(path = "pipeline-migration-preflight", consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) + @PutMapping(path = "pipeline-migration-preflight", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize(AuthConstants.HAS_WRITE_ADAPTER_PRIVILEGE) public ResponseEntity> performPipelineMigrationPreflight( - @RequestBody AdapterDescription adapterDescription - ) { + @RequestBody AdapterDescription adapterDescription) { var updateManager = new AdapterUpdateManagement(managementService); var migrations = updateManager.checkPipelineMigrations(adapterDescription); return ok(migrations); } - @GetMapping(path = "/{id}", produces = {MediaType.APPLICATION_JSON_VALUE, SpMediaType.YAML, SpMediaType.YML}) + @GetMapping(path = "/{id}", produces = { MediaType.APPLICATION_JSON_VALUE, SpMediaType.YAML, SpMediaType.YML }) @PreAuthorize("this.hasReadAuthority()") public ResponseEntity getAdapter( @PathVariable("id") String elementId, - @RequestParam(value = "output", - defaultValue = "full", - required = false) String outputMode - ) { + @RequestParam(value = "output", defaultValue = "full", required = false) String outputMode) { try { var adapterDescription = getAdapterDescription(elementId); - // This check is done here because the adapter permission is checked based on the corresponding data stream + // This check is done here because the adapter permission is checked based on + // the corresponding data stream // and not based on the element id if (!checkAdapterReadPermission(adapterDescription)) { LOG.error("User is not allowed to read adapter {}", elementId); return ResponseEntity.status(HttpStatus.SC_UNAUTHORIZED) - .build(); + .build(); } if (outputMode.equalsIgnoreCase("compact")) { @@ -176,18 +171,17 @@ public ResponseEntity getAdapter( private boolean checkAdapterReadPermission(AdapterDescription adapterDescription) { var spPermissionEvaluator = new SpPermissionEvaluator(); var authentication = SecurityContextHolder.getContext() - .getAuthentication(); + .getAuthentication(); return spPermissionEvaluator.hasPermission( authentication, adapterDescription.getCorrespondingDataStreamElementId(), - "READ" - ); + "READ"); } @PostMapping(path = "/{id}/stop", produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("this.hasWriteAuthority() and hasPermission('#elementId', 'WRITE')") public ResponseEntity stopAdapter(@PathVariable("id") String elementId, - @RequestParam(value = "forceStop", defaultValue = "false") boolean forceStop) { + @RequestParam(value = "forceStop", defaultValue = "false") boolean forceStop) { try { managementService.stopStreamAdapter(elementId, forceStop); return ok(Notifications.success("Adapter stopped")); @@ -213,12 +207,10 @@ public ResponseEntity startAdapter(@PathVariable("id") String elementId) { @PreAuthorize("this.hasWriteAuthority() and hasPermission('#elementId', 'WRITE')") public ResponseEntity deleteAdapter( @PathVariable("id") String elementId, - @RequestParam(value = "deleteAssociatedPipelines", defaultValue = "false") - boolean deleteAssociatedPipelines - ) { + @RequestParam(value = "deleteAssociatedPipelines", defaultValue = "false") boolean deleteAssociatedPipelines) { List pipelinesUsingAdapter = getPipelinesUsingAdapter(elementId); IPipelineStorage pipelineStorageAPI = StorageDispatcher.INSTANCE.getNoSqlStore() - .getPipelineStorageAPI(); + .getPipelineStorageAPI(); if (pipelinesUsingAdapter.isEmpty()) { try { @@ -232,40 +224,40 @@ public ResponseEntity deleteAdapter( List namesOfPipelinesUsingAdapter = pipelinesUsingAdapter .stream() .map(pipelineId -> pipelineStorageAPI.getElementById( - pipelineId) - .getName()) + pipelineId) + .getName()) .collect(Collectors.toList()); return ResponseEntity.status(HttpStatus.SC_CONFLICT) - .body(String.join(", ", namesOfPipelinesUsingAdapter)); + .body(String.join(", ", namesOfPipelinesUsingAdapter)); } else { PermissionResourceManager permissionResourceManager = new PermissionResourceManager(); - // find out the names of pipelines that have an owner and the owner is not the current user + // find out the names of pipelines that have an owner and the owner is not the + // current user List namesOfPipelinesNotOwnedByUser = pipelinesUsingAdapter .stream() - .filter(pipelineId -> - !permissionResourceManager.findForObjectId( - pipelineId) - .stream() - .findFirst() - .map( - Permission::getOwnerSid) - // if a pipeline has no owner, pretend the owner - // is the user so the user can delete it - .orElse( - this.getAuthenticatedUserSid()) - .equals( - this.getAuthenticatedUserSid())) + .filter(pipelineId -> !permissionResourceManager.findForObjectId( + pipelineId) + .stream() + .findFirst() + .map( + Permission::getOwnerSid) + // if a pipeline has no owner, pretend the owner + // is the user so the user can delete it + .orElse( + this.getAuthenticatedUserSid()) + .equals( + this.getAuthenticatedUserSid())) .map(pipelineId -> pipelineStorageAPI.getElementById( - pipelineId) - .getName()) + pipelineId) + .getName()) .collect(Collectors.toList()); boolean isAdmin = SecurityContextHolder.getContext() - .getAuthentication() - .getAuthorities() - .stream() - .anyMatch(r -> r.getAuthority() - .equals( - DefaultRole.ROLE_ADMIN.name())); + .getAuthentication() + .getAuthorities() + .stream() + .anyMatch(r -> r.getAuthority() + .equals( + DefaultRole.ROLE_ADMIN.name())); // if the user is admin or owns all pipelines using this adapter, // the user can delete all associated pipelines and this adapter if (isAdmin || namesOfPipelinesNotOwnedByUser.isEmpty()) { @@ -276,18 +268,19 @@ public ResponseEntity deleteAdapter( } managementService.deleteAdapter(elementId); return ok(Notifications.success("Adapter with id: " + elementId - + " and all pipelines using the adapter are deleted.")); + + " and all pipelines using the adapter are deleted.")); } catch (Exception e) { LOG.error( "Error while deleting adapter with id " - + elementId + " and all pipelines using the adapter", e - ); + + elementId + " and all pipelines using the adapter", + e); return ok(Notifications.error(e.getMessage())); } } else { - // otherwise, hint the user the names of pipelines using the adapter but not owned by the user + // otherwise, hint the user the names of pipelines using the adapter but not + // owned by the user return ResponseEntity.status(HttpStatus.SC_CONFLICT) - .body(String.join(", ", namesOfPipelinesNotOwnedByUser)); + .body(String.join(", ", namesOfPipelinesNotOwnedByUser)); } } } @@ -296,23 +289,19 @@ public ResponseEntity deleteAdapter( @PreAuthorize("this.hasReadAuthority()") @PostFilter("hasPermission(filterObject.correspondingDataStreamElementId, 'READ')") public List getAllAdapters() { - LOG.info("GET ALL ADAPTERS"); return managementService.getAllAdapterInstances(); } - @GetMapping(path = "/paginator", produces = MediaType.APPLICATION_JSON_VALUE) -@PreAuthorize("this.hasReadAuthority()") -@PostFilter("hasPermission(filterObject.correspondingDataStreamElementId, 'READ')") -public List getAllAdaptersPaginated( - @RequestParam(required = false) String startkey, - @RequestParam(defaultValue = "10") int limit, - @RequestParam(defaultValue = "createdAt") String view, - @RequestParam(defaultValue = "false") boolean descending - ) { - - LOG.info("GET Paginated ADAPTERS: startkey={}, limit={} view={} descending={}", startkey, limit, view, descending); - return managementService.getPaginatedAdapterInstances(startkey, limit, view,descending); -} + @GetMapping(path = "/paginator", produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("this.hasReadAuthority()") + @PostFilter("hasPermission(filterObject.correspondingDataStreamElementId, 'READ')") + public List getAllAdaptersPaginated( + @RequestParam(required = false) String startKey, + @RequestParam(defaultValue = "10") int limit, + @RequestParam(defaultValue = "createdAt") String view, + @RequestParam(defaultValue = "false") boolean descending) { + return managementService.getPaginatedAdapterInstances(startKey, limit, view, descending); + } private AdapterDescription getAdapterDescription(String elementId) throws AdapterException { return managementService.getAdapter(elementId); @@ -324,8 +313,8 @@ private CompactAdapter toCompactAdapterDescription(AdapterDescription adapterDes private List getPipelinesUsingAdapter(String adapterId) { return StorageDispatcher.INSTANCE.getNoSqlStore() - .getPipelineStorageAPI() - .getPipelinesUsingAdapter(adapterId); + .getPipelineStorageAPI() + .getPipelinesUsingAdapter(adapterId); } } From 9742ac0ec32e3641955e7620c324f6518c031f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 10:18:17 +0200 Subject: [PATCH 046/113] minor key renaming --- .../platform-services/src/lib/apis/adapter.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index bc2ca38033..c693e8ad10 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -92,7 +92,7 @@ export class AdapterService { let params = new HttpParams().set('limit', limit.toString()); if (startid) { - params = params.set('startkey', startid); + params = params.set('startKey', startid); } params = params.set('view', property); From 38483dfa2e5d20c4f1f94358a29bfeb8b036b82e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 11:24:29 +0200 Subject: [PATCH 047/113] refactored getAdapterPagination --- .../impl/AdapterInstanceStorageImpl.java | 70 ++++++++----------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index f278276dba..ff912f6041 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; import java.util.List; import java.util.NoSuchElementException; @@ -59,59 +60,48 @@ public List findAll() { } @Override - public List getAdapterPaginator(String startItem, int limit, String view, boolean descending) { +public List getAdapterPaginator(String startItem, int limit, String view, boolean descending) { long startItemLong = 0L; // default value String uri = "paginator/by_" + view; - if (startItem == null) { - - return couchDbClientSupplier - .get() - .view(uri) - .includeDocs(true) - .limit(limit) - .descending(descending) - .query(AdapterDescription.class); - - } - - if ("createdAt".equals(view)) { - startItemLong = Long.parseLong(startItem); - - return couchDbClientSupplier - .get() - .view(uri) - .includeDocs(true) - .limit(limit) - .startKey(startItemLong) - .descending(descending) - .query(AdapterDescription.class); - } - - if (startItem.startsWith("[") && startItem.endsWith("]")) { - try { - // Assuming the startItem is a JSON array in string form, we will parse it - ObjectMapper objectMapper = new ObjectMapper(); - Object[] startKeyArray = objectMapper.readValue(startItem, Object[].class); + if (startItem == null || startItem.isEmpty()) { return couchDbClientSupplier .get() .view(uri) .includeDocs(true) .limit(limit) - .startKey(startKeyArray) .descending(descending) .query(AdapterDescription.class); - } catch (Exception e) { - throw new IllegalArgumentException("Invalid startItem format for compound key"); - } } - return couchDbClientSupplier + var buildCall = couchDbClientSupplier .get() .view(uri) .includeDocs(true) - .limit(limit) - .startKey(startItem) - .descending(descending).query(AdapterDescription.class); - } + .limit(limit); + + if ("createdAt".equals(view)) { + try { + startItemLong = Long.parseLong(startItem); + buildCall = buildCall.startKey(startItemLong); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid startItem format for 'createdAt'", e); + } + } else if (startItem.startsWith("[") && startItem.endsWith("]")) { + try { + // Assuming the startItem is a JSON array in string form + ObjectMapper objectMapper = new ObjectMapper(); + Object[] startKeyArray = objectMapper.readValue(startItem, Object[].class); + buildCall = buildCall.startKey(startKeyArray); + } catch (IOException e) { + throw new IllegalArgumentException("Invalid startItem format for compound key", e); + } + } else { + buildCall = buildCall.startKey(startItem); + } + + return buildCall + .descending(descending) + .query(AdapterDescription.class); +} } From da0d1b59248ddeaacd8eaca9e928e286e0041be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 11:35:05 +0200 Subject: [PATCH 048/113] added EndItem to paginated API --- .../management/AdapterMasterManagement.java | 4 ++-- .../rest/impl/connect/AdapterResource.java | 3 ++- .../streampipes/storage/api/IAdapterStorage.java | 2 +- .../couchdb/impl/AdapterInstanceStorageImpl.java | 15 ++++++++++++++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java index 82895da319..8890f31b0f 100644 --- a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java +++ b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java @@ -144,9 +144,9 @@ public List getAllAdapterInstances() { return adapterInstanceStorage.findAll(); } - public List getPaginatedAdapterInstances(String startKey, int limit, String view, + public List getPaginatedAdapterInstances(String startKey, String endKey, int limit, String view, boolean descending) { - return adapterInstanceStorage.getAdapterPaginator(startKey, limit, view, descending); + return adapterInstanceStorage.getAdapterPaginator(startKey,endKey, limit, view, descending); } public void stopStreamAdapter(String elementId, diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java index 8142d38f2b..3cce5f70e7 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java @@ -297,10 +297,11 @@ public List getAllAdapters() { @PostFilter("hasPermission(filterObject.correspondingDataStreamElementId, 'READ')") public List getAllAdaptersPaginated( @RequestParam(required = false) String startKey, + @RequestParam(required = false) String endKey, @RequestParam(defaultValue = "10") int limit, @RequestParam(defaultValue = "createdAt") String view, @RequestParam(defaultValue = "false") boolean descending) { - return managementService.getPaginatedAdapterInstances(startKey, limit, view, descending); + return managementService.getPaginatedAdapterInstances(startKey,endKey, limit, view, descending); } private AdapterDescription getAdapterDescription(String elementId) throws AdapterException { diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java index d6b063b7ba..1d6358d79e 100644 --- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java +++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java @@ -28,5 +28,5 @@ public interface IAdapterStorage extends CRUDStorage { List getAdaptersByAppId(String appId); - List getAdapterPaginator(String startitem, int limit, String view, boolean descending); + List getAdapterPaginator(String startItem, String endItem, int limit, String view, boolean descending); } diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index ff912f6041..195d20bc5c 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -24,12 +24,18 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.util.List; import java.util.NoSuchElementException; public class AdapterInstanceStorageImpl extends DefaultCrudStorage implements IAdapterStorage { + private static final Logger LOG = LoggerFactory.getLogger(AdapterInstanceStorageImpl.class.getCanonicalName()); + + public AdapterInstanceStorageImpl() { super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); } @@ -60,7 +66,7 @@ public List findAll() { } @Override -public List getAdapterPaginator(String startItem, int limit, String view, boolean descending) { +public List getAdapterPaginator(String startItem, String endItem, int limit, String view, boolean descending) { long startItemLong = 0L; // default value String uri = "paginator/by_" + view; @@ -100,6 +106,13 @@ public List getAdapterPaginator(String startItem, int limit, buildCall = buildCall.startKey(startItem); } + if (endItem != null && !endItem.isEmpty()){ + + LOG.info("added end key"); + LOG.info(endItem); + buildCall = buildCall.endKey(endItem); + } + return buildCall .descending(descending) .query(AdapterDescription.class); From bf6517f71e73fd14a3585c6439f026c1c0656d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 11:43:45 +0200 Subject: [PATCH 049/113] added Endkey to frontend --- .../platform-services/src/lib/apis/adapter.service.ts | 2 ++ .../components/existing-adapters/existing-adapters.component.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index c693e8ad10..35ba908a0a 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -52,6 +52,7 @@ export class AdapterService { getAdaptersPaginated( startid: string | number | null, + endid: string | number | null, limit: number, property: string = 'createdAt', descending: boolean = false, @@ -59,6 +60,7 @@ export class AdapterService { return this.requestAdapterDescriptionsPaginated( '/master/adapters/paginator', startid, + endid, limit, property, descending, 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 31ee814de4..663303fc99 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 @@ -346,12 +346,14 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { fetchAdapters = ( startKey?: number, + endKey?: number, pageSize?: number, ): Observable => { const sortBy = this.getSortView(); return this.adapterService .getAdaptersPaginated( startKey, + endKey, pageSize, sortBy, this.sort?.direction !== 'asc', From 61820b64067ccccaea3d4450a93e4a7c55ab5e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 12:48:08 +0200 Subject: [PATCH 050/113] endkey working --- .../src/lib/apis/adapter.service.ts | 18 ++++++++++++++++-- .../existing-adapters.component.ts | 7 ++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index 35ba908a0a..e21077991c 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -57,6 +57,10 @@ export class AdapterService { property: string = 'createdAt', descending: boolean = false, ): Observable { + console.log('getAdaptersPaginated'); + console.log('1', startid); + console.log('2', endid); + console.log('3', limit); return this.requestAdapterDescriptionsPaginated( '/master/adapters/paginator', startid, @@ -87,20 +91,30 @@ export class AdapterService { requestAdapterDescriptionsPaginated( path: string, startid: string | number | null, + endid: string | number | null, limit: number, property: string, descending: boolean, ): Observable { + console.log('Start'); + console.log(limit); let params = new HttpParams().set('limit', limit.toString()); + console.log('Start1'); if (startid) { params = params.set('startKey', startid); } - + console.log('Start2'); + if (endid) { + params = params.set('endKey', endid); + } + console.log('Start3'); params = params.set('view', property); params = params.set('descending', descending); - const url = `${this.connectPath}${path}`; + console.log(params); + const url = `${this.connectPath}${path}`; + console.log('Call'); return this.http.get(url, { params }).pipe( map(response => { return (response as any[]).map(p => 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 663303fc99..43bdb4756f 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 @@ -346,10 +346,15 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { fetchAdapters = ( startKey?: number, - endKey?: number, pageSize?: number, + endKey?: number, ): Observable => { const sortBy = this.getSortView(); + console.log(sortBy); + console.log(startKey); + console.log(endKey); + console.log(pageSize); + return this.adapterService .getAdaptersPaginated( startKey, From 559c7da4876ddddf13ddfe1206b7d670f532158c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 13:22:41 +0200 Subject: [PATCH 051/113] filtering works --- .../sp-table-pagination.component.ts | 10 ++++++++ .../existing-adapters.component.html | 1 + .../existing-adapters.component.ts | 24 ++++++++++++------- .../filter-toolbar.component.ts | 1 + 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index e8dcda2134..d98b0c0e40 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -60,6 +60,7 @@ export class SpTablePaginationComponent implements AfterViewInit { @Input() sort: MatSort; //Necessary if other refreshs than based on sort are crucial @Input() refresh: BehaviorSubject; + @Input() filter: BehaviorSubject; @Input() fetchDataFn: ( startKey?: any, @@ -76,6 +77,7 @@ export class SpTablePaginationComponent implements AfterViewInit { currentPage = 0; propertyName = 'createdAt'; isNextDisabled: boolean = false; + filtering = ''; startKeyMap: Map = new Map(); @@ -95,6 +97,14 @@ export class SpTablePaginationComponent implements AfterViewInit { this.loadData(this.currentPage); }); } + + if (changes.filter) { + this.filter.subscribe(() => { + console.log('NEW FIlter Value', this.filter.value); + this.filtering = this.filter.value; + this.loadData(0); + }); + } } ngAfterViewInit() { diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html index 777f347f37..1066b6ab1d 100644 --- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html +++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.html @@ -103,6 +103,7 @@ [fetchDataFn]="fetchAdapters" [getViewFn]="getViewKeysForSort" [refresh]="refreshSwitch" + [filter]="filter" data-cy="all-adapters-table" [sort]="sort" matSort 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 43bdb4756f..b669813a98 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 @@ -84,6 +84,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { isAdmin = false; refreshSwitch = new BehaviorSubject(false); + filter = new BehaviorSubject(''); adapterMetrics: Record = {}; tutorialActive = false; @@ -321,8 +322,8 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { }); } - applyFilter(filter: AdapterFilterSettingsModel) { - this.currentFilter = filter; + applyFilter(filtering: AdapterFilterSettingsModel) { + this.filter.next(filtering.textFilter); } navigateToDetailsOverviewPage(adapter: AdapterDescription): void { @@ -345,15 +346,20 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } fetchAdapters = ( - startKey?: number, + startKey?: string, pageSize?: number, - endKey?: number, ): Observable => { - const sortBy = this.getSortView(); - console.log(sortBy); - console.log(startKey); - console.log(endKey); - console.log(pageSize); + let sortBy = this.getSortView(); + + let endKey: string | null = + this.filter.value !== '' ? this.filter.value : null; + if (endKey) { + startKey = endKey; + endKey = endKey + '\ufff0'; + sortBy = 'name'; + } + + console.log('EndKey Fetch Adapter', endKey); return this.adapterService .getAdaptersPaginated( 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 e90973b000..14e5c58927 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 @@ -47,6 +47,7 @@ export class SpConnectFilterToolbarComponent implements OnInit { } loadAvailableTypeCategories() { + //TODO THIS IS a TODO this.dataMarketplaceService.getAdapterCategories().subscribe(res => { this.adapterCategories = res; this.adapterCategories.unshift({ From 0757f00a47c21fc0609a8f530c8f6499bb657e88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 13:29:57 +0200 Subject: [PATCH 052/113] filtering works --- .../components/existing-adapters/existing-adapters.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 b669813a98..d1d1276246 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 @@ -299,6 +299,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } applyAdapterFilters(elementIds: Set): void { + // left in here for usage in Asset Browser this.currentFilterIds = elementIds; this.filteredAdapters = this.adapterFilter .transform(this.existingAdapters, this.currentFilter) @@ -372,7 +373,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { .pipe( tap(adapters => { this.existingAdapters = adapters; - this.applyAdapterFilters(this.currentFilterIds); this.operationInProgressAdapterId = undefined; this.getMonitoringInfos(adapters); }), From 4b36e014b70679cf6db03a95c3c96df0eb1856f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 13:43:12 +0200 Subject: [PATCH 053/113] added view for category base --- .../setup/CouchDbInstallationStep.java | 9 ++ .../v099/AddAdapterPaginatorViewsToDB.java | 131 +++++++++--------- 2 files changed, 75 insertions(+), 65 deletions(-) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index 1e673dec04..320b6a5c19 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -159,6 +159,14 @@ private void addPaginatorView() { + "}" ); + // View to paginate documents by categories + MapReduce paginationFunctionByCategory = new MapReduce(); + paginationFunctionByCategory.setMap( + "function (doc) {\n" + + " emit([doc.properties.category, doc._id], doc);\n" + + "}" + ); + // View to list all non-design documents MapReduce nonDesignDocsView = new MapReduce(); nonDesignDocsView.setMap( @@ -173,6 +181,7 @@ private void addPaginatorView() { paginatorViews.put("by_createdAt", paginationFunctionByCreate); paginatorViews.put("by_name", paginationFunctionByName); paginatorViews.put("by_running", paginationFunctionByRunning); + paginatorViews.put("by_category", paginationFunctionByCategory); paginatorViews.put("non_design_docs", nonDesignDocsView); paginatorDocument.setViews(paginatorViews); diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java index 1d7039784d..0c9739091c 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java @@ -31,18 +31,15 @@ import java.util.HashMap; import java.util.Map; - - - import static org.apache.streampipes.manager.setup.design.DesignDocumentUtils.prepareDocument; public class AddAdapterPaginatorViewsToDB implements Migration { @Override public boolean shouldExecute() { - + CouchDbClient client = Utils.getCouchDbAdapterInstanceClient(); - String designDocId = "_design/paginator"; + String designDocId = "_design/paginator"; // Check if the design document exists if (doesDesignDocumentExist(client, designDocId)) { @@ -52,79 +49,83 @@ public boolean shouldExecute() { } } - public static boolean doesDesignDocumentExist(CouchDbClient client, String designDocId) { + public static boolean doesDesignDocumentExist(CouchDbClient client, String designDocId) { try { Document doc = client.find(Document.class, designDocId); - return doc != null; + return doc != null; } catch (CouchDbException e) { - return false; + return false; } } @Override public void executeMigration() throws IOException { - //TODO CALL ORIGINAL CODE - - DesignDocument paginatorDocument = prepareDocument("_design/paginator"); - - Map paginatorViews = new HashMap<>(); - - // View to paginate documents by creation time - MapReduce paginationFunctionByCreate = new MapReduce(); - paginationFunctionByCreate.setMap( - "function (doc) {\n" - + " if (doc.properties && doc.properties.createdAt) {\n" - + " emit(doc.properties.createdAt, doc);\n" - + " }\n" - + "}" - ); - - // View to paginate documents by name - MapReduce paginationFunctionByName = new MapReduce(); - paginationFunctionByName.setMap( - "function (doc) {\n" - + " if (doc.properties && doc.properties.name && typeof doc.properties.name === 'string') {\n" - + " emit(doc.properties.name, doc);\n" - + " }\n" - + "}" - ); - - // View to paginate documents by running - MapReduce paginationFunctionByRunning = new MapReduce(); - paginationFunctionByRunning.setMap( - "function (doc) {\n" - + " emit([doc.properties.running, doc._id], doc);\n" - + "}" - ); - - // View to list all non-design documents - MapReduce nonDesignDocsView = new MapReduce(); - nonDesignDocsView.setMap( - "function (doc) {\n" - + " if (!doc._id.startsWith(\"_design/\")) {\n" - + " emit(doc._id, null);\n" - + " }\n" - + "}" - ); - - // Add views to the document - paginatorViews.put("by_createdAt", paginationFunctionByCreate); - paginatorViews.put("by_name", paginationFunctionByName); - paginatorViews.put("by_running", paginationFunctionByRunning); - paginatorViews.put("non_design_docs", nonDesignDocsView); - - paginatorDocument.setViews(paginatorViews); - + // TODO CALL ORIGINAL CODE + + DesignDocument paginatorDocument = prepareDocument("_design/paginator"); + + Map paginatorViews = new HashMap<>(); + + // View to paginate documents by creation time + MapReduce paginationFunctionByCreate = new MapReduce(); + paginationFunctionByCreate.setMap( + "function (doc) {\n" + + " if (doc.properties && doc.properties.createdAt) {\n" + + " emit(doc.properties.createdAt, doc);\n" + + " }\n" + + "}"); + + // View to paginate documents by name + MapReduce paginationFunctionByName = new MapReduce(); + paginationFunctionByName.setMap( + "function (doc) {\n" + + " if (doc.properties && doc.properties.name && typeof doc.properties.name === 'string') {\n" + + " emit(doc.properties.name, doc);\n" + + " }\n" + + "}"); + + // View to paginate documents by running + MapReduce paginationFunctionByRunning = new MapReduce(); + paginationFunctionByRunning.setMap( + "function (doc) {\n" + + " emit([doc.properties.running, doc._id], doc);\n" + + "}"); + + // View to paginate documents by categories + MapReduce paginationFunctionByCategory = new MapReduce(); + paginationFunctionByCategory.setMap( + "function (doc) {\n" + + " emit([doc.properties.category, doc._id], doc);\n" + + "}"); + + // View to list all non-design documents + MapReduce nonDesignDocsView = new MapReduce(); + nonDesignDocsView.setMap( + "function (doc) {\n" + + " if (!doc._id.startsWith(\"_design/\")) {\n" + + " emit(doc._id, null);\n" + + " }\n" + + "}"); + + // Add views to the document + paginatorViews.put("by_createdAt", paginationFunctionByCreate); + paginatorViews.put("by_name", paginationFunctionByName); + paginatorViews.put("by_running", paginationFunctionByRunning); + paginatorViews.put("by_category", paginationFunctionByCategory); + paginatorViews.put("non_design_docs", nonDesignDocsView); + + paginatorDocument.setViews(paginatorViews); + + // Push the design document to CouchDB Utils.getCouchDbAdapterInstanceClient() - .design() - .synchronizeWithDb(paginatorDocument); -} - + .design() + .synchronizeWithDb(paginatorDocument); + } @Override public String getDescription() { return "Check for Paginator view in AdapterInstances, if it does not exist, add the Paginatorview."; - + } } From e0fd74f7e04ac063deb4825dd7475ed877dc353d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Wed, 17 Sep 2025 14:35:16 +0200 Subject: [PATCH 054/113] filtering working again --- .../src/lib/apis/adapter.service.ts | 12 ---- .../sp-table-pagination.component.ts | 1 + .../existing-adapters.component.ts | 58 ++++++++++++++++--- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index e21077991c..ee96f9bed2 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -57,10 +57,6 @@ export class AdapterService { property: string = 'createdAt', descending: boolean = false, ): Observable { - console.log('getAdaptersPaginated'); - console.log('1', startid); - console.log('2', endid); - console.log('3', limit); return this.requestAdapterDescriptionsPaginated( '/master/adapters/paginator', startid, @@ -96,25 +92,17 @@ export class AdapterService { property: string, descending: boolean, ): Observable { - console.log('Start'); - console.log(limit); let params = new HttpParams().set('limit', limit.toString()); - console.log('Start1'); if (startid) { params = params.set('startKey', startid); } - console.log('Start2'); if (endid) { params = params.set('endKey', endid); } - console.log('Start3'); params = params.set('view', property); params = params.set('descending', descending); - - console.log(params); const url = `${this.connectPath}${path}`; - console.log('Call'); return this.http.get(url, { params }).pipe( map(response => { return (response as any[]).map(p => diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index d98b0c0e40..3f790b7c54 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -102,6 +102,7 @@ export class SpTablePaginationComponent implements AfterViewInit { this.filter.subscribe(() => { console.log('NEW FIlter Value', this.filter.value); this.filtering = this.filter.value; + this.resetPagination(); this.loadData(0); }); } 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 d1d1276246..2c9b5facc6 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 @@ -84,7 +84,10 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { isAdmin = false; refreshSwitch = new BehaviorSubject(false); - filter = new BehaviorSubject(''); + filter = new BehaviorSubject<{ text: string; category: string }>({ + text: '', + category: '', + }); adapterMetrics: Record = {}; tutorialActive = false; @@ -324,7 +327,43 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } applyFilter(filtering: AdapterFilterSettingsModel) { - this.filter.next(filtering.textFilter); + console.log(filtering); + if (filtering.textFilter != '') { + this.filter.next({ text: filtering.textFilter, category: '' }); + } + if ( + filtering.selectedCategory != '' && + filtering.selectedCategory != 'All' + ) { + this.filter.next({ + text: '', + category: filtering.selectedCategory, + }); + } + + if (filtering.selectedCategory == 'All' && filtering.textFilter == '') { + this.filter.next({ text: '', category: '' }); + } + } + + getEndKeyFromFilter(): { endKey: string | null; sortby: string } { + let endKey: string | null = null; + let sortBy: string; + if (this.filter.value.text != '') { + endKey = this.filter.value.text; + sortBy = 'name'; + } else { + if ( + this.filter.value.category != '' && + this.filter.value.category != 'All' + ) { + endKey = '[[' + this.filter.value.category + '],'; + sortBy = 'category'; + } + } + + console.log('FROM FILTERING', endKey); + return { endKey: endKey, sortby: sortBy }; } navigateToDetailsOverviewPage(adapter: AdapterDescription): void { @@ -351,16 +390,19 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { pageSize?: number, ): Observable => { let sortBy = this.getSortView(); + const filterkeys = this.getEndKeyFromFilter(); - let endKey: string | null = - this.filter.value !== '' ? this.filter.value : null; - if (endKey) { - startKey = endKey; - endKey = endKey + '\ufff0'; - sortBy = 'name'; + let endKey: string | null = null; + + if (filterkeys.endKey) { + startKey = filterkeys.endKey; + endKey = filterkeys.endKey + '\ufff0'; + sortBy = filterkeys.sortby; } console.log('EndKey Fetch Adapter', endKey); + console.log('EndKey Fetch Adapter', startKey); + console.log('EndKey Fetch Adapter', sortBy); return this.adapterService .getAdaptersPaginated( From 8289d28b648632353af9fd950b4daeba7af0382f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Thu, 18 Sep 2025 08:59:21 +0200 Subject: [PATCH 055/113] save before cleanup --- .../management/AdapterMasterManagement.java | 7 + .../setup/CouchDbInstallationStep.java | 69 +++--- .../rest/impl/connect/AdapterResource.java | 11 + .../v099/AddAdapterPaginatorViewsToDB.java | 7 +- .../storage/api/IAdapterStorage.java | 2 + .../impl/AdapterInstanceStorageImpl.java | 212 ++++++++++++------ .../src/lib/apis/adapter.service.ts | 1 + .../existing-adapters.component.ts | 13 +- 8 files changed, 209 insertions(+), 113 deletions(-) diff --git a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java index 8890f31b0f..96978cdeae 100644 --- a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java +++ b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java @@ -149,6 +149,13 @@ public List getPaginatedAdapterInstances(String startKey, St return adapterInstanceStorage.getAdapterPaginator(startKey,endKey, limit, view, descending); } + + public List getItemsByCategoryPaginated(String category, String startKey, int limit, + boolean descending) { + return adapterInstanceStorage.getItemsByCategoryPaginated(category,startKey, limit, descending); + } + + public void stopStreamAdapter(String elementId, boolean forceStop) throws AdapterException { AdapterDescription ad = adapterInstanceStorage.getElementById(elementId); diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index 320b6a5c19..577c274958 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -52,8 +52,7 @@ public void install() { new CreateAssetLinkTypeTask().execute(); new CreateDefaultAssetTask().execute(); new AddDefaultPipelineTemplatesTask( - StorageDispatcher.INSTANCE.getNoSqlStore().getPipelineTemplateStorage() - ).execute(); + StorageDispatcher.INSTANCE.getNoSqlStore().getPipelineTemplateStorage()).execute(); } @Override @@ -114,8 +113,7 @@ private void addNotificationView() { + "}"); notificationCountTypeViews.put("unread", countFunction); notificationCountDocument.setViews(notificationCountTypeViews); - Response countResp = - Utils.getCouchDbNotificationClient().design().synchronizeWithDb(notificationCountDocument); + Response countResp = Utils.getCouchDbNotificationClient().design().synchronizeWithDb(notificationCountDocument); if (resp.getError() != null && countResp != null) { logFailure(PREPARING_NOTIFICATIONS_TEXT); @@ -126,7 +124,8 @@ private void addNotificationView() { logFailure(PREPARING_NOTIFICATIONS_TEXT, e); } } -private void addPaginatorView() { + + private void addPaginatorView() { DesignDocument paginatorDocument = prepareDocument("_design/paginator"); Map paginatorViews = new HashMap<>(); @@ -134,48 +133,46 @@ private void addPaginatorView() { // View to paginate documents by creation time MapReduce paginationFunctionByCreate = new MapReduce(); paginationFunctionByCreate.setMap( - "function (doc) {\n" - + " if (doc.properties && doc.properties.createdAt) {\n" - + " emit(doc.properties.createdAt, doc);\n" - + " }\n" - + "}" - ); + "function (doc) {\n" + + " if (doc.properties && doc.properties.createdAt) {\n" + + " emit(doc.properties.createdAt, doc);\n" + + " }\n" + + "}"); // View to paginate documents by name MapReduce paginationFunctionByName = new MapReduce(); paginationFunctionByName.setMap( - "function (doc) {\n" - + " if (doc.properties && doc.properties.name && typeof doc.properties.name === 'string') {\n" - + " emit(doc.properties.name, doc);\n" - + " }\n" - + "}" - ); + "function (doc) {\n" + + " if (doc.properties && doc.properties.name && typeof doc.properties.name === 'string') {\n" + + " emit(doc.properties.name, doc);\n" + + " }\n" + + "}"); // View to paginate documents by running MapReduce paginationFunctionByRunning = new MapReduce(); paginationFunctionByRunning.setMap( - "function (doc) {\n" - + " emit([doc.properties.running, doc._id], doc);\n" - + "}" - ); + "function (doc) {\n" + + " emit([doc.properties.running, doc._id], doc);\n" + + "}"); - // View to paginate documents by categories MapReduce paginationFunctionByCategory = new MapReduce(); paginationFunctionByCategory.setMap( - "function (doc) {\n" - + " emit([doc.properties.category, doc._id], doc);\n" - + "}" - ); + "function (doc) {\n" + + " if (doc.properties && Array.isArray(doc.properties.category)) {\n" + + " doc.properties.category.forEach(function (cat) {\n" + + " emit([cat, doc._id], doc);\n" + + " });\n" + + " }\n" + + "}"); // View to list all non-design documents MapReduce nonDesignDocsView = new MapReduce(); nonDesignDocsView.setMap( - "function (doc) {\n" - + " if (!doc._id.startsWith(\"_design/\")) {\n" - + " emit(doc._id, null);\n" - + " }\n" - + "}" - ); + "function (doc) {\n" + + " if (!doc._id.startsWith(\"_design/\")) {\n" + + " emit(doc._id, null);\n" + + " }\n" + + "}"); // Add views to the document paginatorViews.put("by_createdAt", paginationFunctionByCreate); @@ -188,9 +185,10 @@ private void addPaginatorView() { // Push the design document to CouchDB Utils.getCouchDbAdapterInstanceClient() - .design() - .synchronizeWithDb(paginatorDocument); -} + .design() + .synchronizeWithDb(paginatorDocument); + } + private void addPipelineView() { DesignDocument pipelineDocument = prepareDocument("_design/adapters"); DesignDocument allPipelinesDocument = prepareDocument("_design/pipelines"); @@ -211,7 +209,6 @@ private void addPipelineView() { pipelineDocument.setViews(adapterViews); Utils.getCouchDbPipelineClient().design().synchronizeWithDb(pipelineDocument); - MapReduce allPipelinesFunction = new MapReduce(); allPipelinesFunction.setMap("function (doc) {\n" + " emit(doc._id, doc);\n" diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java index 3cce5f70e7..3d60bbbd35 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java @@ -304,6 +304,17 @@ public List getAllAdaptersPaginated( return managementService.getPaginatedAdapterInstances(startKey,endKey, limit, view, descending); } + @GetMapping(path = "/paginator/category", produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("this.hasReadAuthority()") + @PostFilter("hasPermission(filterObject.correspondingDataStreamElementId, 'READ')") + public List getCategoryAdaptersPaginated( + @RequestParam(required = false) String startKey, + @RequestParam(required = false) String category, + @RequestParam(defaultValue = "10") int limit, + @RequestParam(defaultValue = "false") boolean descending) { + return managementService.getItemsByCategoryPaginated(category, startKey, limit,descending); + } + private AdapterDescription getAdapterDescription(String elementId) throws AdapterException { return managementService.getAdapter(elementId); } diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java index 0c9739091c..ac5f1c5966 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java @@ -91,11 +91,14 @@ public void executeMigration() throws IOException { + " emit([doc.properties.running, doc._id], doc);\n" + "}"); - // View to paginate documents by categories MapReduce paginationFunctionByCategory = new MapReduce(); paginationFunctionByCategory.setMap( "function (doc) {\n" - + " emit([doc.properties.category, doc._id], doc);\n" + + " if (doc.properties && Array.isArray(doc.properties.category)) {\n" + + " doc.properties.category.forEach(function (cat) {\n" + + " emit([cat, doc._id], doc);\n" + + " });\n" + + " }\n" + "}"); // View to list all non-design documents diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java index 1d6358d79e..7c579b2df5 100644 --- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java +++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java @@ -29,4 +29,6 @@ public interface IAdapterStorage extends CRUDStorage { List getAdaptersByAppId(String appId); List getAdapterPaginator(String startItem, String endItem, int limit, String view, boolean descending); + List getItemsByCategoryPaginated(String category, String startDocId, int limit, + boolean descending); } diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 195d20bc5c..8a0316a75d 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -23,98 +23,164 @@ import org.apache.streampipes.storage.couchdb.utils.Utils; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; +import java.util.stream.Collectors; public class AdapterInstanceStorageImpl extends DefaultCrudStorage implements IAdapterStorage { private static final Logger LOG = LoggerFactory.getLogger(AdapterInstanceStorageImpl.class.getCanonicalName()); + public AdapterInstanceStorageImpl() { + super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); + } + + @Override + public AdapterDescription getFirstAdapterByAppId(String appId) { + return this.findAll() + .stream() + .filter(p -> p.getAppId().equals(appId)) + .findFirst() + .orElseThrow(NoSuchElementException::new); + } - public AdapterInstanceStorageImpl() { - super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); - } - - @Override - public AdapterDescription getFirstAdapterByAppId(String appId) { - return this.findAll() - .stream() - .filter(p -> p.getAppId().equals(appId)) - .findFirst() - .orElseThrow(NoSuchElementException::new); - } - - @Override - public List getAdaptersByAppId(String appId) { - return this.findAll() - .stream() - .filter(p -> p.getAppId().equals(appId)) - .toList(); - } - - @Override - public List findAll() { - List adapters = findAll("paginator/non_design_docs"); - return adapters.stream() - .filter(adapter -> adapter.getDescription() != null) - .toList(); - } - - @Override -public List getAdapterPaginator(String startItem, String endItem, int limit, String view, boolean descending) { - long startItemLong = 0L; // default value - String uri = "paginator/by_" + view; - - if (startItem == null || startItem.isEmpty()) { - return couchDbClientSupplier - .get() - .view(uri) - .includeDocs(true) - .limit(limit) - .descending(descending) - .query(AdapterDescription.class); + @Override + public List getAdaptersByAppId(String appId) { + return this.findAll() + .stream() + .filter(p -> p.getAppId().equals(appId)) + .toList(); } - var buildCall = couchDbClientSupplier - .get() - .view(uri) - .includeDocs(true) - .limit(limit); - - if ("createdAt".equals(view)) { - try { - startItemLong = Long.parseLong(startItem); - buildCall = buildCall.startKey(startItemLong); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid startItem format for 'createdAt'", e); + @Override + public List findAll() { + List adapters = findAll("paginator/non_design_docs"); + return adapters.stream() + .filter(adapter -> adapter.getDescription() != null) + .toList(); + } + + @Override + public List getAdapterPaginator(String startItem, String endItem, int limit, String view, + boolean descending) { + long startItemLong = 0L; // default value + String uri = "paginator/by_" + view; + + LOG.info(startItem); + + if (startItem == null || startItem.isEmpty()) { + return couchDbClientSupplier + .get() + .view(uri) + .includeDocs(true) + .limit(limit) + .descending(descending) + .query(AdapterDescription.class); } - } else if (startItem.startsWith("[") && startItem.endsWith("]")) { - try { - // Assuming the startItem is a JSON array in string form - ObjectMapper objectMapper = new ObjectMapper(); - Object[] startKeyArray = objectMapper.readValue(startItem, Object[].class); - buildCall = buildCall.startKey(startKeyArray); - } catch (IOException e) { - throw new IllegalArgumentException("Invalid startItem format for compound key", e); + + var buildCall = couchDbClientSupplier + .get() + .view(uri) + .includeDocs(true) + .limit(limit); + + if ("createdAt".equals(view)) { + try { + startItemLong = Long.parseLong(startItem); + buildCall = buildCall.startKey(startItemLong); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid startItem format for 'createdAt'", e); + } + } else if (startItem.startsWith("[") && startItem.endsWith("]")) { + try { + // Assuming the startItem is a JSON array in string form + LOG.info("Starting Object Thinf"); + ObjectMapper objectMapper = new ObjectMapper(); + Object[] startKeyArray = objectMapper.readValue(startItem, Object[].class); + LOG.info("Array Start Key"); + LOG.info("Array Start Key: " + Arrays.toString(startKeyArray)); + buildCall = buildCall.startKey(startKeyArray[0]); + + } catch (IOException e) { + throw new IllegalArgumentException("Invalid startItem format for compound key", e); + } + } else { + LOG.info(startItem); + buildCall = buildCall.startKey(startItem); } - } else { - buildCall = buildCall.startKey(startItem); - } - if (endItem != null && !endItem.isEmpty()){ + if (endItem != null && !endItem.isEmpty()) { + + LOG.info("added end key"); + LOG.info(endItem); + if (endItem.startsWith("[") && endItem.endsWith("]")) { + try { + // Assuming the startItem is a JSON array in string form + LOG.info("Starting Object Thinf"); + ObjectMapper objectMapper = new ObjectMapper(); + // TODO CHANGED END TO START + Object[] endKeyArray = objectMapper.readValue(startItem, Object[].class); + + + LOG.info("Array End Key: " + Arrays.toString(endKeyArray)); + + buildCall = buildCall.endKey(endKeyArray[0]); + + - LOG.info("added end key"); - LOG.info(endItem); - buildCall = buildCall.endKey(endItem); + } catch (IOException e) { + throw new IllegalArgumentException("Invalid startItem format for compound key", e); + } + } else { + buildCall = buildCall.endKey(endItem); + } + } + + return buildCall + .descending(descending) + .query(AdapterDescription.class); } - return buildCall - .descending(descending) - .query(AdapterDescription.class); -} + @Override + public List getItemsByCategoryPaginated(String category, String startDocId, int limit, + boolean descending) { + + String viewName = "paginator/by_category"; + + // Construct start key + Object[] startKey = (startDocId != null && !startDocId.isEmpty()) + ? new Object[] { category } // startDocID + : new Object[] { category }; + + // Construct end key + Object[] endKey = new Object[] { category, "\ufff0" }; + + //LOG.info("Category: " + category); + LOG.info("StartDocId: " + startDocId); + LOG.info("StartKey: " + Arrays.toString(startKey)); + LOG.info("EndKey: " + Arrays.toString(endKey)); + LOG.info("Descending: " + descending); + + var viewQuery = couchDbClientSupplier.get() + .view(viewName) + .includeDocs(true) + .limit(limit) + .descending(descending) + .startKey(startKey) + .endKey(endKey).query(AdapterDescription.class); + + // Manually filter to enforce exact match + List filtered = viewQuery.stream() + .filter(doc -> doc.getCategory() != null && doc.getCategory().contains(category)) + .collect(Collectors.toList()); + + return filtered; + } } diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index ee96f9bed2..e13a081842 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -57,6 +57,7 @@ export class AdapterService { property: string = 'createdAt', descending: boolean = false, ): Observable { + console.log('Property', property); return this.requestAdapterDescriptionsPaginated( '/master/adapters/paginator', startid, 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 2c9b5facc6..3c8ac31090 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 @@ -357,7 +357,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.filter.value.category != '' && this.filter.value.category != 'All' ) { - endKey = '[[' + this.filter.value.category + '],'; + endKey = '["' + this.filter.value.category + '"'; sortBy = 'category'; } } @@ -380,6 +380,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { const sortMap: { [key: string]: string | string[] } = { lastModified: 'createdAt', status: ['running', 'elementId'], + category: ['category', 'elementId'], }; return sortMap[sortActive ?? ''] || sortActive || ''; @@ -396,7 +397,15 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { if (filterkeys.endKey) { startKey = filterkeys.endKey; - endKey = filterkeys.endKey + '\ufff0'; + if (startKey.startsWith('[')) { + startKey = startKey + ']'; + } + + if (startKey.startsWith('[')) { + endKey = filterkeys.endKey + ',"\ufff0"]'; + } else { + endKey = filterkeys.endKey + '\ufff0'; + } sortBy = filterkeys.sortby; } From e454473403aafd6d2e7ba745faaaaaa8ade77292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Thu, 18 Sep 2025 10:56:51 +0200 Subject: [PATCH 056/113] first working draft --- .../impl/AdapterInstanceStorageImpl.java | 166 +++++++++++++----- 1 file changed, 125 insertions(+), 41 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 8a0316a75d..8e13922cd1 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -21,14 +21,32 @@ import org.apache.streampipes.model.connect.adapter.AdapterDescription; import org.apache.streampipes.storage.api.IAdapterStorage; import org.apache.streampipes.storage.couchdb.utils.Utils; +import org.lightcouch.CouchDbClient; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URLEncoder; +import java.util.Base64; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; @@ -120,67 +138,133 @@ public List getAdapterPaginator(String startItem, String end LOG.info("added end key"); LOG.info(endItem); - if (endItem.startsWith("[") && endItem.endsWith("]")) { - try { - // Assuming the startItem is a JSON array in string form - LOG.info("Starting Object Thinf"); - ObjectMapper objectMapper = new ObjectMapper(); - // TODO CHANGED END TO START - Object[] endKeyArray = objectMapper.readValue(startItem, Object[].class); - + buildCall = buildCall.endKey(endItem); + + } - LOG.info("Array End Key: " + Arrays.toString(endKeyArray)); + return buildCall + .descending(descending) + .query(AdapterDescription.class); + } - buildCall = buildCall.endKey(endKeyArray[0]); + @Override +public List getItemsByCategoryPaginated(String category, String startDocId, int limit, boolean descending) { + List resultList = new ArrayList<>(); + + try { + + CouchDbClient dbClient = couchDbClientSupplier.get();//new CouchDbClient(); // or however you're managing it + // GET INFO from dbClient + + LOG.info(dbClient.getBaseUri().toString()); + LOG.info(dbClient.getBaseUri()); + + Gson gson = dbClient.getGson(); + String host = "localhost"; + int port = 5984; + String dbName = "adapterinstance"; + String designDoc = "paginator"; + String viewName = "by_category"; + + + + // Query parameters + String startKey = URLEncoder.encode("[\"" + category + "\"]", StandardCharsets.UTF_8); + String endKey = URLEncoder.encode("[\"" + category + "\", \"\ufff0\"]", StandardCharsets.UTF_8); + + // Construct full URL + String urlStr = String.format( + "http://%s:%d/%s/_design/%s/_view/%s?startkey=%s&endkey=%s&limit=%d&include_docs=true", + host, port, dbName, designDoc, viewName, startKey, endKey, limit + ); + + // Auth + String username = "admin"; + String password = "admin"; + String authHeader = Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); + + // HTTP request setup + URL url = new URL(urlStr); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setRequestProperty("Authorization", "Basic " + authHeader); + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); + + int responseCode = conn.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_OK) { + throw new RuntimeException("Failed with HTTP code: " + responseCode); + } + + // ✅ Parse response using Gson + try (Reader reader = new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)) { + JsonObject root = JsonParser.parseReader(reader).getAsJsonObject(); + + if (root.has("rows")) { + JsonArray rows = root.getAsJsonArray("rows"); + for (JsonElement rowElem : rows) { + JsonObject rowObj = rowElem.getAsJsonObject(); + JsonElement docElem = rowObj.get("doc"); + if (docElem != null && !docElem.isJsonNull()) { + // Optional: enforce @class for polymorphic deserialization if needed + docElem.getAsJsonObject().addProperty("@class", "org.apache.streampipes.model.connect.adapter.AdapterDescription"); - } catch (IOException e) { - throw new IllegalArgumentException("Invalid startItem format for compound key", e); + AdapterDescription adapter = gson.fromJson(docElem, AdapterDescription.class); + resultList.add(adapter); + } } - } else { - buildCall = buildCall.endKey(endItem); } } - return buildCall - .descending(descending) - .query(AdapterDescription.class); + } catch (IOException e) { + System.err.println("I/O error during CouchDB request: " + e.getMessage()); + e.printStackTrace(); + } catch (RuntimeException e) { + System.err.println("Runtime exception: " + e.getMessage()); + e.printStackTrace(); + } catch (Exception e) { + System.err.println("Unexpected exception: " + e.getMessage()); + e.printStackTrace(); } - @Override - public List getItemsByCategoryPaginated(String category, String startDocId, int limit, - boolean descending) { + return resultList; + + - String viewName = "paginator/by_category"; + + //String viewName = "paginator/by_category"; // Construct start key - Object[] startKey = (startDocId != null && !startDocId.isEmpty()) - ? new Object[] { category } // startDocID - : new Object[] { category }; + //Object[] startKey = (startDocId != null && !startDocId.isEmpty()) + // ? new Object[] { category } // startDocID + // : new Object[] { category }; // Construct end key - Object[] endKey = new Object[] { category, "\ufff0" }; + //Object[] endKey = new Object[] { category, "\ufff0" }; //LOG.info("Category: " + category); - LOG.info("StartDocId: " + startDocId); - LOG.info("StartKey: " + Arrays.toString(startKey)); - LOG.info("EndKey: " + Arrays.toString(endKey)); - LOG.info("Descending: " + descending); - - var viewQuery = couchDbClientSupplier.get() - .view(viewName) - .includeDocs(true) - .limit(limit) - .descending(descending) - .startKey(startKey) - .endKey(endKey).query(AdapterDescription.class); + //LOG.info("StartDocId: " + startDocId); + //LOG.info("StartKey: " + Arrays.toString(startKey)); + //LOG.info("EndKey: " + Arrays.toString(endKey)); + //LOG.info("Descending: " + descending); + + //var viewQuery = couchDbClientSupplier.get() + // .view(viewName) + // .includeDocs(true) + // .limit(limit) + // .descending(descending) + // .startKey(startKey) + // .endKey(endKey).query(AdapterDescription.class); // Manually filter to enforce exact match - List filtered = viewQuery.stream() - .filter(doc -> doc.getCategory() != null && doc.getCategory().contains(category)) - .collect(Collectors.toList()); + //List filtered = viewQuery.stream() + // .filter(doc -> doc.getCategory() != null && doc.getCategory().contains(category)) + // .collect(Collectors.toList()); - return filtered; + // return filtered; } + + } From 7ac3140692b25b3e6179ef677adfe069907dfc34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Thu, 18 Sep 2025 11:14:56 +0200 Subject: [PATCH 057/113] First draft of working backend --- .../impl/AdapterInstanceStorageImpl.java | 52 ++++++++++++++++--- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 8e13922cd1..b750748440 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -22,6 +22,7 @@ import org.apache.streampipes.storage.api.IAdapterStorage; import org.apache.streampipes.storage.couchdb.utils.Utils; import org.lightcouch.CouchDbClient; +import org.lightcouch.CouchDbProperties; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; @@ -42,6 +43,7 @@ import java.io.Reader; import java.net.HttpURLConnection; import java.net.MalformedURLException; +import java.net.URI; import java.net.URLEncoder; import java.util.Base64; import java.net.URL; @@ -156,12 +158,40 @@ public List getItemsByCategoryPaginated(String category, Str CouchDbClient dbClient = couchDbClientSupplier.get();//new CouchDbClient(); // or however you're managing it // GET INFO from dbClient - LOG.info(dbClient.getBaseUri().toString()); - LOG.info(dbClient.getBaseUri()); - Gson gson = dbClient.getGson(); - String host = "localhost"; - int port = 5984; + URI baseUri = dbClient.getBaseUri(); + + // Log the base URI to check its structure + LOG.info("Base URI: " + baseUri.toString()); + + // Extract the host and port from the URI + String host = baseUri.getHost(); + int port = baseUri.getPort(); + + LOG.info("Base URI: " + host.toString()); + //LOG.info("Base URI: " + port.toString()); + // If port is not explicitly set, default to 5984 (common CouchDB port) + //if (port == -1) { + // port = 5984; + //} + + + //CouchDbProperties props = dbClient.getCouchDbProperties(); + + String userInfo = baseUri.getUserInfo(); // Returns "admin:admin" + String[] parts = userInfo != null ? userInfo.split(":") : new String[] { "admin", "admin" }; + + String username = parts[0]; + String password = parts.length > 1 ? parts[1] : ""; + LOG.info("Base URI: " + username); + LOG.info("Base URI: " + password); + //String host = props.getHost(); + //int port = props.getPort(); + //String username = props.getUsername(); + //String password = props.getPassword(); + + String authHeader = Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); + String dbName = "adapterinstance"; String designDoc = "paginator"; String viewName = "by_category"; @@ -179,9 +209,15 @@ public List getItemsByCategoryPaginated(String category, Str ); // Auth - String username = "admin"; - String password = "admin"; - String authHeader = Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); + //String username = "admin"; + //String password = "admin"; + + + // Extract the username and password from the dbClient if it's configured for HTTP Basic Authentication + //String username = dbClient.getUsername(); + //String password = dbClient.getPassword(); + + //String authHeader = Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); // HTTP request setup URL url = new URL(urlStr); From b58d16b6efb8b94276904d5c078a721943b5af47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Thu, 18 Sep 2025 11:54:35 +0200 Subject: [PATCH 058/113] Paging works --- .../impl/AdapterInstanceStorageImpl.java | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index b750748440..5fd2a64129 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -151,13 +151,14 @@ public List getAdapterPaginator(String startItem, String end @Override public List getItemsByCategoryPaginated(String category, String startDocId, int limit, boolean descending) { + + // Does not use LightCouchDB, as the current functionality of the URI Parser runs into issues by querying endKey with arrays. + List resultList = new ArrayList<>(); try { - + // Extract the necessary data form the couch DB Instance CouchDbClient dbClient = couchDbClientSupplier.get();//new CouchDbClient(); // or however you're managing it - // GET INFO from dbClient - Gson gson = dbClient.getGson(); URI baseUri = dbClient.getBaseUri(); @@ -167,28 +168,12 @@ public List getItemsByCategoryPaginated(String category, Str // Extract the host and port from the URI String host = baseUri.getHost(); int port = baseUri.getPort(); - - LOG.info("Base URI: " + host.toString()); - //LOG.info("Base URI: " + port.toString()); - // If port is not explicitly set, default to 5984 (common CouchDB port) - //if (port == -1) { - // port = 5984; - //} - - - //CouchDbProperties props = dbClient.getCouchDbProperties(); - String userInfo = baseUri.getUserInfo(); // Returns "admin:admin" + LOG.info(userInfo); String[] parts = userInfo != null ? userInfo.split(":") : new String[] { "admin", "admin" }; String username = parts[0]; String password = parts.length > 1 ? parts[1] : ""; - LOG.info("Base URI: " + username); - LOG.info("Base URI: " + password); - //String host = props.getHost(); - //int port = props.getPort(); - //String username = props.getUsername(); - //String password = props.getPassword(); String authHeader = Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); @@ -199,7 +184,15 @@ public List getItemsByCategoryPaginated(String category, Str // Query parameters - String startKey = URLEncoder.encode("[\"" + category + "\"]", StandardCharsets.UTF_8); + //Check if startDocId exists + String startKey; + if (startDocId != null && !startDocId.isEmpty()) { + startKey = "[\"" + category + "\", \"" + startDocId + "\"]"; +} else { + startKey = "[\"" + category + "\"]"; +} + startKey = URLEncoder.encode(startKey); + //String startKey = URLEncoder.encode("[\"" + category + "\"]", StandardCharsets.UTF_8); String endKey = URLEncoder.encode("[\"" + category + "\", \"\ufff0\"]", StandardCharsets.UTF_8); // Construct full URL @@ -207,17 +200,8 @@ public List getItemsByCategoryPaginated(String category, Str "http://%s:%d/%s/_design/%s/_view/%s?startkey=%s&endkey=%s&limit=%d&include_docs=true", host, port, dbName, designDoc, viewName, startKey, endKey, limit ); - - // Auth - //String username = "admin"; - //String password = "admin"; - - - // Extract the username and password from the dbClient if it's configured for HTTP Basic Authentication - //String username = dbClient.getUsername(); - //String password = dbClient.getPassword(); - - //String authHeader = Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); + LOG.info("StartKey" + startKey.toString()); + LOG.info("urlStr" + urlStr.toString()); // HTTP request setup URL url = new URL(urlStr); From 5a92934023744fbd75072e288fa4017c2b101fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Thu, 18 Sep 2025 13:45:23 +0200 Subject: [PATCH 059/113] UI for category --- .../src/lib/apis/adapter.service.ts | 44 +++++++++++++++++++ .../existing-adapters.component.ts | 41 +++++++++++------ 2 files changed, 72 insertions(+), 13 deletions(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index e13a081842..a653954e7f 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -67,6 +67,20 @@ export class AdapterService { descending, ); } + getAdaptersCategorywisePaginated( + category: string, + startid: string | number | null, + limit: number, + descending: boolean = false, + ): Observable { + return this.requestAdapterCategoryWiseDescriptionsPaginated( + '/master/adapters/paginator/category', + category, + startid, + limit, + descending, + ); + } getAdapter(id: string): Observable { return this.http @@ -85,6 +99,36 @@ export class AdapterService { ); } + requestAdapterCategoryWiseDescriptionsPaginated( + path: string, + category: string, + startid: string | number | null, + limit: number, + descending: boolean, + ): Observable { + let params = new HttpParams().set('limit', limit.toString()); + + params = params.set('category', category); + + console.log('category ', category); + + if (startid) { + params = params.set('startKey', startid); + } + + params = params.set('descending', descending); + const url = `${this.connectPath}${path}`; + console.log(params); + + return this.http.get(url, { params }).pipe( + map(response => { + return (response as any[]).map(p => + AdapterDescription.fromData(p), + ); + }), + ); + } + requestAdapterDescriptionsPaginated( path: string, startid: string | number | null, 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 3c8ac31090..9b7e1afb78 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 @@ -349,6 +349,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { getEndKeyFromFilter(): { endKey: string | null; sortby: string } { let endKey: string | null = null; let sortBy: string; + // TODO DO I still need this ? if (this.filter.value.text != '') { endKey = this.filter.value.text; sortBy = 'name'; @@ -413,21 +414,35 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { console.log('EndKey Fetch Adapter', startKey); console.log('EndKey Fetch Adapter', sortBy); - return this.adapterService - .getAdaptersPaginated( - startKey, - endKey, + if (sortBy == 'category') { + // Unfortunatly needs a different endpoint + const arr = JSON.parse(startKey); + console.log(arr[0]); + console.log(arr[1]); + + return this.adapterService.getAdaptersCategorywisePaginated( + arr[0], + arr[1], pageSize, - sortBy, - this.sort?.direction !== 'asc', - ) - .pipe( - tap(adapters => { - this.existingAdapters = adapters; - this.operationInProgressAdapterId = undefined; - this.getMonitoringInfos(adapters); - }), + false, ); + } else { + return this.adapterService + .getAdaptersPaginated( + startKey, + endKey, + pageSize, + sortBy, + this.sort?.direction !== 'asc', + ) + .pipe( + tap(adapters => { + this.existingAdapters = adapters; + this.operationInProgressAdapterId = undefined; + this.getMonitoringInfos(adapters); + }), + ); + } }; private getSortView(): string { From 67e2bace68fb13f42b6b707ac3d5eed2acadfbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Thu, 18 Sep 2025 14:23:14 +0200 Subject: [PATCH 060/113] category filter seems to work --- .../sp-table-pagination.component.ts | 8 +++++++- .../existing-adapters.component.ts | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 3f790b7c54..5e281bbb87 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -102,6 +102,9 @@ export class SpTablePaginationComponent implements AfterViewInit { this.filter.subscribe(() => { console.log('NEW FIlter Value', this.filter.value); this.filtering = this.filter.value; + if (this.filter.value['category'] != '') { + this.propertyName = this.getViewFn('category'); + } this.resetPagination(); this.loadData(0); }); @@ -138,6 +141,8 @@ export class SpTablePaginationComponent implements AfterViewInit { } loadData(pageIndex: number) { const startkey = this.startKeyMap.get(pageIndex) || null; + console.log('LOAD DARA start key', startkey); + console.log(this.propertyName); this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ next: (data: T[]) => { @@ -150,7 +155,7 @@ export class SpTablePaginationComponent implements AfterViewInit { this.totalItems = data.length + pageIndex * this.pageSize; } - this.last_key = data[data.length - 1][this.propertyName]; + //this.last_key = data[data.length - 1][this.propertyName]; if (data.length > this.pageSize) { let nextStartKey; @@ -168,6 +173,7 @@ export class SpTablePaginationComponent implements AfterViewInit { this.startKeyMap.set(pageIndex + 1, nextStartKeyString); this.dataSource.data = data.slice(0, this.pageSize); } + console.log(this.startKeyMap); }, error: err => { console.error('Failed to fetch paginated data', err); 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 9b7e1afb78..3f98184412 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 @@ -327,7 +327,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } applyFilter(filtering: AdapterFilterSettingsModel) { - console.log(filtering); + console.log('Filtering ', filtering); if (filtering.textFilter != '') { this.filter.next({ text: filtering.textFilter, category: '' }); } @@ -353,13 +353,15 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { if (this.filter.value.text != '') { endKey = this.filter.value.text; sortBy = 'name'; + this.sort.active = ''; } else { if ( this.filter.value.category != '' && this.filter.value.category != 'All' ) { - endKey = '["' + this.filter.value.category + '"'; + //endKey = '["' + this.filter.value.category + '"'; sortBy = 'category'; + this.sort.active = ''; } } @@ -394,6 +396,8 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { let sortBy = this.getSortView(); const filterkeys = this.getEndKeyFromFilter(); + console.log('f startkey', startKey); + let endKey: string | null = null; if (filterkeys.endKey) { @@ -417,6 +421,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { if (sortBy == 'category') { // Unfortunatly needs a different endpoint const arr = JSON.parse(startKey); + console.log(arr); console.log(arr[0]); console.log(arr[1]); @@ -447,7 +452,11 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { private getSortView(): string { // Parse naming of the view - if (this.sort?.active === 'lastModified') { + + console.log(this.sort); + if (this.sort?.active === '') { + return 'category'; + } else if (this.sort?.active === 'lastModified') { return 'createdAt'; } else if (this.sort?.active === 'status') { return 'running'; From 014afe15cc97b8eb103bff8d430e34ddc6e732f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Thu, 18 Sep 2025 14:33:50 +0200 Subject: [PATCH 061/113] small fix in backend for running --- .../impl/AdapterInstanceStorageImpl.java | 38 ++----------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 5fd2a64129..fe7833302e 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -126,7 +126,7 @@ public List getAdapterPaginator(String startItem, String end Object[] startKeyArray = objectMapper.readValue(startItem, Object[].class); LOG.info("Array Start Key"); LOG.info("Array Start Key: " + Arrays.toString(startKeyArray)); - buildCall = buildCall.startKey(startKeyArray[0]); + buildCall = buildCall.startKey(startKeyArray); } catch (IOException e) { throw new IllegalArgumentException("Invalid startItem format for compound key", e); @@ -187,8 +187,10 @@ public List getItemsByCategoryPaginated(String category, Str //Check if startDocId exists String startKey; if (startDocId != null && !startDocId.isEmpty()) { + LOG.info("WE HABE A STARTSD" + startDocId); startKey = "[\"" + category + "\", \"" + startDocId + "\"]"; } else { + LOG.info("OnlyCat" + category); startKey = "[\"" + category + "\"]"; } startKey = URLEncoder.encode(startKey); @@ -250,40 +252,6 @@ public List getItemsByCategoryPaginated(String category, Str } return resultList; - - - - - //String viewName = "paginator/by_category"; - - // Construct start key - //Object[] startKey = (startDocId != null && !startDocId.isEmpty()) - // ? new Object[] { category } // startDocID - // : new Object[] { category }; - - // Construct end key - //Object[] endKey = new Object[] { category, "\ufff0" }; - - //LOG.info("Category: " + category); - //LOG.info("StartDocId: " + startDocId); - //LOG.info("StartKey: " + Arrays.toString(startKey)); - //LOG.info("EndKey: " + Arrays.toString(endKey)); - //LOG.info("Descending: " + descending); - - //var viewQuery = couchDbClientSupplier.get() - // .view(viewName) - // .includeDocs(true) - // .limit(limit) - // .descending(descending) - // .startKey(startKey) - // .endKey(endKey).query(AdapterDescription.class); - - // Manually filter to enforce exact match - //List filtered = viewQuery.stream() - // .filter(doc -> doc.getCategory() != null && doc.getCategory().contains(category)) - // .collect(Collectors.toList()); - - // return filtered; } From 03540105953ad598fbd28d63b6875adf32ab6464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Thu, 18 Sep 2025 16:09:05 +0200 Subject: [PATCH 062/113] paging in category works --- .../sp-table-pagination.component.ts | 23 +++++++++++++++---- .../existing-adapters.component.ts | 7 +++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 5e281bbb87..27623366d0 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -79,7 +79,7 @@ export class SpTablePaginationComponent implements AfterViewInit { isNextDisabled: boolean = false; filtering = ''; - startKeyMap: Map = new Map(); + startKeyMap: Map = new Map(); private sortInitialized = false; @@ -140,9 +140,24 @@ export class SpTablePaginationComponent implements AfterViewInit { this.table.setNoDataRow(this.noDataRow); } loadData(pageIndex: number) { - const startkey = this.startKeyMap.get(pageIndex) || null; - console.log('LOAD DARA start key', startkey); - console.log(this.propertyName); + const start = this.startKeyMap.get(pageIndex) || null; + console.log('LOAD DATA start key', start); + console.log('LOAD DATA Property', this.propertyName); + let startkey = start; + + // Check if propertyName includes 'category' + if ( + startkey == null && + ((typeof this.propertyName === 'string' && + this.propertyName === 'category') || + (Array.isArray(this.propertyName) && + this.propertyName.includes('category'))) + ) { + startkey = '["' + this.filtering['category'] + '"]'; + } + + console.log('LOAD DATA start key', startkey); + console.log('LOAD DATA Property', this.propertyName); this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ next: (data: T[]) => { 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 3f98184412..6957b66110 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 @@ -361,7 +361,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { ) { //endKey = '["' + this.filter.value.category + '"'; sortBy = 'category'; - this.sort.active = ''; + this.sort.active = 'category'; } } @@ -420,6 +420,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { if (sortBy == 'category') { // Unfortunatly needs a different endpoint + const arr = JSON.parse(startKey); console.log(arr); console.log(arr[0]); @@ -453,8 +454,8 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { private getSortView(): string { // Parse naming of the view - console.log(this.sort); - if (this.sort?.active === '') { + console.log('VIEWS FROM SORTING', this.sort); + if (this.sort?.active === 'category') { return 'category'; } else if (this.sort?.active === 'lastModified') { return 'createdAt'; From 08e0059eefb4e1b4e77dbc1c514a18d1e1aa9c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Thu, 18 Sep 2025 16:19:36 +0200 Subject: [PATCH 063/113] DB Credentials from Env --- .../couchdb/impl/AdapterInstanceStorageImpl.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index fe7833302e..ecfd0497ad 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -18,6 +18,7 @@ package org.apache.streampipes.storage.couchdb.impl; +import org.apache.streampipes.commons.environment.Environments; import org.apache.streampipes.model.connect.adapter.AdapterDescription; import org.apache.streampipes.storage.api.IAdapterStorage; import org.apache.streampipes.storage.couchdb.utils.Utils; @@ -168,13 +169,15 @@ public List getItemsByCategoryPaginated(String category, Str // Extract the host and port from the URI String host = baseUri.getHost(); int port = baseUri.getPort(); - String userInfo = baseUri.getUserInfo(); // Returns "admin:admin" - LOG.info(userInfo); - String[] parts = userInfo != null ? userInfo.split(":") : new String[] { "admin", "admin" }; - String username = parts[0]; - String password = parts.length > 1 ? parts[1] : ""; + //String userInfo = baseUri.getUserInfo(); // Returns "admin:admin" + //LOG.info(userInfo); + //String[] parts = userInfo != null ? userInfo.split(":") : new String[] { "admin", "admin" }; + String username = Environments.getEnvironment().getCouchDbUsername().getValueOrDefault();//parts[0]; + String password = Environments.getEnvironment().getCouchDbPassword().getValueOrDefault();//parts[0];//parts.length > 1 ? parts[1] : ""; + LOG.info(username); + LOG.info(password); String authHeader = Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); String dbName = "adapterinstance"; From fc3901cb00cfce8d477a851673ad80f2028bd465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 08:57:51 +0200 Subject: [PATCH 064/113] search working --- .../sp-table-pagination/sp-table-pagination.component.ts | 4 ++++ .../existing-adapters/existing-adapters.component.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 27623366d0..ee449919c1 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -104,6 +104,10 @@ export class SpTablePaginationComponent implements AfterViewInit { this.filtering = this.filter.value; if (this.filter.value['category'] != '') { this.propertyName = this.getViewFn('category'); + } else if (this.filter.value['text'] != '') { + this.propertyName = this.getViewFn('name'); + } else { + this.propertyName = this.getViewFn(''); } this.resetPagination(); this.loadData(0); 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 6957b66110..d1423e1a30 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 @@ -353,7 +353,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { if (this.filter.value.text != '') { endKey = this.filter.value.text; sortBy = 'name'; - this.sort.active = ''; + this.sort.active = 'name'; } else { if ( this.filter.value.category != '' && From 3489caba04991c41daa1983ef61e3280157e44d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 09:02:30 +0200 Subject: [PATCH 065/113] searchbar working --- .../existing-adapters/existing-adapters.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 d1423e1a30..1e7176aeb5 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 @@ -401,7 +401,9 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { let endKey: string | null = null; if (filterkeys.endKey) { - startKey = filterkeys.endKey; + if (startKey == null) { + startKey = filterkeys.endKey; + } if (startKey.startsWith('[')) { startKey = startKey + ']'; } From 1f2db049576344d784b920f3d2abe8046481bbaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 09:20:17 +0200 Subject: [PATCH 066/113] reset working --- .../sp-table-pagination/sp-table-pagination.component.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index ee449919c1..86a6204d0d 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -87,7 +87,12 @@ export class SpTablePaginationComponent implements AfterViewInit { if (changes['sort'] && this.sort && !this.sortInitialized) { this.sort.sortChange.subscribe((sortChange: Sort) => { this.propertyName = this.getViewFn(sortChange.active); + console.log('Changed Triggert'); + console.log(this.propertyName); + this.filter.value['category'] = ''; + this.filter.value['text'] = ''; this.resetPagination(); + this.loadData(0); }); this.sortInitialized = true; } From 3e746e3007dcc49d699ec98ca4fff749aa9e042e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 10:01:21 +0200 Subject: [PATCH 067/113] changes in filter toolbar (only one applicable) --- .../filter-toolbar/filter-toolbar.component.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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 14e5c58927..0cffe5a037 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 @@ -47,7 +47,6 @@ export class SpConnectFilterToolbarComponent implements OnInit { } loadAvailableTypeCategories() { - //TODO THIS IS a TODO this.dataMarketplaceService.getAdapterCategories().subscribe(res => { this.adapterCategories = res; this.adapterCategories.unshift({ @@ -60,11 +59,15 @@ export class SpConnectFilterToolbarComponent implements OnInit { } filterAdapter(event: MatSelectChange) { + // Reset the text filter when a category is selected + this.currentFilter.textFilter = ''; this.filterChangedEmitter.emit(this.currentFilter); } - updateFilterTerm(event: string) { - this.currentFilter.textFilter = event; + updateFilterTerm(term: string) { + // Reset the category filter when text input is used + this.currentFilter.textFilter = term; + this.currentFilter.selectedCategory = 'All'; this.filterChangedEmitter.emit(this.currentFilter); } } From a44b980f7d27d843343961fc5cae7cc37a168d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 10:04:23 +0200 Subject: [PATCH 068/113] everything working? --- .../components/existing-adapters/existing-adapters.component.ts | 1 + 1 file changed, 1 insertion(+) 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 1e7176aeb5..87d9c7a35b 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 @@ -328,6 +328,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { applyFilter(filtering: AdapterFilterSettingsModel) { console.log('Filtering ', filtering); + if (filtering.textFilter != '') { this.filter.next({ text: filtering.textFilter, category: '' }); } From 7620c4c139d2e01c3ab71340f2fe0e7fa684a26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 10:34:34 +0200 Subject: [PATCH 069/113] refactored fetchAdapters --- .../sp-table-pagination.component.ts | 9 ++- .../existing-adapters.component.ts | 70 +++++++------------ 2 files changed, 33 insertions(+), 46 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 86a6204d0d..c1a4e5997b 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -82,12 +82,13 @@ export class SpTablePaginationComponent implements AfterViewInit { startKeyMap: Map = new Map(); private sortInitialized = false; + private filterInitialized = false; ngOnChanges(changes: SimpleChanges): void { if (changes['sort'] && this.sort && !this.sortInitialized) { this.sort.sortChange.subscribe((sortChange: Sort) => { + console.log(); this.propertyName = this.getViewFn(sortChange.active); - console.log('Changed Triggert'); console.log(this.propertyName); this.filter.value['category'] = ''; this.filter.value['text'] = ''; @@ -103,9 +104,11 @@ export class SpTablePaginationComponent implements AfterViewInit { }); } - if (changes.filter) { + if (changes.filter && !this.filterInitialized) { this.filter.subscribe(() => { console.log('NEW FIlter Value', this.filter.value); + this.propertyName = this.sort.active; + console.log(this.propertyName); this.filtering = this.filter.value; if (this.filter.value['category'] != '') { this.propertyName = this.getViewFn('category'); @@ -116,6 +119,8 @@ export class SpTablePaginationComponent implements AfterViewInit { } this.resetPagination(); this.loadData(0); + + this.filterInitialized = true; }); } } 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 87d9c7a35b..6d20e95985 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 @@ -347,27 +347,39 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } } - getEndKeyFromFilter(): { endKey: string | null; sortby: string } { + getStartAndEndKeyFromFilter(startKey): { + startKey: string | null; + endKey: string | null; + } { let endKey: string | null = null; - let sortBy: string; - // TODO DO I still need this ? if (this.filter.value.text != '') { endKey = this.filter.value.text; - sortBy = 'name'; this.sort.active = 'name'; } else { if ( this.filter.value.category != '' && this.filter.value.category != 'All' ) { - //endKey = '["' + this.filter.value.category + '"'; - sortBy = 'category'; this.sort.active = 'category'; } - } + let endKey: string | null = null; + + if (endKey) { + if (startKey == null) { + startKey = endKey; + } + if (startKey.startsWith('[')) { + startKey = startKey + ']'; + } - console.log('FROM FILTERING', endKey); - return { endKey: endKey, sortby: sortBy }; + if (startKey.startsWith('[')) { + endKey = endKey + ',"\ufff0"]'; + } else { + endKey = endKey + '\ufff0'; + } + } + } + return { startKey: startKey, endKey: endKey }; } navigateToDetailsOverviewPage(adapter: AdapterDescription): void { @@ -394,40 +406,12 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { startKey?: string, pageSize?: number, ): Observable => { - let sortBy = this.getSortView(); - const filterkeys = this.getEndKeyFromFilter(); - - console.log('f startkey', startKey); - - let endKey: string | null = null; - - if (filterkeys.endKey) { - if (startKey == null) { - startKey = filterkeys.endKey; - } - if (startKey.startsWith('[')) { - startKey = startKey + ']'; - } - - if (startKey.startsWith('[')) { - endKey = filterkeys.endKey + ',"\ufff0"]'; - } else { - endKey = filterkeys.endKey + '\ufff0'; - } - sortBy = filterkeys.sortby; - } - - console.log('EndKey Fetch Adapter', endKey); - console.log('EndKey Fetch Adapter', startKey); - console.log('EndKey Fetch Adapter', sortBy); - + const { startKey: derivedStartKey, endKey } = + this.getStartAndEndKeyFromFilter(startKey); + const sortBy = this.getSortView(); if (sortBy == 'category') { // Unfortunatly needs a different endpoint - - const arr = JSON.parse(startKey); - console.log(arr); - console.log(arr[0]); - console.log(arr[1]); + const arr = JSON.parse(derivedStartKey); return this.adapterService.getAdaptersCategorywisePaginated( arr[0], @@ -438,7 +422,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } else { return this.adapterService .getAdaptersPaginated( - startKey, + derivedStartKey, endKey, pageSize, sortBy, @@ -456,8 +440,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { private getSortView(): string { // Parse naming of the view - - console.log('VIEWS FROM SORTING', this.sort); if (this.sort?.active === 'category') { return 'category'; } else if (this.sort?.active === 'lastModified') { From 980d91cd2ff85a7ac71732d615943311f5c8e1b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 11:03:19 +0200 Subject: [PATCH 070/113] first part of refactoring pagination ui --- .../sp-table-pagination.component.ts | 15 ++++----------- .../existing-adapters.component.ts | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index c1a4e5997b..4ac96d6c31 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -106,20 +106,10 @@ export class SpTablePaginationComponent implements AfterViewInit { if (changes.filter && !this.filterInitialized) { this.filter.subscribe(() => { - console.log('NEW FIlter Value', this.filter.value); - this.propertyName = this.sort.active; - console.log(this.propertyName); this.filtering = this.filter.value; - if (this.filter.value['category'] != '') { - this.propertyName = this.getViewFn('category'); - } else if (this.filter.value['text'] != '') { - this.propertyName = this.getViewFn('name'); - } else { - this.propertyName = this.getViewFn(''); - } + this.propertyName = this.getViewFn(this.filter.value['view']); this.resetPagination(); this.loadData(0); - this.filterInitialized = true; }); } @@ -161,6 +151,7 @@ export class SpTablePaginationComponent implements AfterViewInit { // Check if propertyName includes 'category' if ( + //TODO Move this to the other component only if else startkey == null && ((typeof this.propertyName === 'string' && this.propertyName === 'category') || @@ -190,10 +181,12 @@ export class SpTablePaginationComponent implements AfterViewInit { let nextStartKey; if (Array.isArray(this.propertyName)) { + console.log('ARRAY'); nextStartKey = this.propertyName.map( prop => data[this.pageSize][prop], ); } else { + console.log('ELSE'); nextStartKey = data[this.pageSize][this.propertyName]; } const nextStartKeyString = Array.isArray(nextStartKey) 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 6d20e95985..1760d326e8 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 @@ -84,9 +84,14 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { isAdmin = false; refreshSwitch = new BehaviorSubject(false); - filter = new BehaviorSubject<{ text: string; category: string }>({ + filter = new BehaviorSubject<{ + text: string; + category: string; + view: string; + }>({ text: '', category: '', + view: '', }); adapterMetrics: Record = {}; @@ -330,7 +335,11 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { console.log('Filtering ', filtering); if (filtering.textFilter != '') { - this.filter.next({ text: filtering.textFilter, category: '' }); + this.filter.next({ + text: filtering.textFilter, + category: '', + view: 'name', + }); } if ( filtering.selectedCategory != '' && @@ -339,11 +348,12 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.filter.next({ text: '', category: filtering.selectedCategory, + view: 'category', }); } if (filtering.selectedCategory == 'All' && filtering.textFilter == '') { - this.filter.next({ text: '', category: '' }); + this.filter.next({ text: '', category: '', view: '' }); } } @@ -354,6 +364,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { let endKey: string | null = null; if (this.filter.value.text != '') { endKey = this.filter.value.text; + this.sort.active = 'name'; } else { if ( From 5ce8c16d4d2880166476bd59065ea9a388524292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 11:14:48 +0200 Subject: [PATCH 071/113] refactoring finished --- .../sp-table-pagination.component.ts | 24 ------------------- .../existing-adapters.component.ts | 11 ++++++--- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 4ac96d6c31..533070df03 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -87,9 +87,7 @@ export class SpTablePaginationComponent implements AfterViewInit { ngOnChanges(changes: SimpleChanges): void { if (changes['sort'] && this.sort && !this.sortInitialized) { this.sort.sortChange.subscribe((sortChange: Sort) => { - console.log(); this.propertyName = this.getViewFn(sortChange.active); - console.log(this.propertyName); this.filter.value['category'] = ''; this.filter.value['text'] = ''; this.resetPagination(); @@ -145,25 +143,8 @@ export class SpTablePaginationComponent implements AfterViewInit { } loadData(pageIndex: number) { const start = this.startKeyMap.get(pageIndex) || null; - console.log('LOAD DATA start key', start); - console.log('LOAD DATA Property', this.propertyName); let startkey = start; - // Check if propertyName includes 'category' - if ( - //TODO Move this to the other component only if else - startkey == null && - ((typeof this.propertyName === 'string' && - this.propertyName === 'category') || - (Array.isArray(this.propertyName) && - this.propertyName.includes('category'))) - ) { - startkey = '["' + this.filtering['category'] + '"]'; - } - - console.log('LOAD DATA start key', startkey); - console.log('LOAD DATA Property', this.propertyName); - this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ next: (data: T[]) => { if (data.length < this.pageSize) { @@ -175,18 +156,14 @@ export class SpTablePaginationComponent implements AfterViewInit { this.totalItems = data.length + pageIndex * this.pageSize; } - //this.last_key = data[data.length - 1][this.propertyName]; - if (data.length > this.pageSize) { let nextStartKey; if (Array.isArray(this.propertyName)) { - console.log('ARRAY'); nextStartKey = this.propertyName.map( prop => data[this.pageSize][prop], ); } else { - console.log('ELSE'); nextStartKey = data[this.pageSize][this.propertyName]; } const nextStartKeyString = Array.isArray(nextStartKey) @@ -195,7 +172,6 @@ export class SpTablePaginationComponent implements AfterViewInit { this.startKeyMap.set(pageIndex + 1, nextStartKeyString); this.dataSource.data = data.slice(0, this.pageSize); } - console.log(this.startKeyMap); }, error: err => { console.error('Failed to fetch paginated data', err); 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 1760d326e8..1ff9b24930 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 @@ -332,8 +332,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } applyFilter(filtering: AdapterFilterSettingsModel) { - console.log('Filtering ', filtering); - if (filtering.textFilter != '') { this.filter.next({ text: filtering.textFilter, @@ -357,11 +355,13 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } } - getStartAndEndKeyFromFilter(startKey): { + getStartAndEndKeyFromFilter(startKeyOrg): { startKey: string | null; endKey: string | null; } { let endKey: string | null = null; + let startKey = startKeyOrg; + if (this.filter.value.text != '') { endKey = this.filter.value.text; @@ -372,7 +372,12 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.filter.value.category != 'All' ) { this.sort.active = 'category'; + + if (startKey == null) { + startKey = '["' + this.filter.value.category + '"]'; + } } + let endKey: string | null = null; if (endKey) { From 9aa9a3ba80f120ae0916aa1f3235b43bf028b426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 11:21:26 +0200 Subject: [PATCH 072/113] refactored ng --- .../sp-table-pagination.component.ts | 60 ++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 533070df03..038dcedd29 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -86,33 +86,53 @@ export class SpTablePaginationComponent implements AfterViewInit { ngOnChanges(changes: SimpleChanges): void { if (changes['sort'] && this.sort && !this.sortInitialized) { - this.sort.sortChange.subscribe((sortChange: Sort) => { - this.propertyName = this.getViewFn(sortChange.active); - this.filter.value['category'] = ''; - this.filter.value['text'] = ''; - this.resetPagination(); - this.loadData(0); - }); - this.sortInitialized = true; + this.initSortSubscription(); } - if (changes.refresh) { - this.refresh.subscribe(() => { - this.loadData(this.currentPage); - }); + if (changes['refresh']) { + this.initRefreshSubscription(); } - if (changes.filter && !this.filterInitialized) { - this.filter.subscribe(() => { - this.filtering = this.filter.value; - this.propertyName = this.getViewFn(this.filter.value['view']); - this.resetPagination(); - this.loadData(0); - this.filterInitialized = true; - }); + if (changes['filter'] && !this.filterInitialized) { + this.initFilterSubscription(); } } + private initSortSubscription(): void { + this.sort.sortChange.subscribe(sortChange => + this.updateSort(sortChange), + ); + this.sortInitialized = true; + } + + private initRefreshSubscription(): void { + this.refresh?.subscribe(() => { + this.loadData(this.currentPage); + }); + } + + private initFilterSubscription(): void { + this.filter?.subscribe(() => { + this.filtering = this.filter.value; + this.propertyName = this.getViewFn(this.filter.value['view']); + this.resetPagination(); + this.loadData(0); + this.filterInitialized = true; + }); + } + + private updateSort(sortChange: Sort): void { + this.propertyName = this.getViewFn(sortChange.active); + this.clearFilters(); + this.resetPagination(); + this.loadData(0); + } + + private clearFilters(): void { + this.filter.value['category'] = ''; + this.filter.value['text'] = ''; + } + ngAfterViewInit() { this.loadData(0); } From 084f9915ad7e17e92498e06d8ebf7d0019cfc444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 11:27:39 +0200 Subject: [PATCH 073/113] small fix in refactoring --- .../existing-adapters/existing-adapters.component.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 1ff9b24930..ba5eaa4a59 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 @@ -363,7 +363,10 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { let startKey = startKeyOrg; if (this.filter.value.text != '') { - endKey = this.filter.value.text; + if (startKey == null) { + startKey = this.filter.value.text; + } + endKey = this.filter.value.text + '\ufff0'; this.sort.active = 'name'; } else { From caec7f282130b25e049bdbd460ff95b9756dd2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 11:42:21 +0200 Subject: [PATCH 074/113] finished refactoring --- .../existing-adapters.component.ts | 97 +++++++++++-------- 1 file changed, 54 insertions(+), 43 deletions(-) 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 ba5eaa4a59..59eb1885d3 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 @@ -318,7 +318,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { return elementIds.has(a.elementId); } }); - //this.dataSource.data = this.filteredAdapters; } startAdapterTutorial() { @@ -331,74 +330,82 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { }); } - applyFilter(filtering: AdapterFilterSettingsModel) { - if (filtering.textFilter != '') { + applyFilter(filtering: AdapterFilterSettingsModel): void { + if (filtering.textFilter) { this.filter.next({ text: filtering.textFilter, category: '', view: 'name', }); + return; } if ( - filtering.selectedCategory != '' && - filtering.selectedCategory != 'All' + filtering.selectedCategory && + filtering.selectedCategory !== 'All' ) { this.filter.next({ text: '', category: filtering.selectedCategory, view: 'category', }); + return; } + this.filter.next({ text: '', category: '', view: '' }); + } - if (filtering.selectedCategory == 'All' && filtering.textFilter == '') { - this.filter.next({ text: '', category: '', view: '' }); + private buildRangeForTextFilter( + text: string, + startKey: string | null, + ): { + startKey: string | null; + endKey: string | null; + } { + if (!startKey || startKey == null) { + startKey = text; } + const endKey = text + '\ufff0'; + this.sort.active = 'name'; + return { startKey, endKey }; } - getStartAndEndKeyFromFilter(startKeyOrg): { + private buildRangeForCategoryFilter( + category: string, + startKey: string | null, + ): { startKey: string | null; endKey: string | null; } { - let endKey: string | null = null; - let startKey = startKeyOrg; - - if (this.filter.value.text != '') { - if (startKey == null) { - startKey = this.filter.value.text; - } - endKey = this.filter.value.text + '\ufff0'; + this.sort.active = 'category'; - this.sort.active = 'name'; - } else { - if ( - this.filter.value.category != '' && - this.filter.value.category != 'All' - ) { - this.sort.active = 'category'; - - if (startKey == null) { - startKey = '["' + this.filter.value.category + '"]'; - } - } + if (!startKey) { + startKey = `["${category}"]`; + } - let endKey: string | null = null; + const endKey = startKey.startsWith('[') + ? startKey.slice(0, -1) + ', "\ufff0"]' + : startKey + '\ufff0'; - if (endKey) { - if (startKey == null) { - startKey = endKey; - } - if (startKey.startsWith('[')) { - startKey = startKey + ']'; - } + return { startKey, endKey }; + } - if (startKey.startsWith('[')) { - endKey = endKey + ',"\ufff0"]'; - } else { - endKey = endKey + '\ufff0'; - } - } + getStartAndEndKeyFromFilter(startKeyOrg: string | null): { + startKey: string | null; + endKey: string | null; + } { + const filterValue = this.filter.value; + console.log('FIlterValue', filterValue); + const startKey = startKeyOrg; + + if (filterValue.text) { + return this.buildRangeForTextFilter(filterValue.text, startKey); + } else if (filterValue.category && filterValue.category !== 'All') { + return this.buildRangeForCategoryFilter( + filterValue.category, + startKey, + ); } - return { startKey: startKey, endKey: endKey }; + + return { startKey, endKey: null }; } navigateToDetailsOverviewPage(adapter: AdapterDescription): void { @@ -428,6 +435,10 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { const { startKey: derivedStartKey, endKey } = this.getStartAndEndKeyFromFilter(startKey); const sortBy = this.getSortView(); + + console.log(sortBy); + console.log(endKey); + console.log(startKey); if (sortBy == 'category') { // Unfortunatly needs a different endpoint const arr = JSON.parse(derivedStartKey); From e9d3ed76ea0209b67153dea713d65377072f84fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 13:15:13 +0200 Subject: [PATCH 075/113] start and stop button --- .../existing-adapters.component.ts | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) 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 59eb1885d3..0cca568b65 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 @@ -104,6 +104,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { startAdapterErrorText = 'Could not start adapter'; stopAdapterErrorText = 'Could not stop adapter'; + allAdapters: AdapterDescription[] = []; constructor( private cdRef: ChangeDetectorRef, private adapterService: AdapterService, @@ -186,7 +187,38 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { return active; } - startAllAdapters(action: boolean) { + private getAllAdapters(): Observable { + return this.adapterService.getAdapters().pipe( + tap(adapters => { + this.allAdapters = adapters; + this.operationInProgressAdapterId = undefined; + this.getMonitoringInfos(adapters); + }), + ); + } + + startAllAdapters(action: boolean): void { + this.getAllAdapters().subscribe(allAdapters => { + const dialogRef: DialogRef = + this.dialogService.open(AllAdapterActionsComponent, { + panelType: PanelType.STANDARD_PANEL, + title: (action ? 'Start' : 'Stop') + ' all adapters', + width: '70vw', + data: { + adapters: allAdapters, + action: action, + }, + }); + + dialogRef.afterClosed().subscribe(data => { + if (data) { + this.getAdaptersRunning(); + } + }); + }); + } + + startAdapters(action: boolean) { const dialogRef: DialogRef = this.dialogService.open(AllAdapterActionsComponent, { panelType: PanelType.STANDARD_PANEL, @@ -393,7 +425,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { endKey: string | null; } { const filterValue = this.filter.value; - console.log('FIlterValue', filterValue); const startKey = startKeyOrg; if (filterValue.text) { @@ -436,9 +467,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.getStartAndEndKeyFromFilter(startKey); const sortBy = this.getSortView(); - console.log(sortBy); - console.log(endKey); - console.log(startKey); if (sortBy == 'category') { // Unfortunatly needs a different endpoint const arr = JSON.parse(derivedStartKey); From 1fbac4c10e39bf713e950a390e9f294ea478877c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 13:20:02 +0200 Subject: [PATCH 076/113] removed error --- .../platform-services/src/lib/apis/adapter.service.ts | 1 - .../sp-table-pagination/sp-table-pagination.component.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index a653954e7f..0a2da72015 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -57,7 +57,6 @@ export class AdapterService { property: string = 'createdAt', descending: boolean = false, ): Observable { - console.log('Property', property); return this.requestAdapterDescriptionsPaginated( '/master/adapters/paginator', startid, diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 038dcedd29..b671d7a5e1 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -140,7 +140,7 @@ export class SpTablePaginationComponent implements AfterViewInit { this.startKeyMap.clear(); this.currentPage = 0; this.last_key = null; - this.paginator.firstPage(); + this.paginator?.firstPage(); this.loadData(this.currentPage); this.isNextDisabled = false; this.totalItems = 1000000; From fcfbab95f02928ff9c6f8697f9b5772d4d13356e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 13:26:05 +0200 Subject: [PATCH 077/113] deleted logger --- .../impl/AdapterInstanceStorageImpl.java | 181 ++++++++---------- 1 file changed, 76 insertions(+), 105 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index ecfd0497ad..c8cb2effc9 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -121,12 +121,8 @@ public List getAdapterPaginator(String startItem, String end } } else if (startItem.startsWith("[") && startItem.endsWith("]")) { try { - // Assuming the startItem is a JSON array in string form - LOG.info("Starting Object Thinf"); ObjectMapper objectMapper = new ObjectMapper(); Object[] startKeyArray = objectMapper.readValue(startItem, Object[].class); - LOG.info("Array Start Key"); - LOG.info("Array Start Key: " + Arrays.toString(startKeyArray)); buildCall = buildCall.startKey(startKeyArray); } catch (IOException e) { @@ -138,12 +134,8 @@ public List getAdapterPaginator(String startItem, String end } if (endItem != null && !endItem.isEmpty()) { - - LOG.info("added end key"); - LOG.info(endItem); - buildCall = buildCall.endKey(endItem); - - } + buildCall = buildCall.endKey(endItem); + } return buildCall .descending(descending) @@ -151,111 +143,90 @@ public List getAdapterPaginator(String startItem, String end } @Override -public List getItemsByCategoryPaginated(String category, String startDocId, int limit, boolean descending) { - - // Does not use LightCouchDB, as the current functionality of the URI Parser runs into issues by querying endKey with arrays. - - List resultList = new ArrayList<>(); - - try { - // Extract the necessary data form the couch DB Instance - CouchDbClient dbClient = couchDbClientSupplier.get();//new CouchDbClient(); // or however you're managing it - Gson gson = dbClient.getGson(); - URI baseUri = dbClient.getBaseUri(); - - // Log the base URI to check its structure - LOG.info("Base URI: " + baseUri.toString()); - - // Extract the host and port from the URI - String host = baseUri.getHost(); - int port = baseUri.getPort(); - - //String userInfo = baseUri.getUserInfo(); // Returns "admin:admin" - //LOG.info(userInfo); - //String[] parts = userInfo != null ? userInfo.split(":") : new String[] { "admin", "admin" }; - - String username = Environments.getEnvironment().getCouchDbUsername().getValueOrDefault();//parts[0]; - String password = Environments.getEnvironment().getCouchDbPassword().getValueOrDefault();//parts[0];//parts.length > 1 ? parts[1] : ""; - LOG.info(username); - LOG.info(password); - String authHeader = Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); - - String dbName = "adapterinstance"; - String designDoc = "paginator"; - String viewName = "by_category"; - - - - // Query parameters - //Check if startDocId exists - String startKey; - if (startDocId != null && !startDocId.isEmpty()) { - LOG.info("WE HABE A STARTSD" + startDocId); - startKey = "[\"" + category + "\", \"" + startDocId + "\"]"; -} else { - LOG.info("OnlyCat" + category); - startKey = "[\"" + category + "\"]"; -} - startKey = URLEncoder.encode(startKey); - //String startKey = URLEncoder.encode("[\"" + category + "\"]", StandardCharsets.UTF_8); - String endKey = URLEncoder.encode("[\"" + category + "\", \"\ufff0\"]", StandardCharsets.UTF_8); - - // Construct full URL - String urlStr = String.format( - "http://%s:%d/%s/_design/%s/_view/%s?startkey=%s&endkey=%s&limit=%d&include_docs=true", - host, port, dbName, designDoc, viewName, startKey, endKey, limit - ); - LOG.info("StartKey" + startKey.toString()); - LOG.info("urlStr" + urlStr.toString()); - - // HTTP request setup - URL url = new URL(urlStr); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - conn.setRequestProperty("Authorization", "Basic " + authHeader); - conn.setConnectTimeout(5000); - conn.setReadTimeout(5000); - - int responseCode = conn.getResponseCode(); - if (responseCode != HttpURLConnection.HTTP_OK) { - throw new RuntimeException("Failed with HTTP code: " + responseCode); - } + public List getItemsByCategoryPaginated(String category, String startDocId, int limit, + boolean descending) { + + // Does not use LightCouchDB, as the current functionality of the URI Parser + // runs into issues by querying endKey with arrays. + + List resultList = new ArrayList<>(); + + try { + CouchDbClient dbClient = couchDbClientSupplier.get(); + Gson gson = dbClient.getGson(); + URI baseUri = dbClient.getBaseUri(); + String host = baseUri.getHost(); + int port = baseUri.getPort(); + String username = Environments.getEnvironment().getCouchDbUsername().getValueOrDefault(); + String password = Environments.getEnvironment().getCouchDbPassword().getValueOrDefault(); + String authHeader = Base64.getEncoder() + .encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); + String dbName = "adapterinstance"; + String designDoc = "paginator"; + String viewName = "by_category"; + + String startKey; + if (startDocId != null && !startDocId.isEmpty()) { + startKey = "[\"" + category + "\", \"" + startDocId + "\"]"; + } else { + LOG.info("OnlyCat" + category); + startKey = "[\"" + category + "\"]"; + } + startKey = URLEncoder.encode(startKey); - // ✅ Parse response using Gson - try (Reader reader = new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)) { - JsonObject root = JsonParser.parseReader(reader).getAsJsonObject(); + String endKey = URLEncoder.encode("[\"" + category + "\", \"\ufff0\"]", StandardCharsets.UTF_8); - if (root.has("rows")) { - JsonArray rows = root.getAsJsonArray("rows"); + String urlStr = String.format( + "http://%s:%d/%s/_design/%s/_view/%s?startkey=%s&endkey=%s&limit=%d&include_docs=true", + host, port, dbName, designDoc, viewName, startKey, endKey, limit); - for (JsonElement rowElem : rows) { - JsonObject rowObj = rowElem.getAsJsonObject(); - JsonElement docElem = rowObj.get("doc"); + // HTTP request setup + URL url = new URL(urlStr); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setRequestProperty("Authorization", "Basic " + authHeader); + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); - if (docElem != null && !docElem.isJsonNull()) { - // Optional: enforce @class for polymorphic deserialization if needed - docElem.getAsJsonObject().addProperty("@class", "org.apache.streampipes.model.connect.adapter.AdapterDescription"); + int responseCode = conn.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_OK) { + throw new RuntimeException("Failed with HTTP code: " + responseCode); + } - AdapterDescription adapter = gson.fromJson(docElem, AdapterDescription.class); - resultList.add(adapter); + try (Reader reader = new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)) { + JsonObject root = JsonParser.parseReader(reader).getAsJsonObject(); + + if (root.has("rows")) { + JsonArray rows = root.getAsJsonArray("rows"); + + for (JsonElement rowElem : rows) { + JsonObject rowObj = rowElem.getAsJsonObject(); + JsonElement docElem = rowObj.get("doc"); + + if (docElem != null && !docElem.isJsonNull()) { + // Optional: enforce @class for polymorphic deserialization if needed + docElem.getAsJsonObject().addProperty("@class", + "org.apache.streampipes.model.connect.adapter.AdapterDescription"); + + AdapterDescription adapter = gson.fromJson(docElem, AdapterDescription.class); + resultList.add(adapter); + } } } } - } - } catch (IOException e) { - System.err.println("I/O error during CouchDB request: " + e.getMessage()); - e.printStackTrace(); - } catch (RuntimeException e) { - System.err.println("Runtime exception: " + e.getMessage()); - e.printStackTrace(); - } catch (Exception e) { - System.err.println("Unexpected exception: " + e.getMessage()); - e.printStackTrace(); - } + } catch (IOException e) { + System.err.println("I/O error during CouchDB request: " + e.getMessage()); + e.printStackTrace(); + } catch (RuntimeException e) { + System.err.println("Runtime exception: " + e.getMessage()); + e.printStackTrace(); + } catch (Exception e) { + System.err.println("Unexpected exception: " + e.getMessage()); + e.printStackTrace(); + } - return resultList; + return resultList; } - } From 0b3b2c5ac311754fe51e76f2fad9d0f1ee3ae8b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 13:29:46 +0200 Subject: [PATCH 078/113] eliminated Logs in Backend --- .../couchdb/impl/AdapterInstanceStorageImpl.java | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index c8cb2effc9..69832ddf86 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -35,29 +35,21 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URI; -import java.net.URLEncoder; -import java.util.Base64; import java.net.URL; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Base64; import java.util.List; import java.util.NoSuchElementException; -import java.util.stream.Collectors; public class AdapterInstanceStorageImpl extends DefaultCrudStorage implements IAdapterStorage { - private static final Logger LOG = LoggerFactory.getLogger(AdapterInstanceStorageImpl.class.getCanonicalName()); public AdapterInstanceStorageImpl() { super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); @@ -94,8 +86,6 @@ public List getAdapterPaginator(String startItem, String end long startItemLong = 0L; // default value String uri = "paginator/by_" + view; - LOG.info(startItem); - if (startItem == null || startItem.isEmpty()) { return couchDbClientSupplier .get() @@ -129,7 +119,6 @@ public List getAdapterPaginator(String startItem, String end throw new IllegalArgumentException("Invalid startItem format for compound key", e); } } else { - LOG.info(startItem); buildCall = buildCall.startKey(startItem); } @@ -169,7 +158,6 @@ public List getItemsByCategoryPaginated(String category, Str if (startDocId != null && !startDocId.isEmpty()) { startKey = "[\"" + category + "\", \"" + startDocId + "\"]"; } else { - LOG.info("OnlyCat" + category); startKey = "[\"" + category + "\"]"; } startKey = URLEncoder.encode(startKey); From daac59d7e0792e5bb254ec83c051f1a50316e356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 13:33:18 +0200 Subject: [PATCH 079/113] save before backend refactoring --- .../storage/couchdb/impl/AdapterInstanceStorageImpl.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 69832ddf86..dfe23623a8 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -22,13 +22,11 @@ import org.apache.streampipes.model.connect.adapter.AdapterDescription; import org.apache.streampipes.storage.api.IAdapterStorage; import org.apache.streampipes.storage.couchdb.utils.Utils; + import org.lightcouch.CouchDbClient; -import org.lightcouch.CouchDbProperties; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; + import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; From 1c36928405713a21eff6337448740f94df1ddefc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 13:38:09 +0200 Subject: [PATCH 080/113] refactoring in backend seems to be working --- .../impl/AdapterInstanceStorageImpl.java | 211 +++++++++--------- 1 file changed, 107 insertions(+), 104 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index dfe23623a8..a1bf9d98c5 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -24,6 +24,7 @@ import org.apache.streampipes.storage.couchdb.utils.Utils; import org.lightcouch.CouchDbClient; +import org.lightcouch.View; import com.fasterxml.jackson.databind.ObjectMapper; @@ -36,6 +37,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; +import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; @@ -48,7 +50,6 @@ public class AdapterInstanceStorageImpl extends DefaultCrudStorage implements IAdapterStorage { - public AdapterInstanceStorageImpl() { super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); } @@ -81,124 +82,61 @@ public List findAll() { @Override public List getAdapterPaginator(String startItem, String endItem, int limit, String view, boolean descending) { - long startItemLong = 0L; // default value String uri = "paginator/by_" + view; + var dbClient = couchDbClientSupplier.get(); + var viewBuilder = dbClient.view(uri) + .includeDocs(true) + .limit(limit) + .descending(descending); - if (startItem == null || startItem.isEmpty()) { - return couchDbClientSupplier - .get() - .view(uri) - .includeDocs(true) - .limit(limit) - .descending(descending) - .query(AdapterDescription.class); + if (startItem != null && !startItem.isEmpty()) { + viewBuilder = applyStartKey(viewBuilder, view, startItem); } - var buildCall = couchDbClientSupplier - .get() - .view(uri) - .includeDocs(true) - .limit(limit); - - if ("createdAt".equals(view)) { - try { - startItemLong = Long.parseLong(startItem); - buildCall = buildCall.startKey(startItemLong); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid startItem format for 'createdAt'", e); + if (endItem != null && !endItem.isEmpty()) { + viewBuilder = viewBuilder.endKey(endItem); + } + + return viewBuilder.query(AdapterDescription.class); + } + + private View applyStartKey(View viewBuilder, String view, String startItem) { + try { + if ("createdAt".equals(view)) { + long startItemLong = Long.parseLong(startItem); + return viewBuilder.startKey(startItemLong); } - } else if (startItem.startsWith("[") && startItem.endsWith("]")) { - try { - ObjectMapper objectMapper = new ObjectMapper(); - Object[] startKeyArray = objectMapper.readValue(startItem, Object[].class); - buildCall = buildCall.startKey(startKeyArray); - - } catch (IOException e) { - throw new IllegalArgumentException("Invalid startItem format for compound key", e); + + if (startItem.startsWith("[") && startItem.endsWith("]")) { + ObjectMapper mapper = new ObjectMapper(); + Object[] startKeyArray = mapper.readValue(startItem, Object[].class); + return viewBuilder.startKey(startKeyArray); } - } else { - buildCall = buildCall.startKey(startItem); - } - if (endItem != null && !endItem.isEmpty()) { - buildCall = buildCall.endKey(endItem); - } + return viewBuilder.startKey(startItem); - return buildCall - .descending(descending) - .query(AdapterDescription.class); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid startItem format for 'createdAt'", e); + } catch (IOException e) { + throw new IllegalArgumentException("Invalid startItem format for compound key", e); + } } @Override - public List getItemsByCategoryPaginated(String category, String startDocId, int limit, - boolean descending) { - - // Does not use LightCouchDB, as the current functionality of the URI Parser - // runs into issues by querying endKey with arrays. - + public List getItemsByCategoryPaginated(String category, String startDocId, + int limit, boolean descending) { List resultList = new ArrayList<>(); try { - CouchDbClient dbClient = couchDbClientSupplier.get(); - Gson gson = dbClient.getGson(); - URI baseUri = dbClient.getBaseUri(); - String host = baseUri.getHost(); - int port = baseUri.getPort(); - String username = Environments.getEnvironment().getCouchDbUsername().getValueOrDefault(); - String password = Environments.getEnvironment().getCouchDbPassword().getValueOrDefault(); - String authHeader = Base64.getEncoder() - .encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); - String dbName = "adapterinstance"; - String designDoc = "paginator"; - String viewName = "by_category"; - - String startKey; - if (startDocId != null && !startDocId.isEmpty()) { - startKey = "[\"" + category + "\", \"" + startDocId + "\"]"; - } else { - startKey = "[\"" + category + "\"]"; - } - startKey = URLEncoder.encode(startKey); - - String endKey = URLEncoder.encode("[\"" + category + "\", \"\ufff0\"]", StandardCharsets.UTF_8); - - String urlStr = String.format( - "http://%s:%d/%s/_design/%s/_view/%s?startkey=%s&endkey=%s&limit=%d&include_docs=true", - host, port, dbName, designDoc, viewName, startKey, endKey, limit); + String url = buildCategoryPaginatedUrl(category, startDocId, limit); + HttpURLConnection conn = createAuthenticatedConnection(url); - // HTTP request setup - URL url = new URL(urlStr); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - conn.setRequestProperty("Authorization", "Basic " + authHeader); - conn.setConnectTimeout(5000); - conn.setReadTimeout(5000); - - int responseCode = conn.getResponseCode(); - if (responseCode != HttpURLConnection.HTTP_OK) { - throw new RuntimeException("Failed with HTTP code: " + responseCode); + if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { + throw new RuntimeException("Failed with HTTP code: " + conn.getResponseCode()); } try (Reader reader = new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)) { - JsonObject root = JsonParser.parseReader(reader).getAsJsonObject(); - - if (root.has("rows")) { - JsonArray rows = root.getAsJsonArray("rows"); - - for (JsonElement rowElem : rows) { - JsonObject rowObj = rowElem.getAsJsonObject(); - JsonElement docElem = rowObj.get("doc"); - - if (docElem != null && !docElem.isJsonNull()) { - // Optional: enforce @class for polymorphic deserialization if needed - docElem.getAsJsonObject().addProperty("@class", - "org.apache.streampipes.model.connect.adapter.AdapterDescription"); - - AdapterDescription adapter = gson.fromJson(docElem, AdapterDescription.class); - resultList.add(adapter); - } - } - } + resultList = parseAdapterDescriptions(reader, couchDbClientSupplier.get().getGson()); } } catch (IOException e) { @@ -207,12 +145,77 @@ public List getItemsByCategoryPaginated(String category, Str } catch (RuntimeException e) { System.err.println("Runtime exception: " + e.getMessage()); e.printStackTrace(); - } catch (Exception e) { - System.err.println("Unexpected exception: " + e.getMessage()); - e.printStackTrace(); } return resultList; } + private String buildCategoryPaginatedUrl(String category, String startDocId, int limit) + throws UnsupportedEncodingException { + String dbName = "adapterinstance"; + String designDoc = "paginator"; + String viewName = "by_category"; + + String startKey = startDocId != null && !startDocId.isEmpty() + ? "[\"" + category + "\", \"" + startDocId + "\"]" + : "[\"" + category + "\"]"; + + String endKey = "[\"" + category + "\", \"\ufff0\"]"; + + CouchDbClient dbClient = couchDbClientSupplier.get(); + URI baseUri = dbClient.getBaseUri(); + + return String.format( + "http://%s:%d/%s/_design/%s/_view/%s?startkey=%s&endkey=%s&limit=%d&include_docs=true", + baseUri.getHost(), + baseUri.getPort(), + dbName, + designDoc, + viewName, + URLEncoder.encode(startKey, StandardCharsets.UTF_8), + URLEncoder.encode(endKey, StandardCharsets.UTF_8), + limit); + } + + private HttpURLConnection createAuthenticatedConnection(String urlStr) throws IOException { + URL url = new URL(urlStr); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + + String username = Environments.getEnvironment().getCouchDbUsername().getValueOrDefault(); + String password = Environments.getEnvironment().getCouchDbPassword().getValueOrDefault(); + String authHeader = Base64.getEncoder() + .encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); + + conn.setRequestMethod("GET"); + conn.setRequestProperty("Authorization", "Basic " + authHeader); + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); + + return conn; + } + + private List parseAdapterDescriptions(Reader reader, Gson gson) { + List result = new ArrayList<>(); + JsonObject root = JsonParser.parseReader(reader).getAsJsonObject(); + + if (root.has("rows")) { + JsonArray rows = root.getAsJsonArray("rows"); + + for (JsonElement rowElem : rows) { + JsonObject rowObj = rowElem.getAsJsonObject(); + JsonElement docElem = rowObj.get("doc"); + + if (docElem != null && !docElem.isJsonNull()) { + docElem.getAsJsonObject().addProperty("@class", + "org.apache.streampipes.model.connect.adapter.AdapterDescription"); + + AdapterDescription adapter = gson.fromJson(docElem, AdapterDescription.class); + result.add(adapter); + } + } + } + + return result; + } + } From 2ea8fee853efc8ac59abfd42717ca5fa2a691740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 13:40:10 +0200 Subject: [PATCH 081/113] eliminated last print --- .../platform-services/src/lib/apis/adapter.service.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index 0a2da72015..289756d32b 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -109,15 +109,12 @@ export class AdapterService { params = params.set('category', category); - console.log('category ', category); - if (startid) { params = params.set('startKey', startid); } params = params.set('descending', descending); const url = `${this.connectPath}${path}`; - console.log(params); return this.http.get(url, { params }).pipe( map(response => { From 5d55a8cd5500f9df9dd380937e39f86916dab732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 13:48:55 +0200 Subject: [PATCH 082/113] minor --- .../apache/streampipes/storage/api/IAdapterStorage.java | 8 +++++--- .../storage/couchdb/impl/AdapterInstanceStorageImpl.java | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java index 7c579b2df5..877be16082 100644 --- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java +++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IAdapterStorage.java @@ -28,7 +28,9 @@ public interface IAdapterStorage extends CRUDStorage { List getAdaptersByAppId(String appId); - List getAdapterPaginator(String startItem, String endItem, int limit, String view, boolean descending); - List getItemsByCategoryPaginated(String category, String startDocId, int limit, - boolean descending); + List getAdapterPaginator(String startItem, String endItem, int limit, String view, + boolean descending); + + List getItemsByCategoryPaginated(String category, String startDocId, + int limit, boolean descending); } diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index a1bf9d98c5..b110978d23 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -23,16 +23,16 @@ import org.apache.streampipes.storage.api.IAdapterStorage; import org.apache.streampipes.storage.couchdb.utils.Utils; -import org.lightcouch.CouchDbClient; -import org.lightcouch.View; - import com.fasterxml.jackson.databind.ObjectMapper; - import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import org.lightcouch.CouchDbClient; +import org.lightcouch.View; + + import java.io.IOException; import java.io.InputStreamReader; From bf272507f162ec68a3276549cb4ff50985a9d5c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 13:56:52 +0200 Subject: [PATCH 083/113] mvn succesful --- .../couchdb/impl/AdapterDescriptionStorageImpl.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java index 28a2329f0c..5e38cebe7e 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterDescriptionStorageImpl.java @@ -61,8 +61,16 @@ private String getCurrentRev(String elementId) { } @Override - public List getAdapterPaginator(String startitem, int limit, String view, boolean descending) { + public List getAdapterPaginator(String startItem, String endItem, int limit, String view, + boolean descending) { // TODO Auto-generated method stub throw new UnsupportedOperationException("Unimplemented method 'getAdapterPaginator'"); } + + @Override + public List getItemsByCategoryPaginated(String category, String startDocId, int limit, + boolean descending) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getItemsByCategoryPaginated'"); + } } From 71d9e411e7a1b608d2b37caf1937949f8459419d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 14:26:06 +0200 Subject: [PATCH 084/113] fix going beack to all --- .../existing-adapters.component.ts | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) 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 0cca568b65..f99abb2dcc 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 @@ -382,6 +382,16 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { }); return; } + + if (filtering.selectedCategory && filtering.selectedCategory == 'All') { + this.sort.active = 'createdAt'; + this.filter.next({ + text: '', + category: '', + view: 'createdAt', + }); + return; + } this.filter.next({ text: '', category: '', view: '' }); } @@ -426,14 +436,18 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } { const filterValue = this.filter.value; const startKey = startKeyOrg; - - if (filterValue.text) { + if (filterValue.text != '') { return this.buildRangeForTextFilter(filterValue.text, startKey); - } else if (filterValue.category && filterValue.category !== 'All') { + } else if ( + filterValue.category != '' && + filterValue.category !== 'All' + ) { return this.buildRangeForCategoryFilter( filterValue.category, startKey, ); + } else if (filterValue.category == 'All') { + this.sort.active = ''; } return { startKey, endKey: null }; From a58ed05e9f2bdc5d0d9ebca5c77d3a51ec8b7155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 14:30:32 +0200 Subject: [PATCH 085/113] fixed category issue --- .../existing-adapters.component.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) 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 f99abb2dcc..6431440c6e 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 @@ -384,13 +384,15 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } if (filtering.selectedCategory && filtering.selectedCategory == 'All') { - this.sort.active = 'createdAt'; - this.filter.next({ - text: '', - category: '', - view: 'createdAt', - }); - return; + if (this.sort.active === 'category') { + this.sort.active = 'createdAt'; + } + //this.filter.next({ + // text: '', + // category: '', + // view: 'createdAt', + //}); + //return; } this.filter.next({ text: '', category: '', view: '' }); } From ed89132b5a1a0b747f84df8cc9f1ec2ba7fab50d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 14:40:04 +0200 Subject: [PATCH 086/113] fixed search field to ascending --- .../existing-adapters/existing-adapters.component.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) 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 6431440c6e..0408d26266 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 @@ -387,12 +387,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { if (this.sort.active === 'category') { this.sort.active = 'createdAt'; } - //this.filter.next({ - // text: '', - // category: '', - // view: 'createdAt', - //}); - //return; } this.filter.next({ text: '', category: '', view: '' }); } @@ -409,6 +403,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } const endKey = text + '\ufff0'; this.sort.active = 'name'; + this.sort.direction = 'asc'; return { startKey, endKey }; } From 2b34cb28a1861d4b22642966576cbf2feb06b934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Fri, 19 Sep 2025 14:41:36 +0200 Subject: [PATCH 087/113] added a comment --- .../components/existing-adapters/existing-adapters.component.ts | 1 + 1 file changed, 1 insertion(+) 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 0408d26266..75f2386f3a 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 @@ -403,6 +403,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } const endKey = text + '\ufff0'; this.sort.active = 'name'; + // Search Field only works if asc this.sort.direction = 'asc'; return { startKey, endKey }; } From 751eb82de7111d04961071d99b2bf111f763b244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 08:42:52 +0200 Subject: [PATCH 088/113] added wait to goToConnect --- .../support/utils/connect/ConnectUtils.ts | 14 ++++- .../tests/connect/adapterPaging.spec.ts | 57 +++++++++++++++++++ .../connect/compact/addCompactAdapter.spec.ts | 3 +- 3 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 ui/cypress/tests/connect/adapterPaging.spec.ts diff --git a/ui/cypress/support/utils/connect/ConnectUtils.ts b/ui/cypress/support/utils/connect/ConnectUtils.ts index 4841a01e19..8bbfb47dab 100644 --- a/ui/cypress/support/utils/connect/ConnectUtils.ts +++ b/ui/cypress/support/utils/connect/ConnectUtils.ts @@ -105,27 +105,35 @@ export class ConnectUtils { .setName(name) .addInput('input', 'wait-time-ms', '1000'); + console.log('Step 1 Done'); + if (persist) { builder.setTimestampProperty('timestamp').setStoreInDataLake(); } const configuration = builder.build(); - + console.log('Step 1 Build done'); ConnectUtils.goToConnect(); - + console.log('DO to connect Done'); ConnectUtils.goToNewAdapterPage(); + console.log('New Adapter'); ConnectUtils.selectAdapter(configuration.adapterType); + console.log('select'); ConnectUtils.configureAdapter(configuration); - + console.log('configure'); ConnectEventSchemaUtils.finishEventSchemaConfiguration(); + console.log('Schema'); ConnectUtils.startAdapter(configuration); + console.log('Start'); } public static goToConnect() { cy.visit('#/connect'); + cy.dataCy('all-adapters-table', { timeout: 15000 }) // Increase timeout if needed + .should('exist'); // Wait for the element to exist in the DOM } public static goToNewAdapterPage() { diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts new file mode 100644 index 0000000000..0903da2809 --- /dev/null +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -0,0 +1,57 @@ +/* + * 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 { ConnectUtils } from '../../support/utils/connect/ConnectUtils'; +import { ConnectBtns } from '../../support/utils/connect/ConnectBtns'; +import { CompactAdapterUtils } from '../../support/utils/connect/CompactAdapterUtils'; + +describe('Adapter Paging Test', () => { + beforeEach('Setup Test', () => { + // To set up test, we are adding 2 stream adapters that can be further configured + //TODO compactAdapter + cy.initStreamPipesTest(); + //cy.login(); // Comment this in and the line above out to disable a clean setup + console.log('Add a simulator'); + ConnectUtils.addMachineDataSimulator('simulator-1'); + + //Generate 5 Adapters + //for (let i = 0; i < 5; i++) { + // const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() + // .build(); + + //CompactAdapterUtils.storeCompactAdapter(compactAdapter) + //} + + // One Adapter running for testing purposes + + //const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() + // .setStart() + // .build(); + + //CompactAdapterUtils.storeCompactAdapter(compactAdapter) + }); + + it('Basic Paging check', () => { + ConnectUtils.goToConnect(); + // set the paging to 5 items + + // calculate list of items on page 1 + + // calculate lust of items on page 2 + }); +}); diff --git a/ui/cypress/tests/connect/compact/addCompactAdapter.spec.ts b/ui/cypress/tests/connect/compact/addCompactAdapter.spec.ts index 57d2466c15..ddb7ab9c36 100644 --- a/ui/cypress/tests/connect/compact/addCompactAdapter.spec.ts +++ b/ui/cypress/tests/connect/compact/addCompactAdapter.spec.ts @@ -27,12 +27,13 @@ describe('Add Compact Adapters', () => { }); it('Add an adapter via the compact API. Do not start', () => { + console.log('Start ADD Adapter'); const compactAdapter = CompactAdapterUtils.getMachineDataSimulator().build(); + console.log('Adapter built'); CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(() => { ConnectUtils.validateAdapterIsStopped(); - PipelineUtils.checkAmountOfPipelinesPipeline(0); }); }); From 1892cb3b86cd6856585c6e0fcf64738ed4d3ccf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 08:44:59 +0200 Subject: [PATCH 089/113] small change in simulator endpoint --- ui/cypress/support/utils/connect/CompactAdapterUtils.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/cypress/support/utils/connect/CompactAdapterUtils.ts b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts index 43757f580c..59fb68afdb 100644 --- a/ui/cypress/support/utils/connect/CompactAdapterUtils.ts +++ b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts @@ -70,11 +70,13 @@ export class CompactAdapterUtils { /** * Creates a CompactAdapterBuilder instance configured for a machine data simulator. */ - public static getMachineDataSimulator(): CompactAdapterBuilder { + public static getMachineDataSimulator( + name: string = 'Test', + ): CompactAdapterBuilder { return CompactAdapterBuilder.create( 'org.apache.streampipes.connect.iiot.adapters.simulator.machine', ) - .setName('Test') + .setName(name) .addConfiguration('wait-time-ms', '1000') .addConfiguration('selected-simulator-option', 'flowrate'); } From bcde2ed2879b8a88f9ffc69117c35815823ad2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 10:08:11 +0200 Subject: [PATCH 090/113] first pagination test runs --- .../support/general/resetStreamPipes.ts | 1 + .../utils/connect/CompactAdapterUtils.ts | 1 + .../tests/connect/adapterPaging.spec.ts | 76 ++++++++++++++----- .../sp-table-pagination.component.html | 1 + 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/ui/cypress/support/general/resetStreamPipes.ts b/ui/cypress/support/general/resetStreamPipes.ts index 4d6eac8503..2f79ac9cd4 100644 --- a/ui/cypress/support/general/resetStreamPipes.ts +++ b/ui/cypress/support/general/resetStreamPipes.ts @@ -25,6 +25,7 @@ declare global { } export const resetStreamPipes = () => { + console.log(window.localStorage.getItem('auth-token')); cy.request({ method: 'POST', url: '/streampipes-backend/api/v2/reset', diff --git a/ui/cypress/support/utils/connect/CompactAdapterUtils.ts b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts index 59fb68afdb..2a07bd8705 100644 --- a/ui/cypress/support/utils/connect/CompactAdapterUtils.ts +++ b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts @@ -54,6 +54,7 @@ export class CompactAdapterUtils { failOnStatusCode = true, ) { const token = window.localStorage.getItem('auth-token'); + console.log(token); return cy.request({ method: 'POST', url: '/streampipes-backend/api/v2/connect/compact-adapters', diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index 0903da2809..fb27bf07ba 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -22,36 +22,70 @@ import { CompactAdapterUtils } from '../../support/utils/connect/CompactAdapterU describe('Adapter Paging Test', () => { beforeEach('Setup Test', () => { - // To set up test, we are adding 2 stream adapters that can be further configured - //TODO compactAdapter + // Initialize the StreamPipes test and wait for token to be available cy.initStreamPipesTest(); - //cy.login(); // Comment this in and the line above out to disable a clean setup - console.log('Add a simulator'); - ConnectUtils.addMachineDataSimulator('simulator-1'); + //TODO Add token working in here - //Generate 5 Adapters - //for (let i = 0; i < 5; i++) { + // Optionally, you can add one adapter running for testing purposes // const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() - // .build(); - - //CompactAdapterUtils.storeCompactAdapter(compactAdapter) - //} - - // One Adapter running for testing purposes - - //const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() - // .setStart() - // .build(); - - //CompactAdapterUtils.storeCompactAdapter(compactAdapter) + // .setStart() + // .build(); + // CompactAdapterUtils.storeCompactAdapter(compactAdapter); }); it('Basic Paging check', () => { + // Generate 5 Adapters + for (let i = 0; i < 10; i++) { + const compactAdapter = CompactAdapterUtils.getMachineDataSimulator( + 'test_' + i, + ).build(); + + CompactAdapterUtils.storeCompactAdapter(compactAdapter); + } + ConnectUtils.goToConnect(); // set the paging to 5 items - // calculate list of items on page 1 + cy.dataCy('table-paginator').within(() => { + // Click the page size selector (usually a ) + cy.get('mat-select').click(); + }); + + // Click the option with value "5" + cy.get('mat-option').contains('5').click(); + + // assert if it actually only shows 5 items + cy.get('[data-cy="adapter-name"]').should('have.length', 5); - // calculate lust of items on page 2 + // Click on Next + + cy.get('[data-cy="table-paginator"]') + .find('button[aria-label="Next"]') + .click(); + + // Wait for updated data (for example, by checking that first row is different) + //cy.get('table.mat-table') + // .find('tr[mat-row]') + // .first() + // .find('td.mat-cell') + // .eq(0) + // .should('not.contain.text', 'First row from previous page'); + + // calculate lust of items on page 2 and validate + cy.get('[data-cy="adapter-name"]').should('have.length', 4); }); + + it('Basic Filtering CreatedAT', () => { + // cy.get('table.mat-table') + // .find('tr[mat-row]') + // .first() + // .find('td.mat-cell') + // .eq(0) // First column (0-based index) + // .should('contain.text', 'Expected Value'); + }); + + it('Basic Filtering Name', () => {}); + + it('Basic Filtering Running', () => {}); + it('Basic Filtering Category', () => {}); }); diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html index 5cae91d411..a7ef8ec932 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.html @@ -35,6 +35,7 @@
Date: Mon, 22 Sep 2025 10:15:01 +0200 Subject: [PATCH 091/113] inbetween save --- ui/cypress/support/general/resetStreamPipes.ts | 1 - ui/cypress/tests/connect/adapterPaging.spec.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/cypress/support/general/resetStreamPipes.ts b/ui/cypress/support/general/resetStreamPipes.ts index 2f79ac9cd4..4d6eac8503 100644 --- a/ui/cypress/support/general/resetStreamPipes.ts +++ b/ui/cypress/support/general/resetStreamPipes.ts @@ -25,7 +25,6 @@ declare global { } export const resetStreamPipes = () => { - console.log(window.localStorage.getItem('auth-token')); cy.request({ method: 'POST', url: '/streampipes-backend/api/v2/reset', diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index fb27bf07ba..65fbea9360 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -72,7 +72,7 @@ describe('Adapter Paging Test', () => { // .should('not.contain.text', 'First row from previous page'); // calculate lust of items on page 2 and validate - cy.get('[data-cy="adapter-name"]').should('have.length', 4); + //cy.get('[data-cy="adapter-name"]').should('have.length', 4); }); it('Basic Filtering CreatedAT', () => { From c118b0b9c7c63a2d4970ef3d1940f58a92bfcc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 10:23:10 +0200 Subject: [PATCH 092/113] draft first test --- .../utils/connect/CompactAdapterUtils.ts | 1 - .../tests/connect/adapterPaging.spec.ts | 36 +++++++++++++------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/ui/cypress/support/utils/connect/CompactAdapterUtils.ts b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts index 2a07bd8705..59fb68afdb 100644 --- a/ui/cypress/support/utils/connect/CompactAdapterUtils.ts +++ b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts @@ -54,7 +54,6 @@ export class CompactAdapterUtils { failOnStatusCode = true, ) { const token = window.localStorage.getItem('auth-token'); - console.log(token); return cy.request({ method: 'POST', url: '/streampipes-backend/api/v2/connect/compact-adapters', diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index 65fbea9360..29627c6c17 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -34,7 +34,6 @@ describe('Adapter Paging Test', () => { }); it('Basic Paging check', () => { - // Generate 5 Adapters for (let i = 0; i < 10; i++) { const compactAdapter = CompactAdapterUtils.getMachineDataSimulator( 'test_' + i, @@ -44,24 +43,39 @@ describe('Adapter Paging Test', () => { } ConnectUtils.goToConnect(); - // set the paging to 5 items - cy.dataCy('table-paginator').within(() => { - // Click the page size selector (usually a ) cy.get('mat-select').click(); }); - - // Click the option with value "5" cy.get('mat-option').contains('5').click(); - - // assert if it actually only shows 5 items cy.get('[data-cy="adapter-name"]').should('have.length', 5); + cy.get('[data-cy="adapter-name"]') + .first() + .invoke('text') + .then(firstPageFirstItem => { + cy.get('[data-cy="adapter-name"]').should('have.length', 5); + cy.get('[data-cy="table-paginator"]') + .find('button[aria-label="Next"]') + .should('not.be.disabled') + .click(); + + cy.wait(10000); + cy.get('[data-cy="adapter-name"]') + .first() + .should('exist') + .invoke('text') + .should(secondPageFirstItem => { + expect(secondPageFirstItem.trim()).to.not.equal( + firstPageFirstItem.trim(), + ); + }); + }); + // Click on Next - cy.get('[data-cy="table-paginator"]') - .find('button[aria-label="Next"]') - .click(); + //cy.get('[data-cy="table-paginator"]') + // .find('button[aria-label="Next"]') + // .click(); // Wait for updated data (for example, by checking that first row is different) //cy.get('table.mat-table') From a0a5e21d53d403f445870748e12d1a9cf4907505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 11:34:19 +0200 Subject: [PATCH 093/113] eliminated some logs --- .../utils/connect/CompactAdapterUtils.ts | 13 ++ .../support/utils/connect/ConnectUtils.ts | 33 +++-- .../tests/connect/adapterPaging.spec.ts | 119 +++++++++--------- 3 files changed, 96 insertions(+), 69 deletions(-) diff --git a/ui/cypress/support/utils/connect/CompactAdapterUtils.ts b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts index 59fb68afdb..98e9de0910 100644 --- a/ui/cypress/support/utils/connect/CompactAdapterUtils.ts +++ b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts @@ -80,4 +80,17 @@ export class CompactAdapterUtils { .addConfiguration('wait-time-ms', '1000') .addConfiguration('selected-simulator-option', 'flowrate'); } + + public static getAndSaveNMachineDataSimulator( + name: string = 'Test', + n: number = 10, + ): void { + for (let i = 0; i < n; i++) { + const compactAdapter = CompactAdapterUtils.getMachineDataSimulator( + 'test_' + i, + ).build(); + + CompactAdapterUtils.storeCompactAdapter(compactAdapter); + } + } } diff --git a/ui/cypress/support/utils/connect/ConnectUtils.ts b/ui/cypress/support/utils/connect/ConnectUtils.ts index 8bbfb47dab..cd26f00390 100644 --- a/ui/cypress/support/utils/connect/ConnectUtils.ts +++ b/ui/cypress/support/utils/connect/ConnectUtils.ts @@ -112,22 +112,12 @@ export class ConnectUtils { } const configuration = builder.build(); - console.log('Step 1 Build done'); ConnectUtils.goToConnect(); - console.log('DO to connect Done'); ConnectUtils.goToNewAdapterPage(); - console.log('New Adapter'); - ConnectUtils.selectAdapter(configuration.adapterType); - console.log('select'); - ConnectUtils.configureAdapter(configuration); - console.log('configure'); ConnectEventSchemaUtils.finishEventSchemaConfiguration(); - console.log('Schema'); - ConnectUtils.startAdapter(configuration); - console.log('Start'); } public static goToConnect() { @@ -452,6 +442,29 @@ export class ConnectUtils { ConnectBtns.stopAdapter().should('have.length', 1); } + public static validateAdapterPagination() { + cy.get('[data-cy="adapter-name"]') + .first() + .invoke('text') + .then(firstPageFirstItem => { + cy.get('[data-cy="adapter-name"]').should('have.length', 5); + cy.get('[data-cy="table-paginator"]') + .find('button[aria-label="Next"]') + .should('not.be.disabled') + .click(); + + cy.get('[data-cy="adapter-name"]') + .first() + .should('exist') + .invoke('text') + .should(secondPageFirstItem => { + expect(secondPageFirstItem.trim()).to.not.equal( + firstPageFirstItem.trim(), + ); + }); + }); + } + public static validateAdapterIsStopped() { ConnectUtils.goToConnect(); ConnectBtns.startAdapter().should('have.length', 1); diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index 29627c6c17..6dca6e61bb 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -22,83 +22,84 @@ import { CompactAdapterUtils } from '../../support/utils/connect/CompactAdapterU describe('Adapter Paging Test', () => { beforeEach('Setup Test', () => { - // Initialize the StreamPipes test and wait for token to be available cy.initStreamPipesTest(); - //TODO Add token working in here - - // Optionally, you can add one adapter running for testing purposes - // const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() - // .setStart() - // .build(); - // CompactAdapterUtils.storeCompactAdapter(compactAdapter); }); it('Basic Paging check', () => { - for (let i = 0; i < 10; i++) { - const compactAdapter = CompactAdapterUtils.getMachineDataSimulator( - 'test_' + i, - ).build(); - - CompactAdapterUtils.storeCompactAdapter(compactAdapter); - } - + //CompactAdapterUtils.getAndSaveNMachineDataSimulator() ConnectUtils.goToConnect(); cy.dataCy('table-paginator').within(() => { cy.get('mat-select').click(); }); cy.get('mat-option').contains('5').click(); cy.get('[data-cy="adapter-name"]').should('have.length', 5); + ConnectUtils.validateAdapterPagination(); + }); - cy.get('[data-cy="adapter-name"]') - .first() - .invoke('text') - .then(firstPageFirstItem => { - cy.get('[data-cy="adapter-name"]').should('have.length', 5); - cy.get('[data-cy="table-paginator"]') - .find('button[aria-label="Next"]') - .should('not.be.disabled') - .click(); + //it('Basic Filtering CreatedAT', () => { + // Click on filter - cy.wait(10000); - cy.get('[data-cy="adapter-name"]') - .first() - .should('exist') - .invoke('text') - .should(secondPageFirstItem => { - expect(secondPageFirstItem.trim()).to.not.equal( - firstPageFirstItem.trim(), - ); - }); - }); + // Click Again - // Click on Next + // cy.get('table.mat-table') + // .find('tr[mat-row]') + // .first() + // .find('td.mat-cell') + // .eq(0) // First column (0-based index) + // .should('contain.text', 'Expected Value'); + //}); - //cy.get('[data-cy="table-paginator"]') - // .find('button[aria-label="Next"]') - // .click(); + it('Basic Filtering Name', () => { + ConnectUtils.goToConnect(); + cy.get('th[mat-sort-header=""] .mat-sort-header-content', { + timeout: 10000, + }) + .contains('Name') // Make sure we're targeting the "Name" column + .should('be.visible') // Wait until it's visible + .click(); // Click to sort by 'Name' + // Wait for sorting to complete (you could adjust or replace this with a more reliable method) + cy.wait(500); - // Wait for updated data (for example, by checking that first row is different) - //cy.get('table.mat-table') - // .find('tr[mat-row]') - // .first() - // .find('td.mat-cell') - // .eq(0) - // .should('not.contain.text', 'First row from previous page'); + // Get the first row's data before sorting + cy.get('table.mat-table') + .find('tr.mat-row') + .first() + .within(() => { + cy.get('[data-cy="adapter-name"]').then($name => { + const firstItemNameBefore = $name.text(); // Save the name of the first item + cy.log('First item before sorting: ' + firstItemNameBefore); - // calculate lust of items on page 2 and validate - //cy.get('[data-cy="adapter-name"]').should('have.length', 4); - }); + // Click the sort header for 'Name' column again (if it sorts in both directions) + cy.get('th[mat-sort-header=""] .mat-sort-header-content') + .contains('Name') + .click(); - it('Basic Filtering CreatedAT', () => { - // cy.get('table.mat-table') - // .find('tr[mat-row]') - // .first() - // .find('td.mat-cell') - // .eq(0) // First column (0-based index) - // .should('contain.text', 'Expected Value'); - }); + // Wait for sorting to complete again + cy.wait(500); - it('Basic Filtering Name', () => {}); + // Get the first row again after sorting + cy.get('table.mat-table') + .find('tr.mat-row') + .first() + .within(() => { + cy.get('[data-cy="adapter-name"]').then( + $newName => { + const firstItemNameAfter = $newName.text(); // Save the name of the new first item + cy.log( + 'First item after sorting: ' + + firstItemNameAfter, + ); + + // Assert that the first item name has changed + expect(firstItemNameBefore).to.not.equal( + firstItemNameAfter, + ); + }, + ); + }); + }); + }); + }); it('Basic Filtering Running', () => {}); it('Basic Filtering Category', () => {}); From 0914a7411f7e9c503f86c858975701cfa4853cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 11:41:18 +0200 Subject: [PATCH 094/113] filter is running --- .../tests/connect/adapterPaging.spec.ts | 66 +++++++++---------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index 6dca6e61bb..e0e7af8ecb 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -51,53 +51,47 @@ describe('Adapter Paging Test', () => { it('Basic Filtering Name', () => { ConnectUtils.goToConnect(); + + // Ensure that the sort header for 'Name' is visible and click it cy.get('th[mat-sort-header=""] .mat-sort-header-content', { timeout: 10000, }) - .contains('Name') // Make sure we're targeting the "Name" column + .contains('Name') // Ensure we are targeting the "Name" column .should('be.visible') // Wait until it's visible .click(); // Click to sort by 'Name' - // Wait for sorting to complete (you could adjust or replace this with a more reliable method) - cy.wait(500); - // Get the first row's data before sorting - cy.get('table.mat-table') - .find('tr.mat-row') + // Wait for sorting to complete + cy.wait(500); // You can adjust or replace this with a more reliable method if needed + + // Get the first item's name before sorting + cy.get('[data-cy="adapter-name"]') .first() - .within(() => { - cy.get('[data-cy="adapter-name"]').then($name => { - const firstItemNameBefore = $name.text(); // Save the name of the first item - cy.log('First item before sorting: ' + firstItemNameBefore); + .invoke('text') + .then(firstItemNameBefore => { + cy.log('First item before sorting: ' + firstItemNameBefore); - // Click the sort header for 'Name' column again (if it sorts in both directions) - cy.get('th[mat-sort-header=""] .mat-sort-header-content') - .contains('Name') - .click(); + // Click the sort header for 'Name' column again (if sorting in both directions) + cy.get('th[mat-sort-header=""] .mat-sort-header-content') + .contains('Name') + .click(); - // Wait for sorting to complete again - cy.wait(500); + // Wait for sorting to complete again + cy.wait(500); - // Get the first row again after sorting - cy.get('table.mat-table') - .find('tr.mat-row') - .first() - .within(() => { - cy.get('[data-cy="adapter-name"]').then( - $newName => { - const firstItemNameAfter = $newName.text(); // Save the name of the new first item - cy.log( - 'First item after sorting: ' + - firstItemNameAfter, - ); + // Get the first item's name after sorting + cy.get('[data-cy="adapter-name"]') + .first() + .invoke('text') + .then(firstItemNameAfter => { + cy.log( + 'First item after sorting: ' + firstItemNameAfter, + ); - // Assert that the first item name has changed - expect(firstItemNameBefore).to.not.equal( - firstItemNameAfter, - ); - }, - ); - }); - }); + // Assert that the first item name has changed + expect(firstItemNameBefore.trim()).to.not.equal( + firstItemNameAfter.trim(), + ); + }); }); }); From d4003a8e260a381b37e13e45383c1bf1c971c18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 11:46:12 +0200 Subject: [PATCH 095/113] clean up --- .../support/utils/connect/ConnectUtils.ts | 28 ++++++++++++ .../tests/connect/adapterPaging.spec.ts | 43 +------------------ 2 files changed, 29 insertions(+), 42 deletions(-) diff --git a/ui/cypress/support/utils/connect/ConnectUtils.ts b/ui/cypress/support/utils/connect/ConnectUtils.ts index cd26f00390..e21e88eae0 100644 --- a/ui/cypress/support/utils/connect/ConnectUtils.ts +++ b/ui/cypress/support/utils/connect/ConnectUtils.ts @@ -465,6 +465,34 @@ export class ConnectUtils { }); } + public static filterAdapterPagination(name: string) { + cy.get('th[mat-sort-header=""] .mat-sort-header-content', { + timeout: 10000, + }) + .contains(name) + .should('be.visible') + .click(); + cy.wait(500); + cy.get('[data-cy="adapter-name"]') + .first() + .invoke('text') + .then(firstItemNameBefore => { + cy.get('th[mat-sort-header=""] .mat-sort-header-content') + .contains(name) + .click(); + + cy.wait(500); + + cy.get('[data-cy="adapter-name"]') + .first() + .invoke('text') + .then(firstItemNameAfter => { + expect(firstItemNameBefore.trim()).to.not.equal( + firstItemNameAfter.trim(), + ); + }); + }); + } public static validateAdapterIsStopped() { ConnectUtils.goToConnect(); ConnectBtns.startAdapter().should('have.length', 1); diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index e0e7af8ecb..b98f9346f6 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -51,48 +51,7 @@ describe('Adapter Paging Test', () => { it('Basic Filtering Name', () => { ConnectUtils.goToConnect(); - - // Ensure that the sort header for 'Name' is visible and click it - cy.get('th[mat-sort-header=""] .mat-sort-header-content', { - timeout: 10000, - }) - .contains('Name') // Ensure we are targeting the "Name" column - .should('be.visible') // Wait until it's visible - .click(); // Click to sort by 'Name' - - // Wait for sorting to complete - cy.wait(500); // You can adjust or replace this with a more reliable method if needed - - // Get the first item's name before sorting - cy.get('[data-cy="adapter-name"]') - .first() - .invoke('text') - .then(firstItemNameBefore => { - cy.log('First item before sorting: ' + firstItemNameBefore); - - // Click the sort header for 'Name' column again (if sorting in both directions) - cy.get('th[mat-sort-header=""] .mat-sort-header-content') - .contains('Name') - .click(); - - // Wait for sorting to complete again - cy.wait(500); - - // Get the first item's name after sorting - cy.get('[data-cy="adapter-name"]') - .first() - .invoke('text') - .then(firstItemNameAfter => { - cy.log( - 'First item after sorting: ' + firstItemNameAfter, - ); - - // Assert that the first item name has changed - expect(firstItemNameBefore.trim()).to.not.equal( - firstItemNameAfter.trim(), - ); - }); - }); + ConnectUtils.filterAdapterPagination('Name'); }); it('Basic Filtering Running', () => {}); From abde46503a4c013a06ee277d9526a03965955a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 13:24:43 +0200 Subject: [PATCH 096/113] eliminated a load --- .../support/utils/connect/ConnectUtils.ts | 11 ++--- .../tests/connect/adapterPaging.spec.ts | 47 +++++++++++++------ .../sp-table-pagination.component.ts | 8 ++-- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/ui/cypress/support/utils/connect/ConnectUtils.ts b/ui/cypress/support/utils/connect/ConnectUtils.ts index e21e88eae0..9403c550bf 100644 --- a/ui/cypress/support/utils/connect/ConnectUtils.ts +++ b/ui/cypress/support/utils/connect/ConnectUtils.ts @@ -453,6 +453,8 @@ export class ConnectUtils { .should('not.be.disabled') .click(); + cy.wait(500); + cy.get('[data-cy="adapter-name"]') .first() .should('exist') @@ -466,13 +468,6 @@ export class ConnectUtils { } public static filterAdapterPagination(name: string) { - cy.get('th[mat-sort-header=""] .mat-sort-header-content', { - timeout: 10000, - }) - .contains(name) - .should('be.visible') - .click(); - cy.wait(500); cy.get('[data-cy="adapter-name"]') .first() .invoke('text') @@ -481,7 +476,7 @@ export class ConnectUtils { .contains(name) .click(); - cy.wait(500); + cy.wait(1000); cy.get('[data-cy="adapter-name"]') .first() diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index b98f9346f6..646238d243 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -28,32 +28,51 @@ describe('Adapter Paging Test', () => { it('Basic Paging check', () => { //CompactAdapterUtils.getAndSaveNMachineDataSimulator() ConnectUtils.goToConnect(); + cy.wait(1000); cy.dataCy('table-paginator').within(() => { cy.get('mat-select').click(); }); cy.get('mat-option').contains('5').click(); + cy.wait(1000); + cy.get('[data-cy="adapter-name"]').should('have.length', 5); ConnectUtils.validateAdapterPagination(); }); - //it('Basic Filtering CreatedAT', () => { - // Click on filter - - // Click Again - - // cy.get('table.mat-table') - // .find('tr[mat-row]') - // .first() - // .find('td.mat-cell') - // .eq(0) // First column (0-based index) - // .should('contain.text', 'Expected Value'); - //}); - it('Basic Filtering Name', () => { ConnectUtils.goToConnect(); + cy.wait(1000); + + cy.get('th[mat-sort-header=""] .mat-sort-header-content', { + timeout: 10000, + }) + .contains('Name') + .should('be.visible') + .click(); + cy.wait(1000); ConnectUtils.filterAdapterPagination('Name'); }); - it('Basic Filtering Running', () => {}); + it('Basic Filtering CreatedAT', () => { + ConnectUtils.goToConnect(); + cy.wait(1000); + ConnectUtils.filterAdapterPagination('Created'); + }); + + it('Basic Filtering Running', () => { + // TODO Add One Item as running + ConnectUtils.goToConnect(); + + cy.wait(1000); + + cy.get('th[mat-sort-header=""] .mat-sort-header-content', { + timeout: 10000, + }) + .contains('Status') + .should('be.visible') + .click(); + cy.wait(1000); + ConnectUtils.filterAdapterPagination('Status'); + }); it('Basic Filtering Category', () => {}); }); diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index b671d7a5e1..6a17e6bb91 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -45,7 +45,7 @@ import { BehaviorSubject } from 'rxjs'; styleUrls: ['./sp-table-pagination.component.scss'], standalone: false, }) -export class SpTablePaginationComponent implements AfterViewInit { +export class SpTablePaginationComponent { @ContentChildren(MatHeaderRowDef) headerRowDefs: QueryList; @ContentChildren(MatRowDef) rowDefs: QueryList>; @ContentChildren(MatColumnDef) columnDefs: QueryList; @@ -133,9 +133,9 @@ export class SpTablePaginationComponent implements AfterViewInit { this.filter.value['text'] = ''; } - ngAfterViewInit() { - this.loadData(0); - } + //ngAfterViewInit() { + // this.loadData(0); + //} resetPagination() { this.startKeyMap.clear(); this.currentPage = 0; From 77660d8cc6cafe1773b272b1b79cbaa5c8006289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 13:50:17 +0200 Subject: [PATCH 097/113] small fix in paging component (added defautls) --- .../sp-table-pagination.component.ts | 19 ++++++++++++++----- .../existing-adapters.component.ts | 7 ++++--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index 6a17e6bb91..ba82063d0d 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -83,13 +83,14 @@ export class SpTablePaginationComponent { private sortInitialized = false; private filterInitialized = false; + private refreshInitialized = false; ngOnChanges(changes: SimpleChanges): void { if (changes['sort'] && this.sort && !this.sortInitialized) { this.initSortSubscription(); } - if (changes['refresh']) { + if (changes['refresh'] && !this.refreshInitialized) { this.initRefreshSubscription(); } @@ -109,20 +110,23 @@ export class SpTablePaginationComponent { this.refresh?.subscribe(() => { this.loadData(this.currentPage); }); + this.refreshInitialized = true; } private initFilterSubscription(): void { this.filter?.subscribe(() => { this.filtering = this.filter.value; this.propertyName = this.getViewFn(this.filter.value['view']); + console.log('Property Name from FIlter', this.propertyName); this.resetPagination(); this.loadData(0); - this.filterInitialized = true; }); + this.filterInitialized = true; } private updateSort(sortChange: Sort): void { this.propertyName = this.getViewFn(sortChange.active); + console.log('Property Name from Update Sort', this.propertyName); this.clearFilters(); this.resetPagination(); this.loadData(0); @@ -133,9 +137,6 @@ export class SpTablePaginationComponent { this.filter.value['text'] = ''; } - //ngAfterViewInit() { - // this.loadData(0); - //} resetPagination() { this.startKeyMap.clear(); this.currentPage = 0; @@ -147,6 +148,7 @@ export class SpTablePaginationComponent { } onPageChange(event: PageEvent) { this.pageSize = event.pageSize; + console.log('Page Size Change', this.pageSize); this.currentPage = event.pageIndex; this.loadData(this.currentPage); } @@ -164,6 +166,7 @@ export class SpTablePaginationComponent { loadData(pageIndex: number) { const start = this.startKeyMap.get(pageIndex) || null; let startkey = start; + console.log(start); this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ next: (data: T[]) => { @@ -176,8 +179,12 @@ export class SpTablePaginationComponent { this.totalItems = data.length + pageIndex * this.pageSize; } + console.log('page from fetch', this.pageSize); + console.log(data.length); + if (data.length > this.pageSize) { let nextStartKey; + console.log('DATA', this.propertyName); if (Array.isArray(this.propertyName)) { nextStartKey = this.propertyName.map( @@ -185,6 +192,7 @@ export class SpTablePaginationComponent { ); } else { nextStartKey = data[this.pageSize][this.propertyName]; + console.log(nextStartKey); } const nextStartKeyString = Array.isArray(nextStartKey) ? JSON.stringify(nextStartKey) @@ -192,6 +200,7 @@ export class SpTablePaginationComponent { this.startKeyMap.set(pageIndex + 1, nextStartKeyString); this.dataSource.data = data.slice(0, this.pageSize); } + console.log(this.startKeyMap); }, error: err => { console.error('Failed to fetch paginated data', err); 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 75f2386f3a..3faf4233bc 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 @@ -91,7 +91,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { }>({ text: '', category: '', - view: '', + view: 'createdAt', }); adapterMetrics: Record = {}; @@ -388,7 +388,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.sort.active = 'createdAt'; } } - this.filter.next({ text: '', category: '', view: '' }); + this.filter.next({ text: '', category: '', view: 'createdAt' }); } private buildRangeForTextFilter( @@ -445,7 +445,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { startKey, ); } else if (filterValue.category == 'All') { - this.sort.active = ''; + this.sort.active = 'createdAt'; } return { startKey, endKey: null }; @@ -478,6 +478,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { const { startKey: derivedStartKey, endKey } = this.getStartAndEndKeyFromFilter(startKey); const sortBy = this.getSortView(); + console.log('SortBY', sortBy); if (sortBy == 'category') { // Unfortunatly needs a different endpoint From d754af2ee2dbced6114668edb840051ed32f6881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 14:18:47 +0200 Subject: [PATCH 098/113] test running except running --- ui/cypress/support/utils/connect/ConnectUtils.ts | 8 ++++---- ui/cypress/tests/connect/adapterPaging.spec.ts | 2 +- .../existing-adapters/existing-adapters.component.ts | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ui/cypress/support/utils/connect/ConnectUtils.ts b/ui/cypress/support/utils/connect/ConnectUtils.ts index 9403c550bf..a7ef30e04c 100644 --- a/ui/cypress/support/utils/connect/ConnectUtils.ts +++ b/ui/cypress/support/utils/connect/ConnectUtils.ts @@ -447,13 +447,12 @@ export class ConnectUtils { .first() .invoke('text') .then(firstPageFirstItem => { - cy.get('[data-cy="adapter-name"]').should('have.length', 5); cy.get('[data-cy="table-paginator"]') .find('button[aria-label="Next"]') .should('not.be.disabled') .click(); - cy.wait(500); + cy.wait(1000); cy.get('[data-cy="adapter-name"]') .first() @@ -472,16 +471,17 @@ export class ConnectUtils { .first() .invoke('text') .then(firstItemNameBefore => { + cy.log(firstItemNameBefore); cy.get('th[mat-sort-header=""] .mat-sort-header-content') .contains(name) .click(); - - cy.wait(1000); + cy.wait(500); cy.get('[data-cy="adapter-name"]') .first() .invoke('text') .then(firstItemNameAfter => { + cy.log(firstItemNameAfter); expect(firstItemNameBefore.trim()).to.not.equal( firstItemNameAfter.trim(), ); diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index 646238d243..c37518f185 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -33,7 +33,7 @@ describe('Adapter Paging Test', () => { cy.get('mat-select').click(); }); cy.get('mat-option').contains('5').click(); - cy.wait(1000); + cy.wait(2000); cy.get('[data-cy="adapter-name"]').should('have.length', 5); ConnectUtils.validateAdapterPagination(); 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 3faf4233bc..c1abca29d9 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 @@ -91,7 +91,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { }>({ text: '', category: '', - view: 'createdAt', + view: '', }); adapterMetrics: Record = {}; @@ -388,6 +388,7 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { this.sort.active = 'createdAt'; } } + // TODO MAYBE NECESSARY TO DO THIS AS ELSE this.filter.next({ text: '', category: '', view: 'createdAt' }); } From efd51c62fb0b3dde44a54cbaa86b921ce2bdb3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 14:41:52 +0200 Subject: [PATCH 099/113] everything running --- .../tests/connect/adapterPaging.spec.ts | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index c37518f185..19b1e19b4a 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -60,19 +60,25 @@ describe('Adapter Paging Test', () => { }); it('Basic Filtering Running', () => { - // TODO Add One Item as running ConnectUtils.goToConnect(); - cy.wait(1000); + // Add one Adapter running + const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() + .setStart() + .build(); - cy.get('th[mat-sort-header=""] .mat-sort-header-content', { - timeout: 10000, - }) - .contains('Status') - .should('be.visible') - .click(); - cy.wait(1000); - ConnectUtils.filterAdapterPagination('Status'); + CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(() => { + cy.wait(1000); + + cy.get('th[mat-sort-header=""] .mat-sort-header-content', { + timeout: 10000, + }) + .contains('Status') + .should('be.visible') + .click(); + cy.wait(1000); + ConnectUtils.filterAdapterPagination('Status'); + }); }); it('Basic Filtering Category', () => {}); }); From 8ebb24d53e08c8876cfd8c6f9e343d92571177d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 15:17:00 +0200 Subject: [PATCH 100/113] all tests are running --- .../tests/connect/adapterPaging.spec.ts | 34 +++++++++++++++++-- .../filter-toolbar.component.html | 1 + 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index 19b1e19b4a..fcf6d75144 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -66,7 +66,7 @@ describe('Adapter Paging Test', () => { const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() .setStart() .build(); - + 0; CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(() => { cy.wait(1000); @@ -80,5 +80,35 @@ describe('Adapter Paging Test', () => { ConnectUtils.filterAdapterPagination('Status'); }); }); - it('Basic Filtering Category', () => {}); + it('Basic Filtering Category', () => { + ConnectUtils.goToConnect(); + // Select a Invalid Category // Check for 0 + //cy.get('mat-select[formcontrolname="selectedCategory"]') // Target the mat-select element (adjust selector as needed) + //.click(); + cy.wait(1000); + + cy.get('[data-cy="category-select"]').click(); + + cy.wait(500); + + // Select the desired category (assuming you want the category with label 'Category 1') + cy.get('mat-option') + .contains('Finance') // Replace 'Category 1' with the exact category name + .click(); + cy.wait(1000); + // Check that nothing is there + cy.get('[data-cy="no-table-entries"]').should('be.visible'); + cy.get('[data-cy="no-table-entries"]') + .should('be.visible') + .contains('No entries available.'); + cy.wait(500); + cy.get('[data-cy="category-select"]').click(); + + // Select a Debugging Category // CHeck that smth there + cy.get('mat-option') + .contains('Debugging') // Replace 'Category 1' with the exact category name + .click(); + cy.wait(1000); + cy.get('[data-cy="no-table-entries"]').should('not.exist'); + }); }); diff --git a/ui/src/app/connect/components/filter-toolbar/filter-toolbar.component.html b/ui/src/app/connect/components/filter-toolbar/filter-toolbar.component.html index 7f790adbdd..ac7f3b88eb 100644 --- a/ui/src/app/connect/components/filter-toolbar/filter-toolbar.component.html +++ b/ui/src/app/connect/components/filter-toolbar/filter-toolbar.component.html @@ -44,6 +44,7 @@
From 67bdfdec6aa7855ff0e11e9c594bf21ab3ab858e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 15:22:54 +0200 Subject: [PATCH 101/113] small refactoring still running --- .../support/utils/connect/ConnectUtils.ts | 7 +++++++ .../tests/connect/adapterPaging.spec.ts | 21 ++++--------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/ui/cypress/support/utils/connect/ConnectUtils.ts b/ui/cypress/support/utils/connect/ConnectUtils.ts index a7ef30e04c..07ef977a09 100644 --- a/ui/cypress/support/utils/connect/ConnectUtils.ts +++ b/ui/cypress/support/utils/connect/ConnectUtils.ts @@ -488,6 +488,13 @@ export class ConnectUtils { }); }); } + public static filterAdapterForCategory(category: string) { + cy.get('[data-cy="category-select"]').click(); + + cy.wait(500); + + cy.get('mat-option').contains(category).click(); + } public static validateAdapterIsStopped() { ConnectUtils.goToConnect(); ConnectBtns.startAdapter().should('have.length', 1); diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index fcf6d75144..e5ddf4800e 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -82,32 +82,19 @@ describe('Adapter Paging Test', () => { }); it('Basic Filtering Category', () => { ConnectUtils.goToConnect(); - // Select a Invalid Category // Check for 0 - //cy.get('mat-select[formcontrolname="selectedCategory"]') // Target the mat-select element (adjust selector as needed) - //.click(); cy.wait(1000); - cy.get('[data-cy="category-select"]').click(); - - cy.wait(500); - - // Select the desired category (assuming you want the category with label 'Category 1') - cy.get('mat-option') - .contains('Finance') // Replace 'Category 1' with the exact category name - .click(); + ConnectUtils.filterAdapterForCategory('Finance'); cy.wait(1000); - // Check that nothing is there + cy.get('[data-cy="no-table-entries"]').should('be.visible'); cy.get('[data-cy="no-table-entries"]') .should('be.visible') .contains('No entries available.'); cy.wait(500); - cy.get('[data-cy="category-select"]').click(); - // Select a Debugging Category // CHeck that smth there - cy.get('mat-option') - .contains('Debugging') // Replace 'Category 1' with the exact category name - .click(); + ConnectUtils.filterAdapterForCategory('Debugging'); + cy.wait(1000); cy.get('[data-cy="no-table-entries"]').should('not.exist'); }); From 8487379703237bdaf868e9cd311d7af06be470dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Mon, 22 Sep 2025 15:26:27 +0200 Subject: [PATCH 102/113] deleted logs --- .../sp-table-pagination.component.ts | 10 ---------- .../existing-adapters/existing-adapters.component.ts | 1 - 2 files changed, 11 deletions(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index ba82063d0d..d98c19b38a 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -117,7 +117,6 @@ export class SpTablePaginationComponent { this.filter?.subscribe(() => { this.filtering = this.filter.value; this.propertyName = this.getViewFn(this.filter.value['view']); - console.log('Property Name from FIlter', this.propertyName); this.resetPagination(); this.loadData(0); }); @@ -126,7 +125,6 @@ export class SpTablePaginationComponent { private updateSort(sortChange: Sort): void { this.propertyName = this.getViewFn(sortChange.active); - console.log('Property Name from Update Sort', this.propertyName); this.clearFilters(); this.resetPagination(); this.loadData(0); @@ -148,7 +146,6 @@ export class SpTablePaginationComponent { } onPageChange(event: PageEvent) { this.pageSize = event.pageSize; - console.log('Page Size Change', this.pageSize); this.currentPage = event.pageIndex; this.loadData(this.currentPage); } @@ -166,7 +163,6 @@ export class SpTablePaginationComponent { loadData(pageIndex: number) { const start = this.startKeyMap.get(pageIndex) || null; let startkey = start; - console.log(start); this.fetchDataFn(startkey, this.pageSize + 1).subscribe({ next: (data: T[]) => { @@ -179,12 +175,8 @@ export class SpTablePaginationComponent { this.totalItems = data.length + pageIndex * this.pageSize; } - console.log('page from fetch', this.pageSize); - console.log(data.length); - if (data.length > this.pageSize) { let nextStartKey; - console.log('DATA', this.propertyName); if (Array.isArray(this.propertyName)) { nextStartKey = this.propertyName.map( @@ -192,7 +184,6 @@ export class SpTablePaginationComponent { ); } else { nextStartKey = data[this.pageSize][this.propertyName]; - console.log(nextStartKey); } const nextStartKeyString = Array.isArray(nextStartKey) ? JSON.stringify(nextStartKey) @@ -200,7 +191,6 @@ export class SpTablePaginationComponent { this.startKeyMap.set(pageIndex + 1, nextStartKeyString); this.dataSource.data = data.slice(0, this.pageSize); } - console.log(this.startKeyMap); }, error: err => { console.error('Failed to fetch paginated data', err); 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 c1abca29d9..3f08d79f6e 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 @@ -479,7 +479,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { const { startKey: derivedStartKey, endKey } = this.getStartAndEndKeyFromFilter(startKey); const sortBy = this.getSortView(); - console.log('SortBY', sortBy); if (sortBy == 'category') { // Unfortunatly needs a different endpoint From 3c220d4c86a6abb590a51a21967b6c235160916a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 07:41:17 +0200 Subject: [PATCH 103/113] fixed adapter tests --- .../org/apache/streampipes/rest/ResetManagement.java | 10 ++++++++-- .../couchdb/impl/AdapterInstanceStorageImpl.java | 10 +++++++--- ui/cypress/tests/connect/adapterPaging.spec.ts | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java index e5804a563c..5079f8eb32 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java @@ -60,14 +60,17 @@ public static void reset(String username) { logger.info("Start resetting the system"); setHideTutorialToFalse(username); - + logger.info("1"); clearPipelineAssemblyCache(username); + logger.info("2"); stopAndDeleteAllPipelines(); + logger.info("3"); stopAndDeleteAllAdapters(); - + logger.info("4"); deleteAllFiles(); + logger.info("5"); removeAllDataInDataLake(); @@ -102,6 +105,7 @@ private static void stopAndDeleteAllPipelines() { } private static void stopAndDeleteAllAdapters() { + logger.info("Delete Adapter Function"); AdapterMasterManagement adapterMasterManagement = new AdapterMasterManagement( StorageDispatcher.INSTANCE.getNoSqlStore() .getAdapterInstanceStorage(), @@ -111,7 +115,9 @@ private static void stopAndDeleteAllAdapters() { ); List allAdapters = adapterMasterManagement.getAllAdapterInstances(); + logger.info("Size of adapters: {}", allAdapters.size()); allAdapters.forEach(adapterDescription -> { + logger.info(adapterDescription.toString()); try { adapterMasterManagement.deleteAdapter(adapterDescription.getElementId()); } catch (AdapterException e) { diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index b110978d23..669dba12f6 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -31,8 +31,8 @@ import com.google.gson.JsonParser; import org.lightcouch.CouchDbClient; import org.lightcouch.View; - - +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStreamReader; @@ -49,10 +49,12 @@ import java.util.NoSuchElementException; public class AdapterInstanceStorageImpl extends DefaultCrudStorage implements IAdapterStorage { + private static final Logger logger = LoggerFactory.getLogger(AdapterInstanceStorageImpl.class); public AdapterInstanceStorageImpl() { super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); } + @Override public AdapterDescription getFirstAdapterByAppId(String appId) { @@ -74,8 +76,10 @@ public List getAdaptersByAppId(String appId) { @Override public List findAll() { List adapters = findAll("paginator/non_design_docs"); + logger.info("Size of adapters: {}", adapters.size()); + //TODO Need to put smth elese her ! return adapters.stream() - .filter(adapter -> adapter.getDescription() != null) + //.filter(adapter -> adapter.getDescription()) .toList(); } diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index e5ddf4800e..849a6f7a6d 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -26,7 +26,7 @@ describe('Adapter Paging Test', () => { }); it('Basic Paging check', () => { - //CompactAdapterUtils.getAndSaveNMachineDataSimulator() + CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); cy.wait(1000); cy.dataCy('table-paginator').within(() => { From bd58ba362e81c9e910211b4df566b1c9c8a11af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 07:42:48 +0200 Subject: [PATCH 104/113] changes to view --- .../streampipes/manager/setup/CouchDbInstallationStep.java | 2 +- .../core/migrations/v099/AddAdapterPaginatorViewsToDB.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java index 577c274958..2df4e3b42d 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java @@ -170,7 +170,7 @@ private void addPaginatorView() { nonDesignDocsView.setMap( "function (doc) {\n" + " if (!doc._id.startsWith(\"_design/\")) {\n" - + " emit(doc._id, null);\n" + + " emit(doc._id, doc);\n" + " }\n" + "}"); diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java index ac5f1c5966..b3568512e0 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/AddAdapterPaginatorViewsToDB.java @@ -106,7 +106,7 @@ public void executeMigration() throws IOException { nonDesignDocsView.setMap( "function (doc) {\n" + " if (!doc._id.startsWith(\"_design/\")) {\n" - + " emit(doc._id, null);\n" + + " emit(doc._id, doc);\n" + " }\n" + "}"); From c381d09cd63d5e4266958b8d3a5630dd320a960e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 07:45:00 +0200 Subject: [PATCH 105/113] elimnated logger --- .../streampipes/rest/ResetManagement.java | 47 +++++++------------ .../impl/AdapterInstanceStorageImpl.java | 4 -- 2 files changed, 18 insertions(+), 33 deletions(-) diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java index 5079f8eb32..d1c5592bc1 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java @@ -44,7 +44,8 @@ import java.util.Map; public class ResetManagement { - // This class should be moved into another package. I moved it here because I got a cyclic maven + // This class should be moved into another package. I moved it here because I + // got a cyclic maven // dependency between this package and streampipes-pipeline-management // See in issue [STREAMPIPES-405] @@ -60,17 +61,14 @@ public static void reset(String username) { logger.info("Start resetting the system"); setHideTutorialToFalse(username); - logger.info("1"); + clearPipelineAssemblyCache(username); - logger.info("2"); stopAndDeleteAllPipelines(); - logger.info("3"); stopAndDeleteAllAdapters(); - logger.info("4"); + deleteAllFiles(); - logger.info("5"); removeAllDataInDataLake(); @@ -105,19 +103,15 @@ private static void stopAndDeleteAllPipelines() { } private static void stopAndDeleteAllAdapters() { - logger.info("Delete Adapter Function"); AdapterMasterManagement adapterMasterManagement = new AdapterMasterManagement( StorageDispatcher.INSTANCE.getNoSqlStore() - .getAdapterInstanceStorage(), + .getAdapterInstanceStorage(), new SpResourceManager().manageAdapters(), new SpResourceManager().manageDataStreams(), - AdapterMetricsManager.INSTANCE.getAdapterMetrics() - ); + AdapterMetricsManager.INSTANCE.getAdapterMetrics()); List allAdapters = adapterMasterManagement.getAllAdapterInstances(); - logger.info("Size of adapters: {}", allAdapters.size()); allAdapters.forEach(adapterDescription -> { - logger.info(adapterDescription.toString()); try { adapterMasterManagement.deleteAdapter(adapterDescription.getElementId()); } catch (AdapterException e) { @@ -150,24 +144,22 @@ private static void removeAllDataInDataLake() { } private static void removeAllDataViewWidgets() { - var widgetStorage = - StorageDispatcher.INSTANCE.getNoSqlStore() - .getDataExplorerWidgetStorage(); + var widgetStorage = StorageDispatcher.INSTANCE.getNoSqlStore() + .getDataExplorerWidgetStorage(); widgetStorage.findAll() - .forEach(widget -> widgetStorage.deleteElementById(widget.getElementId())); + .forEach(widget -> widgetStorage.deleteElementById(widget.getElementId())); } private static void removeAllDataViews() { - var dataLakeDashboardStorage = - StorageDispatcher.INSTANCE.getNoSqlStore() - .getDataExplorerDashboardStorage(); + var dataLakeDashboardStorage = StorageDispatcher.INSTANCE.getNoSqlStore() + .getDataExplorerDashboardStorage(); dataLakeDashboardStorage.findAll() - .forEach(dashboard -> dataLakeDashboardStorage.deleteElementById(dashboard.getElementId())); + .forEach(dashboard -> dataLakeDashboardStorage.deleteElementById(dashboard.getElementId())); } private static void removeAllAssets(String username) { IGenericStorage genericStorage = StorageDispatcher.INSTANCE.getNoSqlStore() - .getGenericStorage(); + .getGenericStorage(); try { for (Map asset : genericStorage.findAll("asset-management")) { genericStorage.delete((String) asset.get("_id"), (String) asset.get("_rev")); @@ -178,8 +170,7 @@ private static void removeAllAssets(String username) { } private static void removeAllPipelineTemplates() { - var pipelineElementTemplateStorage = StorageDispatcher - .INSTANCE + var pipelineElementTemplateStorage = StorageDispatcher.INSTANCE .getNoSqlStore() .getPipelineElementTemplateStorage(); @@ -192,10 +183,9 @@ private static void removeAllPipelineTemplates() { private static void clearGenericStorage() { var appDocTypesToDelete = List.of( "asset-management", - "asset-sites" - ); + "asset-sites"); var genericStorage = StorageDispatcher.INSTANCE.getNoSqlStore() - .getGenericStorage(); + .getGenericStorage(); appDocTypesToDelete.forEach(docType -> { try { @@ -203,10 +193,9 @@ private static void clearGenericStorage() { for (var doc : allDocs) { genericStorage.delete( doc.get("_id") - .toString(), + .toString(), doc.get("_rev") - .toString() - ); + .toString()); } } catch (IOException e) { throw new RuntimeException(e); diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 669dba12f6..51a6d678b6 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -49,7 +49,6 @@ import java.util.NoSuchElementException; public class AdapterInstanceStorageImpl extends DefaultCrudStorage implements IAdapterStorage { - private static final Logger logger = LoggerFactory.getLogger(AdapterInstanceStorageImpl.class); public AdapterInstanceStorageImpl() { super(Utils::getCouchDbAdapterInstanceClient, AdapterDescription.class); @@ -76,10 +75,7 @@ public List getAdaptersByAppId(String appId) { @Override public List findAll() { List adapters = findAll("paginator/non_design_docs"); - logger.info("Size of adapters: {}", adapters.size()); - //TODO Need to put smth elese her ! return adapters.stream() - //.filter(adapter -> adapter.getDescription()) .toList(); } From efd8c9c3c6c7b13770bb143970174dc53609749c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 07:45:29 +0200 Subject: [PATCH 106/113] eliminated logger --- .../storage/couchdb/impl/AdapterInstanceStorageImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java index 51a6d678b6..33def3aeb8 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterInstanceStorageImpl.java @@ -31,8 +31,6 @@ import com.google.gson.JsonParser; import org.lightcouch.CouchDbClient; import org.lightcouch.View; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStreamReader; From c0715ce0f48d1ccf7c7a098ddc86b5d20a529f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 08:01:13 +0200 Subject: [PATCH 107/113] tests work --- ui/cypress/tests/connect/adapterPaging.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index 849a6f7a6d..83f59a5467 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -40,6 +40,7 @@ describe('Adapter Paging Test', () => { }); it('Basic Filtering Name', () => { + CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); cy.wait(1000); @@ -54,12 +55,14 @@ describe('Adapter Paging Test', () => { }); it('Basic Filtering CreatedAT', () => { + CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); cy.wait(1000); ConnectUtils.filterAdapterPagination('Created'); }); it('Basic Filtering Running', () => { + CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); // Add one Adapter running @@ -81,6 +84,7 @@ describe('Adapter Paging Test', () => { }); }); it('Basic Filtering Category', () => { + CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); cy.wait(1000); From fecffbd1ac438a54904b4ebaef512e9e41108cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= <78690944+JHoelli@users.noreply.github.com> Date: Tue, 23 Sep 2025 08:02:35 +0200 Subject: [PATCH 108/113] Update ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts Co-authored-by: Philipp Zehnder --- .../sp-table-pagination/sp-table-pagination.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts index b671d7a5e1..7d9dd49d02 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table-pagination/sp-table-pagination.component.ts @@ -45,7 +45,7 @@ import { BehaviorSubject } from 'rxjs'; styleUrls: ['./sp-table-pagination.component.scss'], standalone: false, }) -export class SpTablePaginationComponent implements AfterViewInit { +export class SpTablePaginationComponent implements AfterViewInit, OnChanges, AfterContentInit { @ContentChildren(MatHeaderRowDef) headerRowDefs: QueryList; @ContentChildren(MatRowDef) rowDefs: QueryList>; @ContentChildren(MatColumnDef) columnDefs: QueryList; From 961bb5833eef6523efe498a2e1cf63b4832e1e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 08:15:54 +0200 Subject: [PATCH 109/113] changed naming convention to startId and endId --- .../src/lib/apis/adapter.service.ts | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts index 289756d32b..e08aca9e6f 100644 --- a/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts +++ b/ui/projects/streampipes/platform-services/src/lib/apis/adapter.service.ts @@ -51,16 +51,16 @@ export class AdapterService { } getAdaptersPaginated( - startid: string | number | null, - endid: string | number | null, + startId: string | number | null, + endId: string | number | null, limit: number, property: string = 'createdAt', descending: boolean = false, ): Observable { return this.requestAdapterDescriptionsPaginated( '/master/adapters/paginator', - startid, - endid, + startId, + endId, limit, property, descending, @@ -68,14 +68,14 @@ export class AdapterService { } getAdaptersCategorywisePaginated( category: string, - startid: string | number | null, + startId: string | number | null, limit: number, descending: boolean = false, ): Observable { return this.requestAdapterCategoryWiseDescriptionsPaginated( '/master/adapters/paginator/category', category, - startid, + startId, limit, descending, ); @@ -101,7 +101,7 @@ export class AdapterService { requestAdapterCategoryWiseDescriptionsPaginated( path: string, category: string, - startid: string | number | null, + startId: string | number | null, limit: number, descending: boolean, ): Observable { @@ -109,8 +109,8 @@ export class AdapterService { params = params.set('category', category); - if (startid) { - params = params.set('startKey', startid); + if (startId) { + params = params.set('startKey', startId); } params = params.set('descending', descending); @@ -127,19 +127,19 @@ export class AdapterService { requestAdapterDescriptionsPaginated( path: string, - startid: string | number | null, - endid: string | number | null, + startId: string | number | null, + endId: string | number | null, limit: number, property: string, descending: boolean, ): Observable { let params = new HttpParams().set('limit', limit.toString()); - if (startid) { - params = params.set('startKey', startid); + if (startId) { + params = params.set('startKey', startId); } - if (endid) { - params = params.set('endKey', endid); + if (endId) { + params = params.set('endKey', endId); } params = params.set('view', property); params = params.set('descending', descending); From 34c84a4b32e77095b27e9c414be071dd1e364536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 09:56:36 +0200 Subject: [PATCH 110/113] added gradle-tech to package.json --- ui/package-lock.json | 740 ++++++++++++++++++++++++++++++++++++++----- ui/package.json | 1 + 2 files changed, 653 insertions(+), 88 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index ce201a098d..3455219d31 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -23,6 +23,7 @@ "@bluehalo/ngx-leaflet": "^19.0.0", "@ctrl/ngx-codemirror": "7.0.0", "@fortawesome/fontawesome-free": "6.5.1", + "@gradle-tech/develocity-agent": "^2.0.2", "@jsplumb/browser-ui": "^6.2.10", "@ngbracket/ngx-layout": "^19.0.0", "@ngx-loading-bar/core": "6.0.2", @@ -181,6 +182,40 @@ } } }, + "node_modules/@angular-devkit/architect/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/architect/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/build-angular": { "version": "19.2.13", "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.2.13.tgz", @@ -376,6 +411,24 @@ "semver": "bin/semver.js" } }, + "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -412,6 +465,22 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/@angular-devkit/build-angular/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/build-webpack": { "version": "0.1902.13", "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1902.13.tgz", @@ -479,6 +548,40 @@ } } }, + "node_modules/@angular-devkit/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-eslint/builder": { "version": "19.4.0", "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-19.4.0.tgz", @@ -522,6 +625,40 @@ } } }, + "node_modules/@angular-eslint/builder/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-eslint/builder/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-eslint/bundled-angular-compiler": { "version": "19.4.0", "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-19.4.0.tgz", @@ -608,6 +745,40 @@ } } }, + "node_modules/@angular-eslint/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-eslint/schematics/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-eslint/template-parser": { "version": "19.4.0", "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-19.4.0.tgz", @@ -937,6 +1108,40 @@ } } }, + "node_modules/@angular/cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/cli/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/common": { "version": "19.2.13", "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.2.13.tgz", @@ -3683,6 +3888,31 @@ "node": ">=6" } }, + "node_modules/@gradle-tech/develocity-agent": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@gradle-tech/develocity-agent/-/develocity-agent-2.0.2.tgz", + "integrity": "sha512-79k2YkaLDzuqLf5YPYR2RldYtHwi1vWXNd4+X1gpMwqZkKTFO16h4GQfaz7mlfYx0Yssrj9c2WTPwsK5pyocig==", + "license": "SEE LICENSE AT https://gradle.com/help/legal-terms-of-use", + "engines": { + "node": ">=18.20.5" + }, + "peerDependencies": { + "@jest/jest-message-util": ">=28.1", + "@jest/reporters": ">=28.1", + "mocha": ">=7.0.1" + }, + "peerDependenciesMeta": { + "@jest/jest-message-util": { + "optional": true + }, + "@jest/reporters": { + "optional": true + }, + "mocha": { + "optional": true + } + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -4108,7 +4338,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -4126,7 +4356,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=12" @@ -4139,7 +4369,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=12" @@ -4152,14 +4382,14 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -4177,7 +4407,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -4193,7 +4423,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -5826,6 +6056,21 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.1.tgz", + "integrity": "sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, "node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.34.8", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", @@ -5982,25 +6227,59 @@ } } }, - "node_modules/@sigstore/bundle": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz", - "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==", + "node_modules/@schematics/angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "@sigstore/protobuf-specs": "^0.4.0" + "readdirp": "^4.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@sigstore/core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", - "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@schematics/angular/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz", + "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.17.0 || >=20.5.0" } @@ -7544,7 +7823,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -7554,7 +7833,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -7618,7 +7897,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, + "devOptional": true, "license": "Python-2.0" }, "node_modules/aria-query": { @@ -8092,7 +8371,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -8115,7 +8394,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true, + "devOptional": true, "license": "ISC", "peer": true }, @@ -8392,7 +8671,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "engines": { @@ -8434,7 +8713,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8771,7 +9050,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -8786,7 +9065,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -8848,7 +9127,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -8861,7 +9140,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/colorette": { @@ -9165,7 +9444,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -10168,7 +10447,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "engines": { @@ -10406,7 +10685,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "peer": true, "engines": { @@ -10527,7 +10806,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/ecc-jsbn": { @@ -10597,7 +10876,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/emoji-toolkit": { @@ -10933,7 +11212,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -10950,7 +11229,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -11768,7 +12047,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -11856,7 +12135,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", @@ -11988,7 +12267,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, + "devOptional": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -12099,7 +12378,7 @@ "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -12257,7 +12536,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -12322,7 +12601,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "bin": { @@ -13117,7 +13396,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -13170,7 +13449,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/isobject": { @@ -13381,7 +13660,7 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, + "devOptional": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -13467,7 +13746,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -14775,7 +15054,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -14837,7 +15116,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "chalk": "^4.1.0", @@ -15412,7 +15691,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -15438,7 +15717,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, + "devOptional": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -15623,7 +15902,7 @@ "version": "11.7.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.2.tgz", "integrity": "sha512-lkqVJPmqqG/w5jmmFtiRvtA2jkDyNVUcefFJKb2uyX4dekk8Okgqop3cgbFiaIvj8uCRJVTP5x9dfxGyXm2jvQ==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "dependencies": { @@ -15660,7 +15939,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "dependencies": { @@ -15677,7 +15956,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "engines": { @@ -15692,7 +15971,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "dependencies": { @@ -16695,7 +16974,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -16711,7 +16990,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -16781,7 +17060,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, + "devOptional": true, "license": "BlueOak-1.0.0" }, "node_modules/package-manager-detector": { @@ -16950,7 +17229,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -16969,7 +17248,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -16986,7 +17265,7 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, + "devOptional": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -17003,7 +17282,7 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/path-to-regexp": { @@ -17068,7 +17347,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/picomatch": { @@ -17646,7 +17925,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" @@ -17824,7 +18103,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -18392,7 +18671,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" @@ -18640,7 +18919,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -18653,7 +18932,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -18769,7 +19048,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, + "devOptional": true, "license": "ISC", "engines": { "node": ">=14" @@ -19259,7 +19538,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -19275,7 +19554,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -19290,7 +19569,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -19300,7 +19579,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -19310,7 +19589,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -19324,7 +19603,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -19357,7 +19636,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -19377,7 +19656,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -20236,6 +20515,291 @@ } } }, + "node_modules/vite/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.1.tgz", + "integrity": "sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-android-arm64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.1.tgz", + "integrity": "sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz", + "integrity": "sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz", + "integrity": "sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.1.tgz", + "integrity": "sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.1.tgz", + "integrity": "sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.1.tgz", + "integrity": "sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.1.tgz", + "integrity": "sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz", + "integrity": "sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz", + "integrity": "sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.1.tgz", + "integrity": "sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.1.tgz", + "integrity": "sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.1.tgz", + "integrity": "sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.1.tgz", + "integrity": "sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz", + "integrity": "sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz", + "integrity": "sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz", + "integrity": "sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.1.tgz", + "integrity": "sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz", + "integrity": "sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, "node_modules/vite/node_modules/@types/estree": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", @@ -20713,7 +21277,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -20767,7 +21331,7 @@ "version": "9.3.4", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "peer": true }, @@ -20791,7 +21355,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -20837,7 +21401,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, + "devOptional": true, "license": "ISC", "engines": { "node": ">=10" @@ -20867,7 +21431,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -20886,7 +21450,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, + "devOptional": true, "license": "ISC", "engines": { "node": ">=12" @@ -20896,7 +21460,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "dependencies": { @@ -20913,7 +21477,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "peer": true, "bin": { @@ -20924,7 +21488,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "engines": { @@ -20946,7 +21510,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" diff --git a/ui/package.json b/ui/package.json index 597d61859f..be404c858e 100644 --- a/ui/package.json +++ b/ui/package.json @@ -44,6 +44,7 @@ "@bluehalo/ngx-leaflet": "^19.0.0", "@ctrl/ngx-codemirror": "7.0.0", "@fortawesome/fontawesome-free": "6.5.1", + "@gradle-tech/develocity-agent": "^2.0.2", "@jsplumb/browser-ui": "^6.2.10", "@ngbracket/ngx-layout": "^19.0.0", "@ngx-loading-bar/core": "6.0.2", From 2196879d51c0b29241d3105505f329d95a4f79c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 10:41:47 +0200 Subject: [PATCH 111/113] tests running again --- .../support/utils/connect/ConnectUtils.ts | 15 ++++++----- .../tests/connect/adapterPaging.spec.ts | 27 +++++++++---------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/ui/cypress/support/utils/connect/ConnectUtils.ts b/ui/cypress/support/utils/connect/ConnectUtils.ts index 07ef977a09..8979e6b83d 100644 --- a/ui/cypress/support/utils/connect/ConnectUtils.ts +++ b/ui/cypress/support/utils/connect/ConnectUtils.ts @@ -467,18 +467,21 @@ export class ConnectUtils { } public static filterAdapterPagination(name: string) { - cy.get('[data-cy="adapter-name"]') + cy.dataCy('adapter-name', { timeout: 10000 }) .first() .invoke('text') .then(firstItemNameBefore => { cy.log(firstItemNameBefore); - cy.get('th[mat-sort-header=""] .mat-sort-header-content') + + cy.get('th[mat-sort-header=""] .mat-sort-header-content', { + timeout: 10000, + }) .contains(name) .click(); - cy.wait(500); - cy.get('[data-cy="adapter-name"]') + cy.dataCy('adapter-name', { timeout: 10000 }) .first() + .should('not.have.text', firstItemNameBefore.trim()) .invoke('text') .then(firstItemNameAfter => { cy.log(firstItemNameAfter); @@ -489,9 +492,7 @@ export class ConnectUtils { }); } public static filterAdapterForCategory(category: string) { - cy.get('[data-cy="category-select"]').click(); - - cy.wait(500); + cy.dataCy('category-select', { timeout: 10000 }).click(); cy.get('mat-option').contains(category).click(); } diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index 83f59a5467..f31531e36f 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -28,29 +28,29 @@ describe('Adapter Paging Test', () => { it('Basic Paging check', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); - cy.wait(1000); - cy.dataCy('table-paginator').within(() => { + + cy.dataCy('table-paginator', { timeout: 10000 }).within(() => { cy.get('mat-select').click(); }); cy.get('mat-option').contains('5').click(); - cy.wait(2000); - cy.get('[data-cy="adapter-name"]').should('have.length', 5); + cy.dataCy('adapter-name', { timeout: 10000 }).should('have.length', 5); ConnectUtils.validateAdapterPagination(); }); it('Basic Filtering Name', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); - cy.wait(1000); + + cy.dataCy('no-table-entries', { timeout: 10000 }).should('not.exist'); cy.get('th[mat-sort-header=""] .mat-sort-header-content', { timeout: 10000, }) .contains('Name') - .should('be.visible') + //.should('be.visible') .click(); - cy.wait(1000); + ConnectUtils.filterAdapterPagination('Name'); }); @@ -65,6 +65,8 @@ describe('Adapter Paging Test', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); + cy.wait(1000); + // Add one Adapter running const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() .setStart() @@ -89,17 +91,12 @@ describe('Adapter Paging Test', () => { cy.wait(1000); ConnectUtils.filterAdapterForCategory('Finance'); - cy.wait(1000); - cy.get('[data-cy="no-table-entries"]').should('be.visible'); - cy.get('[data-cy="no-table-entries"]') + cy.dataCy('no-table-entries').should('be.visible'); + cy.dataCy('no-table-entries') .should('be.visible') .contains('No entries available.'); - cy.wait(500); - ConnectUtils.filterAdapterForCategory('Debugging'); - - cy.wait(1000); - cy.get('[data-cy="no-table-entries"]').should('not.exist'); + cy.dataCy('no-table-entries').should('not.exist'); }); }); From 9b19cc144e6a78cc2911ccda2564b7f4c095d76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 10:51:07 +0200 Subject: [PATCH 112/113] some small refactoring --- .../support/utils/connect/ConnectBtns.ts | 10 ++++++++ .../tests/connect/adapterPaging.spec.ts | 23 +++++-------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/ui/cypress/support/utils/connect/ConnectBtns.ts b/ui/cypress/support/utils/connect/ConnectBtns.ts index 2a2223284c..1acba037ff 100644 --- a/ui/cypress/support/utils/connect/ConnectBtns.ts +++ b/ui/cypress/support/utils/connect/ConnectBtns.ts @@ -150,5 +150,15 @@ export class ConnectBtns { return 'undefined-org.apache.streampipes.extensions.management.connect.adapter.parser.xml-2-tag-0'; } + // ======================================================================== + // ===================== Filter and Pagination Buttons ========================== + public static sortingHeader(name: string) { + return cy + .get('th[mat-sort-header=""] .mat-sort-header-content', { + timeout: 10000, + }) + .contains(name); + } + // ======================================================================== } diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index f31531e36f..06e77999d1 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -44,12 +44,7 @@ describe('Adapter Paging Test', () => { cy.dataCy('no-table-entries', { timeout: 10000 }).should('not.exist'); - cy.get('th[mat-sort-header=""] .mat-sort-header-content', { - timeout: 10000, - }) - .contains('Name') - //.should('be.visible') - .click(); + ConnectBtns.sortingHeader('Name').click(); ConnectUtils.filterAdapterPagination('Name'); }); @@ -57,7 +52,7 @@ describe('Adapter Paging Test', () => { it('Basic Filtering CreatedAT', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); - cy.wait(1000); + cy.dataCy('no-table-entries', { timeout: 10000 }).should('not.exist'); ConnectUtils.filterAdapterPagination('Created'); }); @@ -65,7 +60,7 @@ describe('Adapter Paging Test', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); - cy.wait(1000); + cy.dataCy('no-table-entries', { timeout: 10000 }).should('not.exist'); // Add one Adapter running const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() @@ -75,21 +70,15 @@ describe('Adapter Paging Test', () => { CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(() => { cy.wait(1000); - cy.get('th[mat-sort-header=""] .mat-sort-header-content', { - timeout: 10000, - }) - .contains('Status') - .should('be.visible') - .click(); - cy.wait(1000); + ConnectBtns.sortingHeader('Status').should('be.visible').click(); + ConnectUtils.filterAdapterPagination('Status'); }); }); it('Basic Filtering Category', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); - cy.wait(1000); - + cy.dataCy('no-table-entries', { timeout: 10000 }).should('not.exist'); ConnectUtils.filterAdapterForCategory('Finance'); cy.dataCy('no-table-entries').should('be.visible'); From e3823fbdceabaed05089e15b9b01fb06e78c6718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacqueline=20H=C3=B6llig?= Date: Tue, 23 Sep 2025 11:03:15 +0200 Subject: [PATCH 113/113] finished refactoring --- ui/cypress/support/utils/connect/ConnectUtils.ts | 6 ++++++ ui/cypress/tests/connect/adapterPaging.spec.ts | 9 +++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ui/cypress/support/utils/connect/ConnectUtils.ts b/ui/cypress/support/utils/connect/ConnectUtils.ts index 8979e6b83d..edbb73ad33 100644 --- a/ui/cypress/support/utils/connect/ConnectUtils.ts +++ b/ui/cypress/support/utils/connect/ConnectUtils.ts @@ -513,4 +513,10 @@ export class ConnectUtils { ConnectBtns.deleteAdapter().should('have.length', amount); } } + + public static waitingForExistingAdapters() { + return cy + .dataCy('no-table-entries', { timeout: 10000 }) + .should('not.exist'); + } } diff --git a/ui/cypress/tests/connect/adapterPaging.spec.ts b/ui/cypress/tests/connect/adapterPaging.spec.ts index 06e77999d1..b8e6c71f80 100644 --- a/ui/cypress/tests/connect/adapterPaging.spec.ts +++ b/ui/cypress/tests/connect/adapterPaging.spec.ts @@ -42,7 +42,7 @@ describe('Adapter Paging Test', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); - cy.dataCy('no-table-entries', { timeout: 10000 }).should('not.exist'); + ConnectUtils.waitingForExistingAdapters(); ConnectBtns.sortingHeader('Name').click(); @@ -52,7 +52,7 @@ describe('Adapter Paging Test', () => { it('Basic Filtering CreatedAT', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); - cy.dataCy('no-table-entries', { timeout: 10000 }).should('not.exist'); + ConnectUtils.waitingForExistingAdapters(); ConnectUtils.filterAdapterPagination('Created'); }); @@ -60,7 +60,7 @@ describe('Adapter Paging Test', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); - cy.dataCy('no-table-entries', { timeout: 10000 }).should('not.exist'); + ConnectUtils.waitingForExistingAdapters(); // Add one Adapter running const compactAdapter = CompactAdapterUtils.getMachineDataSimulator() @@ -78,7 +78,8 @@ describe('Adapter Paging Test', () => { it('Basic Filtering Category', () => { CompactAdapterUtils.getAndSaveNMachineDataSimulator(); ConnectUtils.goToConnect(); - cy.dataCy('no-table-entries', { timeout: 10000 }).should('not.exist'); + ConnectUtils.waitingForExistingAdapters(); + ConnectUtils.filterAdapterForCategory('Finance'); cy.dataCy('no-table-entries').should('be.visible');