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

riemer pushed a commit to branch 
2376-add-endpoint-to-search-for-generic-storage-documents
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to 
refs/heads/2376-add-endpoint-to-search-for-generic-storage-documents by this 
push:
     new 1f2aa2b6d feat(#2376): Add find endpoint to generic storage API
1f2aa2b6d is described below

commit 1f2aa2b6d1864d8913999b069e2f1f854f2df571
Author: Dominik Riemer <[email protected]>
AuthorDate: Thu Dec 28 10:38:00 2023 +0100

    feat(#2376): Add find endpoint to generic storage API
---
 .../rest/impl/GenericStorageResource.java          | 20 +++++++-
 .../streampipes/storage/api/IGenericStorage.java   |  2 +
 .../storage/couchdb/impl/GenericStorageImpl.java   | 23 ++++++++-
 .../src/lib/apis/generic-storage.service.ts        | 31 +++++++-----
 .../src/lib/query/generic-storage-query-builder.ts | 58 ++++++++++++++++++++++
 .../platform-services/src/public-api.ts            |  1 +
 6 files changed, 119 insertions(+), 16 deletions(-)

diff --git 
a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/GenericStorageResource.java
 
b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/GenericStorageResource.java
index 6efef1df9..9f74d7205 100644
--- 
a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/GenericStorageResource.java
+++ 
b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/GenericStorageResource.java
@@ -79,6 +79,22 @@ public class GenericStorageResource extends 
AbstractAuthGuardedRestResource {
     }
   }
 
+  @PostMapping(
+      path = "/{appDocName}/find",
+      produces = MediaType.APPLICATION_JSON_VALUE,
+      consumes = MediaType.APPLICATION_JSON_VALUE)
+  @PreAuthorize(AuthConstants.HAS_WRITE_GENERIC_STORAGE_PRIVILEGE)
+  public ResponseEntity<List<Map<String, Object>>> 
find(@PathVariable(APP_DOC_NAME) String appDocName,
+                                                        @RequestBody 
Map<String, Object> query) {
+    try {
+      var docs = getGenericStorage().find(appDocName, query);
+      return ok(docs);
+    } catch (IOException e) {
+      LOG.error("Could not connect to storage", e);
+      throw new SpMessageException(HttpStatus.INTERNAL_SERVER_ERROR, e);
+    }
+  }
+
   @GetMapping(path = "/{appDocName}/{id}", produces = 
MediaType.APPLICATION_JSON_VALUE)
   @PreAuthorize(AuthConstants.HAS_READ_GENERIC_STORAGE_PRIVILEGE)
   public ResponseEntity<Map<String, Object>> 
getCategory(@PathVariable(APP_DOC_NAME) String appDocName,
@@ -98,8 +114,8 @@ public class GenericStorageResource extends 
AbstractAuthGuardedRestResource {
       consumes = MediaType.APPLICATION_JSON_VALUE)
   @PreAuthorize(AuthConstants.HAS_WRITE_GENERIC_STORAGE_PRIVILEGE)
   public ResponseEntity<Map<String, Object>> 
update(@PathVariable(APP_DOC_NAME) String appDocName,
-                                  @PathVariable("id") String documentId,
-                                  @RequestBody String document) {
+                                                    @PathVariable("id") String 
documentId,
+                                                    @RequestBody String 
document) {
     try {
       Map<String, Object> obj = getGenericStorage().update(documentId, 
document);
       return ok(obj);
diff --git 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
 
b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
index 528e8c93b..e9d9208f9 100644
--- 
a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
+++ 
b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
@@ -28,6 +28,8 @@ public interface IGenericStorage {
 
   List<Map<String, Object>> findAll(String type) throws IOException;
 
+  List<Map<String, Object>> find(String appDocType, Map<String, Object> query) 
throws IOException;
+
   Map<String, Object> findOne(String id) throws IOException;
 
   Map<String, Object> create(String payload) throws IOException;
diff --git 
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
 
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
index 6d5884ee4..f8f6942ef 100644
--- 
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
+++ 
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
@@ -41,8 +41,11 @@ public class GenericStorageImpl implements IGenericStorage {
   private static final String ID = "id";
   private static final String SLASH = "/";
 
+  private static final String DOCS_KEY = "docs";
+
   private final TypeReference<Map<String, Object>> typeRef = new 
TypeReference<>() {
   };
+
   private final ObjectMapper mapper;
 
   public GenericStorageImpl() {
@@ -68,6 +71,22 @@ public class GenericStorageImpl implements IGenericStorage {
     return result;
   }
 
+  @Override
+  public List<Map<String, Object>> find(String appDocType,
+                                        Map<String, Object> query) throws 
IOException {
+    var request = Utils.postRequest(
+        getDatabaseRoute() + "/_find",
+        mapper.writeValueAsString(query)
+    );
+    Content content = executeAndReturnContent(request);
+    var responseObj = deserialize(content.asString(StandardCharsets.UTF_8));
+    if (responseObj != null & responseObj.containsKey("docs")) {
+      return (List<Map<String, Object>>) responseObj.get(DOCS_KEY);
+    } else {
+      return List.of();
+    }
+  }
+
   @Override
   public Map<String, Object> findOne(String id) throws IOException {
     return this.queryDocuments(getDatabaseRoute() + SLASH + id);
@@ -110,7 +129,7 @@ public class GenericStorageImpl implements IGenericStorage {
                                byte[] payload,
                                String rev) throws IOException {
     Request req = Utils.putRequest(
-            getDatabaseRoute() + SLASH + docId + SLASH + attachmentName + 
"?rev=" + rev, payload, contentType
+        getDatabaseRoute() + SLASH + docId + SLASH + attachmentName + "?rev=" 
+ rev, payload, contentType
     );
     executeAndReturnContent(req);
   }
@@ -118,7 +137,7 @@ public class GenericStorageImpl implements IGenericStorage {
   @Override
   public GenericStorageAttachment findAttachment(String docId, String 
attachmentName) throws IOException {
     Request req = Utils.getRequest(getDatabaseRoute() + SLASH + docId + SLASH 
+ attachmentName);
-    Content content =  executeAndReturnContent(req);
+    Content content = executeAndReturnContent(req);
     return new GenericStorageAttachment(content.getType().getMimeType(), 
content.asBytes());
   }
 
diff --git 
a/ui/projects/streampipes/platform-services/src/lib/apis/generic-storage.service.ts
 
b/ui/projects/streampipes/platform-services/src/lib/apis/generic-storage.service.ts
index f4b1ccb28..6f18f3f3a 100644
--- 
a/ui/projects/streampipes/platform-services/src/lib/apis/generic-storage.service.ts
+++ 
b/ui/projects/streampipes/platform-services/src/lib/apis/generic-storage.service.ts
@@ -30,37 +30,44 @@ export class GenericStorageService {
         private platformServicesCommons: PlatformServicesCommons,
     ) {}
 
-    createDocument(appDocName: string, document: any): Observable<any> {
-        return this.http.post(this.getAppDocPath(appDocName), document);
+    createDocument(appDocType: string, document: any): Observable<any> {
+        return this.http.post(this.getAppDocPath(appDocType), document);
     }
 
-    getAllDocuments(appDocName: string): Observable<any> {
-        return this.http.get(this.getAppDocPath(appDocName));
+    getAllDocuments(appDocType: string): Observable<any> {
+        return this.http.get(this.getAppDocPath(appDocType));
     }
 
-    getDocument(appDocName: string, documentId: string): Observable<any> {
-        return 
this.http.get(`${this.getAppDocPath(appDocName)}/${documentId}`);
+    findDocuments(
+        appDocType: string,
+        query: Record<string, any>,
+    ): Observable<any> {
+        return this.http.post(`${this.getAppDocPath(appDocType)}/find`, query);
+    }
+
+    getDocument(appDocType: string, documentId: string): Observable<any> {
+        return 
this.http.get(`${this.getAppDocPath(appDocType)}/${documentId}`);
     }
 
-    updateDocument(appDocName: string, document: any): Observable<any> {
+    updateDocument(appDocType: string, document: any): Observable<any> {
         return this.http.put(
-            `${this.getAppDocPath(appDocName)}/${document._id}`,
+            `${this.getAppDocPath(appDocType)}/${document._id}`,
             document,
         );
     }
 
     deleteDocument(
-        appDocName: string,
+        appDocType: string,
         documentId: string,
         rev: string,
     ): Observable<any> {
         return this.http.delete(
-            `${this.getAppDocPath(appDocName)}/${documentId}/${rev}`,
+            `${this.getAppDocPath(appDocType)}/${documentId}/${rev}`,
         );
     }
 
-    private getAppDocPath(appDocName: string): string {
-        return this.genericStorageBasePath + '/' + appDocName;
+    private getAppDocPath(appDocType: string): string {
+        return this.genericStorageBasePath + '/' + appDocType;
     }
 
     private get genericStorageBasePath() {
diff --git 
a/ui/projects/streampipes/platform-services/src/lib/query/generic-storage-query-builder.ts
 
b/ui/projects/streampipes/platform-services/src/lib/query/generic-storage-query-builder.ts
new file mode 100644
index 000000000..98c8b1f5f
--- /dev/null
+++ 
b/ui/projects/streampipes/platform-services/src/lib/query/generic-storage-query-builder.ts
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ *
+ */
+
+export class GenericStorageQueryBuilder {
+    private query: Record<string, any> = {};
+    private selectors: Record<string, any> = {};
+
+    static create(appDocType: string): GenericStorageQueryBuilder {
+        return new GenericStorageQueryBuilder(appDocType);
+    }
+
+    constructor(appDocType: string) {
+        this.addSelector('appDocType', { $eq: appDocType });
+    }
+
+    public withFields(fields: string[]): GenericStorageQueryBuilder {
+        this.query.fields = fields;
+        return this;
+    }
+
+    public withLimit(limit: number): GenericStorageQueryBuilder {
+        this.query.limit = limit;
+        return this;
+    }
+
+    public withSkip(skip: number): GenericStorageQueryBuilder {
+        this.query.skip = skip;
+        return this;
+    }
+
+    public addSelector(
+        key: string,
+        condition: Record<string, any>,
+    ): GenericStorageQueryBuilder {
+        this.selectors[key] = condition;
+        return this;
+    }
+
+    public build() {
+        this.query.selector = this.selectors;
+        return this.query;
+    }
+}
diff --git a/ui/projects/streampipes/platform-services/src/public-api.ts 
b/ui/projects/streampipes/platform-services/src/public-api.ts
index 433e6bffe..d5cb1d61f 100644
--- a/ui/projects/streampipes/platform-services/src/public-api.ts
+++ b/ui/projects/streampipes/platform-services/src/public-api.ts
@@ -62,6 +62,7 @@ export * from './lib/model/gen/streampipes-model';
 export * from './lib/model/datalake/data-lake-query-config.model';
 export * from './lib/query/DatalakeQueryParameterBuilder';
 export * from './lib/query/data-view-query-generator.service';
+export * from './lib/query/generic-storage-query-builder';
 export * from './lib/model/user/user.model';
 
 export * from './lib/model/assets/asset.model';

Reply via email to