Repository: apache/streampipes (java)

Issue:
Create builder for SpQueryResult
### Body

To write tests for the APIs more easily there should be a builder which creates SpQueryResult objects.

### StreamPipes Committer

I acknowledge that I am a maintainer/committer of the Apache StreamPipes project.

Pull request description:
[#1336] Add a builder to create SpQueryResult objects
<!--
  ~ 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.
  ~
  -->
  
  <!--
Thanks for contributing! Here are some tips you can follow to help us incorporate your contribution quickly and easily:
1. If this is your first time, please read our contributor guidelines:
    - https://streampipes.apache.org/getinvolved.html
    - https://cwiki.apache.org/confluence/display/STREAMPIPES/Getting+Started
2. Make sure the PR title is formatted like: `[#<GitHub issue id>] PR title ...`
3. If the PR is unfinished, add '[WIP]' in your PR title, e.g., `[WIP][#<GitHub issue id>] PR title ...`.
4. Please write your PR title to summarize what this PR proposes/fixes.
5. Link the PR to the corresponding GitHub issue (if present) in the `Development` section in the right menu bar. 
6. Be sure to keep the PR description updated to reflect all changes.
7. If possible, provide a concise example to reproduce the issue for a faster review.
8. Make sure tests pass via `mvn clean install`.
9. (Optional) If the contribution is large, please file an Apache ICLA
    - http://apache.org/licenses/icla.pdf
-->

### Purpose
<!--
Please clarify what changes you are proposing and describe how those changes will address the issue.
Furthermore, describe potential consequences the changes might have.
-->
Fixes #1336

### Remarks
<!--
Is there anything left we need to pay attention on?
Are there some references that might be important? E.g. links to Confluence, or discussions
on the mailing list or GitHub.
-->
PR introduces (a) breaking change(s): no

PR introduces (a) deprecation(s): no


Patch:
diff --git a/archetypes/streampipes-archetype-extensions-jvm/src/main/resources/archetype-resources/pom.xml b/archetypes/streampipes-archetype-extensions-jvm/src/main/resources/archetype-resources/pom.xml
index dd9ec81cb8..95139da33b 100644
--- a/archetypes/streampipes-archetype-extensions-jvm/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/streampipes-archetype-extensions-jvm/src/main/resources/archetype-resources/pom.xml
@@ -24,7 +24,7 @@
     <version>${version}</version>
 
     <properties>
-        <sp.version>0.91.0-SNAPSHOT</sp.version>
+        <sp.version>0.92.0-SNAPSHOT</sp.version>
         <junit-jupiter.version>5.9.1</junit-jupiter.version>
     </properties>
 
diff --git a/archetypes/streampipes-archetype-pe-processors-flink/src/main/resources/archetype-resources/pom.xml b/archetypes/streampipes-archetype-pe-processors-flink/src/main/resources/archetype-resources/pom.xml
index 254fad6efe..1a82a15613 100644
--- a/archetypes/streampipes-archetype-pe-processors-flink/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/streampipes-archetype-pe-processors-flink/src/main/resources/archetype-resources/pom.xml
@@ -25,7 +25,7 @@
     <version>${version}</version>
 
     <properties>
-        <sp.version>0.91.0-SNAPSHOT</sp.version>
+        <sp.version>0.92.0-SNAPSHOT</sp.version>
     </properties>
 
     <dependencies>
diff --git a/archetypes/streampipes-archetype-pe-sinks-flink/src/main/resources/archetype-resources/pom.xml b/archetypes/streampipes-archetype-pe-sinks-flink/src/main/resources/archetype-resources/pom.xml
index 63155f6991..0c29e2aa1c 100644
--- a/archetypes/streampipes-archetype-pe-sinks-flink/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/streampipes-archetype-pe-sinks-flink/src/main/resources/archetype-resources/pom.xml
@@ -25,7 +25,7 @@
     <version>${version}</version>
 
     <properties>
-        <sp.version>0.91.0-SNAPSHOT</sp.version>
+        <sp.version>0.92.0-SNAPSHOT</sp.version>
     </properties>
 
     <dependencies>
diff --git a/installer/cli/.env b/installer/cli/.env
index 6ddb4f9de3..3dee049ee1 100644
--- a/installer/cli/.env
+++ b/installer/cli/.env
@@ -14,13 +14,13 @@
 # limitations under the License.
 
 SP_DOCKER_REGISTRY=apachestreampipes
-SP_VERSION=0.91.0-SNAPSHOT
+SP_VERSION=0.92.0-SNAPSHOT
 SP_SUBNET=172.31.0.0/16
 SP_CONSUL_CONTAINER_IP=172.31.0.9
 COMPOSE_PROJECT_NAME=streampipes
 
 # -------------------------------------------------------------
-# 
+#
 # OPTIONAL environment variables to configure system on startup
 #
 # -------------------------------------------------------------
@@ -32,7 +32,7 @@ COMPOSE_PROJECT_NAME=streampipes
 #SP_PRIORITIZED_PROTOCOL=nats
 
 # Configuration to set MQTT host in backend service
-# 
+#
 # default: activemq
 #SP_MQTT_HOST=mosquitto
 
diff --git a/installer/cli/README.md b/installer/cli/README.md
index 72297e804f..41f50213c8 100644
--- a/installer/cli/README.md
+++ b/installer/cli/README.md
@@ -23,7 +23,7 @@ The StreamPipes command-line interface (CLI) is focused on developers in order t
 * new core features for **backend** and **ui**.
 
 <!-- BEGIN do not edit: set via ../upgrade_versions.sh -->
-**Current version:** 0.91.0-SNAPSHOT
+**Current version:** 0.92.0-SNAPSHOT
 <!-- END do not edit -->
 
 ## TL;DR
diff --git a/installer/compose/.env b/installer/compose/.env
index b5a741703b..a5990407f3 100644
--- a/installer/compose/.env
+++ b/installer/compose/.env
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SP_VERSION=0.91.0-SNAPSHOT
+SP_VERSION=0.92.0-SNAPSHOT
 SP_DOCKER_REGISTRY=apachestreampipes
 SP_SUBNET=172.31.0.0/16
 SP_CONSUL_CONTAINER_IP=172.31.0.9
diff --git a/installer/compose/README.md b/installer/compose/README.md
index 475889cd02..e7285d201d 100644
--- a/installer/compose/README.md
+++ b/installer/compose/README.md
@@ -19,7 +19,7 @@
 StreamPipes Compose is a simple collection of user-friendly `docker-compose` files that easily lets gain first-hand experience with Apache StreamPipes.
 
 <!-- BEGIN do not edit: set via ../upgrade_versions.sh -->
-**Current version:** 0.91.0-SNAPSHOT
+**Current version:** 0.92.0-SNAPSHOT
 <!-- END do not edit -->
 
 > **NOTE**: We recommend StreamPipes Compose to only use for initial try-out and testing. If you are a developer and want to develop new pipeline elements or core feature, use the [StreamPipes CLI](../cli).
diff --git a/installer/k8s/Chart.yaml b/installer/k8s/Chart.yaml
index 38f5c20ca6..cf8030c1d3 100644
--- a/installer/k8s/Chart.yaml
+++ b/installer/k8s/Chart.yaml
@@ -14,9 +14,9 @@
 # limitations under the License.
 
 apiVersion: v1
-appVersion: "0.91.0-SNAPSHOT"
+appVersion: "0.92.0-SNAPSHOT"
 description: Self-Service Data Analytics for the Industrial IoT
 name: streampipes-helm-chart
 home: https://streampipes.apache.org
-version: 0.91.0-SNAPSHOT
+version: 0.92.0-SNAPSHOT
 icon: https://avatars1.githubusercontent.com/u/33908576
diff --git a/installer/k8s/README.md b/installer/k8s/README.md
index 5f0bfbb160..0ec6eeb121 100644
--- a/installer/k8s/README.md
+++ b/installer/k8s/README.md
@@ -19,7 +19,7 @@
 StreamPipes k8s is a helm chart to deploy StreamPipes on Kubernetes.
 
 <!-- BEGIN do not edit: set via ../upgrade_versions.sh -->
-**Current version:** 0.91.0-SNAPSHOT
+**Current version:** 0.92.0-SNAPSHOT
 <!-- END do not edit -->
 
 We provide two helm chart templates to get you going:
diff --git a/installer/k8s/values.yaml b/installer/k8s/values.yaml
index 6027c1e5a1..07edd3dbfc 100644
--- a/installer/k8s/values.yaml
+++ b/installer/k8s/values.yaml
@@ -21,7 +21,7 @@ persistentVolumeReclaimPolicy: "Delete"
 persistentVolumeAccessModes: "ReadWriteOnce"
 
 streampipes:
-  version: "0.91.0-SNAPSHOT"
+  version: "0.92.0-SNAPSHOT"
   registry: "apachestreampipes"
 
 external:
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/DataSeries.java b/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/DataSeries.java
index 13693a6333..8ddb5c99da 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/DataSeries.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/DataSeries.java
@@ -60,4 +60,19 @@ public class DataSeries {
     return rows;
   }
 
+  public void setTotal(int total) {
+    this.total = total;
+  }
+
+  public void setRows(List<List<Object>> rows) {
+    this.rows = rows;
+  }
+
+  public void setTags(Map<String, String> tags) {
+    this.tags = tags;
+  }
+
+  public void setHeaders(List<String> headers) {
+    this.headers = headers;
+  }
 }
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/DataSeriesBuilder.java b/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/DataSeriesBuilder.java
new file mode 100644
index 0000000000..66a3d61089
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/DataSeriesBuilder.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.streampipes.model.datalake;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class DataSeriesBuilder {
+  private final DataSeries dataSeries;
+  private final List<List<Object>> rows;
+
+  private DataSeriesBuilder() {
+    this.dataSeries = new DataSeries();
+    this.rows = new ArrayList<>();
+  }
+
+  public static DataSeriesBuilder create() {
+    return new DataSeriesBuilder();
+  }
+
+  public DataSeries build() {
+    dataSeries.setRows(rows);
+    dataSeries.setTotal(rows.size());
+    return dataSeries;
+  }
+
+  public DataSeriesBuilder withRow(List<Object> row) {
+    this.rows.add(row);
+    return this;
+  }
+
+  public DataSeriesBuilder withRows(List<List<Object>> rows) {
+    this.rows.addAll(rows);
+    return this;
+  }
+
+  public DataSeriesBuilder withHeaders(List<String> headers) {
+    dataSeries.setHeaders(headers);
+    return this;
+  }
+
+  public DataSeriesBuilder withTags(Map<String, String> tags) {
+    dataSeries.setTags(tags);
+    return this;
+  }
+}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/SpQueryResultBuilder.java b/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/SpQueryResultBuilder.java
new file mode 100644
index 0000000000..2f9adf3d94
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/SpQueryResultBuilder.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.streampipes.model.datalake;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SpQueryResultBuilder {
+
+  private final SpQueryResult spQueryResult;
+  private final List<DataSeries> allDataSeries;
+
+  private SpQueryResultBuilder(List<String> headers) {
+    spQueryResult = new SpQueryResult();
+    allDataSeries = new ArrayList<>();
+    spQueryResult.setHeaders(headers);
+  }
+
+  public static SpQueryResultBuilder create(List<String> headers) {
+    return new SpQueryResultBuilder(headers);
+  }
+
+  public SpQueryResult build() {
+    // set the header of all data series
+    allDataSeries
+        .forEach(series -> series.setHeaders(spQueryResult.getHeaders()));
+    spQueryResult.setAllDataSeries(allDataSeries);
+    spQueryResult.setTotal(allDataSeries.size());
+    return spQueryResult;
+  }
+
+  public SpQueryResultBuilder withDataSeries(List<DataSeries> allDataSeries) {
+    this.allDataSeries.addAll(allDataSeries);
+    return this;
+  }
+
+  public SpQueryResultBuilder withDataSeries(DataSeries dataSeries) {
+    this.allDataSeries.add(dataSeries);
+    return this;
+  }
+
+  public SpQueryResultBuilder withSourceIndex(int sourceIndex) {
+    spQueryResult.setSourceIndex(sourceIndex);
+    return this;
+  }
+
+  public SpQueryResultBuilder withSpQueryStatus(SpQueryStatus spQueryStatus) {
+    spQueryResult.setSpQueryStatus(spQueryStatus);
+    return this;
+  }
+
+  public SpQueryResultBuilder withForId(String forId) {
+    spQueryResult.setForId(forId);
+    return this;
+  }
+
+}
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 2ca3e694ec..16107e37c5 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "apache-streampipes",
-  "version": "0.91.0-SNAPSHOT",
+  "version": "0.92.0-SNAPSHOT",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "apache-streampipes",
-      "version": "0.91.0-SNAPSHOT",
+      "version": "0.92.0-SNAPSHOT",
       "hasInstallScript": true,
       "dependencies": {
         "@angular-architects/module-federation": "^14.3.14",
diff --git a/ui/package.json b/ui/package.json
index 3131c42049..d9d8b5772f 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -1,6 +1,6 @@
 {
   "name": "apache-streampipes",
-  "version": "0.91.0-SNAPSHOT",
+  "version": "0.92.0-SNAPSHOT",
   "description": "Apache StreamPipes user interface",
   "homepage": "http://streampipes.apache.org",
   "repository": {


Test patch:
diff --git a/streampipes-model/src/test/java/org/apache/streampipes/model/datalake/DataSeriesBuilderTest.java b/streampipes-model/src/test/java/org/apache/streampipes/model/datalake/DataSeriesBuilderTest.java
new file mode 100644
index 0000000000..1b1111f43b
--- /dev/null
+++ b/streampipes-model/src/test/java/org/apache/streampipes/model/datalake/DataSeriesBuilderTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.streampipes.model.datalake;
+
+
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class DataSeriesBuilderTest {
+
+  private static final List<Object> rowOne = List.of(1, "v1");
+  private static final List<Object> rowTwo = List.of(2, "v2");
+  @Test
+  public void withHeadersTest() {
+    var headers = List.of("h1", "h2");
+    var result = DataSeriesBuilder.create()
+        .withHeaders(headers)
+        .build();
+
+    assertEquals(2, result.getHeaders().size());
+    assertEquals(headers, result.getHeaders());
+  }
+
+
+  @Test
+  public void withRowTest() {
+
+    var result = DataSeriesBuilder.create()
+        .withRow(rowOne)
+        .build();
+
+    assertEquals(1, result.getRows().size());
+    assertEquals(1, result.getTotal());
+    assertEquals(List.of(rowOne), result.getRows());
+  }
+
+  @Test
+  public void withTwoRowsTest() {
+    var result = DataSeriesBuilder.create()
+        .withRow(rowOne)
+        .withRow(rowTwo)
+        .build();
+
+    assertEquals(2, result.getRows().size());
+    assertEquals(2, result.getTotal());
+    assertEquals(List.of(rowOne, rowTwo), result.getRows());
+  }
+
+  @Test
+  public void withRowsTest() {
+    var result = DataSeriesBuilder.create()
+        .withRows(List.of(rowOne, rowTwo))
+        .build();
+
+    assertEquals(2, result.getRows().size());
+    assertEquals(2, result.getTotal());
+    assertEquals(List.of(rowOne, rowTwo), result.getRows());
+  }
+
+  @Test
+  public void withTagsTest() {
+    Map<String, String> tags = Map.of("t1", "v1");
+
+    var result = DataSeriesBuilder.create()
+        .withTags(tags)
+        .build();
+
+    assertEquals(tags, result.getTags());
+  }
+}
\ No newline at end of file
diff --git a/streampipes-model/src/test/java/org/apache/streampipes/model/datalake/SpQueryResultBuilderTest.java b/streampipes-model/src/test/java/org/apache/streampipes/model/datalake/SpQueryResultBuilderTest.java
new file mode 100644
index 0000000000..a453795c50
--- /dev/null
+++ b/streampipes-model/src/test/java/org/apache/streampipes/model/datalake/SpQueryResultBuilderTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.streampipes.model.datalake;
+
+
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class SpQueryResultBuilderTest {
+
+  List<String> headers = List.of("h1", "h2");
+  @Test
+  public void withHeadersTest() {
+    var result = SpQueryResultBuilder.create(headers)
+        .build();
+
+    assertEquals(2, result.getHeaders().size());
+    assertEquals(headers, result.getHeaders());
+  }
+
+  @Test
+  public void withSourceIndexTest() {
+    var sourceIndex = 1;
+    var result = SpQueryResultBuilder.create(headers)
+        .withSourceIndex(sourceIndex)
+        .build();
+
+    assertEquals(sourceIndex, result.getSourceIndex());
+  }
+
+  @Test
+  public void withQueryStatusDefaultTest() {
+    var result = SpQueryResultBuilder.create(headers)
+        .build();
+
+    assertEquals(SpQueryStatus.OK, result.getSpQueryStatus());
+  }
+
+  @Test
+  public void withQueryStatusTooMuchDataTest() {
+    var result = SpQueryResultBuilder.create(headers)
+        .withSpQueryStatus(SpQueryStatus.TOO_MUCH_DATA)
+        .build();
+
+    assertEquals(SpQueryStatus.TOO_MUCH_DATA, result.getSpQueryStatus());
+  }
+
+  @Test
+  public void withForId() {
+    var forId = "id";
+    var result = SpQueryResultBuilder.create(headers)
+        .withForId(forId)
+        .build();
+
+    assertEquals(forId, result.getForId());
+  }
+
+  @Test
+  public void withDataSeriesTest() {
+    List<Object> row = List.of("v1", 1);
+
+    var result = SpQueryResultBuilder.create(headers)
+        .withDataSeries(
+            DataSeriesBuilder.create()
+                .withRow(row)
+                .build()
+        )
+        .build();
+
+    assertEquals(1, result.getAllDataSeries().size());
+    assertEquals(1, result.getAllDataSeries().get(0).getRows().size());
+    assertEquals(row, result.getAllDataSeries().get(0).getRows().get(0));
+  }
+
+  @Test
+  public void completeExampleTest() {
+
+    List<String> headers = List.of("timestamp", "id", "value");
+    List<List<Object>> rows = List.of(
+        List.of(1234L, "one", 1.1),
+        List.of(1235L, "two", 1.0)
+    );
+
+    var spQueryResult = SpQueryResultBuilder.create(headers)
+        .withDataSeries(
+            DataSeriesBuilder.create()
+                .withRows(rows)
+                .build()
+        )
+        .build();
+
+    assertEquals(1, spQueryResult.getTotal());
+    assertEquals(headers, spQueryResult.getAllDataSeries().get(0).getHeaders());
+    assertEquals(2, spQueryResult.getAllDataSeries().get(0).getRows().size());
+    assertEquals(rows, spQueryResult.getAllDataSeries().get(0).getRows());
+  }
+}
\ No newline at end of file