View Javadoc
1   package de.dlr.shepard.integrationtests;
2   
3   import static io.restassured.RestAssured.given;
4   import static org.assertj.core.api.Assertions.assertThat;
5   import static org.junit.jupiter.api.Assertions.assertEquals;
6   
7   import de.dlr.shepard.common.search.io.QueryType;
8   import de.dlr.shepard.common.search.io.ResponseBody;
9   import de.dlr.shepard.common.search.io.ResultTriple;
10  import de.dlr.shepard.common.search.io.SearchBody;
11  import de.dlr.shepard.common.search.io.SearchParams;
12  import de.dlr.shepard.common.search.io.SearchScope;
13  import de.dlr.shepard.common.util.Constants;
14  import de.dlr.shepard.common.util.TraversalRules;
15  import de.dlr.shepard.context.collection.io.CollectionIO;
16  import de.dlr.shepard.context.collection.io.DataObjectIO;
17  import de.dlr.shepard.context.references.basicreference.io.BasicReferenceIO;
18  import de.dlr.shepard.context.references.dataobject.io.CollectionReferenceIO;
19  import de.dlr.shepard.context.references.dataobject.io.DataObjectReferenceIO;
20  import de.dlr.shepard.context.references.file.io.FileReferenceIO;
21  import de.dlr.shepard.context.references.structureddata.io.StructuredDataReferenceIO;
22  import de.dlr.shepard.context.references.timeseriesreference.io.TimeseriesReferenceIO;
23  import de.dlr.shepard.data.file.entities.ShepardFile;
24  import de.dlr.shepard.data.file.io.FileContainerIO;
25  import de.dlr.shepard.data.structureddata.entities.StructuredData;
26  import de.dlr.shepard.data.structureddata.entities.StructuredDataPayload;
27  import de.dlr.shepard.data.structureddata.io.StructuredDataContainerIO;
28  import de.dlr.shepard.data.timeseries.io.TimeseriesContainerIO;
29  import de.dlr.shepard.data.timeseries.io.TimeseriesWithDataPoints;
30  import de.dlr.shepard.data.timeseries.model.Timeseries;
31  import de.dlr.shepard.data.timeseries.model.TimeseriesDataPoint;
32  import io.quarkus.test.junit.QuarkusIntegrationTest;
33  import io.restassured.builder.RequestSpecBuilder;
34  import io.restassured.http.ContentType;
35  import io.restassured.specification.RequestSpecification;
36  import java.io.ByteArrayInputStream;
37  import java.io.InputStream;
38  import java.util.ArrayList;
39  import java.util.List;
40  import org.junit.jupiter.api.BeforeAll;
41  import org.junit.jupiter.api.MethodOrderer;
42  import org.junit.jupiter.api.Order;
43  import org.junit.jupiter.api.Test;
44  import org.junit.jupiter.api.TestMethodOrder;
45  
46  @QuarkusIntegrationTest
47  @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
48  public class ReferenceSearcherIT extends BaseTestCaseIT {
49  
50    private static DataObjectIO dataObjectIO1;
51    private static DataObjectIO dataObjectIO2;
52    private static DataObjectIO dataObjectIO3;
53    private static DataObjectIO dataObjectIO4;
54    private static DataObjectIO collection1DataObject;
55    private static DataObjectIO referenced;
56    private static CollectionIO collection;
57    private static CollectionIO collection1;
58    private static String searchURL;
59    private static String dataObjetReferencesURL;
60    private static RequestSpecification fileRequestSpecification;
61    private static BasicReferenceIO referenceIO1;
62    private static BasicReferenceIO referenceIO1a;
63    private static BasicReferenceIO referenceIO4;
64    private static String fileReferencesURL;
65    private static String fileContainerURL;
66    private static FileContainerIO fileContainerIO;
67    private static ShepardFile file;
68    private static FileReferenceIO fileReferenceIO;
69  
70    private static String sDataReferencesURL;
71    private static String sDataContainerURL;
72    private static StructuredDataContainerIO sDataContainer;
73    private static CollectionIO sDataCollection;
74    private static DataObjectIO sDataObject;
75    private static StructuredDataPayload sDataPayload;
76  
77    private static CollectionIO tSerCollection;
78    private static DataObjectIO tSerDataObject;
79    private static String tSerReferencesURL;
80    private static String tSerContainerURL;
81    private static TimeseriesContainerIO tSerContainer;
82    private static TimeseriesReferenceIO tSerReference;
83    private static TimeseriesWithDataPoints timeseriesWithDataPoints;
84    private static int numPoints = 32;
85  
86    @BeforeAll
87    public static void setUp() {
88      collection = createCollection("DataObjectReferenceTestCollection");
89      collection1 = createCollection("ReferencedSearcherTestCollection1");
90      dataObjectIO1 = createDataObject("DataObjectReference1", collection.getId());
91      dataObjectIO2 = createDataObject("DataObjectReference2", collection.getId());
92      DataObjectIO dataObjectIO3ToCreate = new DataObjectIO();
93      dataObjectIO3ToCreate.setCollectionId(collection.getId());
94      dataObjectIO3ToCreate.setName("dataObject3");
95      dataObjectIO3ToCreate.setPredecessorIds(new long[] { dataObjectIO1.getId() });
96      dataObjectIO3 = createDataObject(dataObjectIO3ToCreate);
97      DataObjectIO dataObjectIO4ToCreate = new DataObjectIO();
98      dataObjectIO4ToCreate.setCollectionId(collection.getId());
99      dataObjectIO4ToCreate.setName("dataObject4");
100     dataObjectIO4ToCreate.setPredecessorIds(new long[] { dataObjectIO3.getId() });
101     dataObjectIO4 = createDataObject(dataObjectIO4ToCreate);
102     referenced = createDataObject("ReferencedDataObject", collection.getId());
103     collection1DataObject = createDataObject("collection1DataObject", collection1.getId());
104 
105     var toCreate1 = new DataObjectReferenceIO();
106     toCreate1.setName("DataObjectReferenceDummy1");
107     toCreate1.setRelationship("integrationtests");
108     toCreate1.setReferencedDataObjectId(referenced.getId());
109     dataObjetReferencesURL = "/%s/%d/%s/%d/%s".formatted(
110         Constants.COLLECTIONS,
111         collection.getId(),
112         Constants.DATA_OBJECTS,
113         dataObjectIO1.getId(),
114         Constants.DATAOBJECT_REFERENCES
115       );
116     referenceIO1 = given()
117       .spec(requestSpecOfDefaultUser)
118       .body(toCreate1)
119       .when()
120       .post(dataObjetReferencesURL)
121       .then()
122       .statusCode(201)
123       .extract()
124       .as(DataObjectReferenceIO.class);
125 
126     var toCreate1a = new DataObjectReferenceIO();
127     toCreate1a.setName("DataObjectReferenceDummy1a");
128     toCreate1a.setRelationship("integrationtests");
129     toCreate1a.setReferencedDataObjectId(referenced.getId());
130     referenceIO1a = given()
131       .spec(requestSpecOfDefaultUser)
132       .body(toCreate1a)
133       .when()
134       .post(dataObjetReferencesURL)
135       .then()
136       .statusCode(201)
137       .extract()
138       .as(DataObjectReferenceIO.class);
139     searchURL = "/" + Constants.SEARCH;
140 
141     var toCreate4 = new DataObjectReferenceIO();
142     toCreate4.setName("DataObjectReferenceDummy4");
143     toCreate4.setRelationship("integrationtests");
144     toCreate4.setReferencedDataObjectId(dataObjectIO4.getId());
145     dataObjetReferencesURL = "/%s/%d/%s/%d/%s".formatted(
146         Constants.COLLECTIONS,
147         collection.getId(),
148         Constants.DATA_OBJECTS,
149         dataObjectIO4.getId(),
150         Constants.DATAOBJECT_REFERENCES
151       );
152     referenceIO4 = given()
153       .spec(requestSpecOfDefaultUser)
154       .body(toCreate4)
155       .when()
156       .post(dataObjetReferencesURL)
157       .then()
158       .statusCode(201)
159       .extract()
160       .as(DataObjectReferenceIO.class);
161 
162     fileReferencesURL = "/%s/%d/%s/%d/%s".formatted(
163         Constants.COLLECTIONS,
164         collection.getId(),
165         Constants.DATA_OBJECTS,
166         dataObjectIO2.getId(),
167         Constants.FILE_REFERENCES
168       );
169     fileContainerURL = "/" + Constants.FILE_CONTAINERS;
170     var fileContainerToCreate = new FileContainerIO();
171     fileContainerToCreate.setName("FileContainer");
172     InputStream targetStream = new ByteArrayInputStream("Hello World!".getBytes());
173     fileContainerIO = given()
174       .spec(requestSpecOfDefaultUser)
175       .body(fileContainerToCreate)
176       .when()
177       .post(fileContainerURL)
178       .then()
179       .statusCode(201)
180       .extract()
181       .as(FileContainerIO.class);
182     fileRequestSpecification = new RequestSpecBuilder()
183       .setContentType(ContentType.MULTIPART)
184       .addHeader("X-API-KEY", defaultUser.getApiKey().getJws())
185       .build();
186     file = given()
187       .spec(fileRequestSpecification)
188       .multiPart("file", "test.txt", targetStream)
189       .when()
190       .post("%s/%d/%s".formatted(fileContainerURL, fileContainerIO.getId(), Constants.PAYLOAD))
191       .then()
192       .statusCode(201)
193       .extract()
194       .as(ShepardFile.class);
195     var fileReferenceToCreate = new FileReferenceIO();
196     fileReferenceToCreate.setName("FileReferenceDummy");
197     fileReferenceToCreate.setFileOids(new String[] { file.getOid() });
198     fileReferenceToCreate.setFileContainerId(fileContainerIO.getId());
199     fileReferenceIO = given()
200       .spec(requestSpecOfDefaultUser)
201       .body(fileReferenceToCreate)
202       .when()
203       .post(fileReferencesURL)
204       .then()
205       .statusCode(201)
206       .extract()
207       .as(FileReferenceIO.class);
208 
209     searchURL = "/" + Constants.SEARCH;
210   }
211 
212   @Test
213   @Order(1)
214   public void findReferenceWithoutTraveralRulesTest() {
215     SearchBody searchBody = new SearchBody();
216     SearchScope searchScope = new SearchScope();
217     searchScope.setCollectionId(collection.getId());
218     searchScope.setDataObjectId(dataObjectIO1.getId());
219     searchScope.setTraversalRules(new TraversalRules[] {});
220     searchBody.setScopes(new SearchScope[] { searchScope });
221     SearchParams searchParams = new SearchParams();
222     searchParams.setQueryType(QueryType.Reference);
223     String query =
224       """
225       {
226             "property": "id",
227             "value": %d,
228             "operator": "eq"
229           }
230       """.formatted(referenceIO1.getId());
231     searchParams.setQuery(query);
232     searchBody.setSearchParams(searchParams);
233     var result = given()
234       .spec(requestSpecOfDefaultUser)
235       .body(searchBody)
236       .when()
237       .post(searchURL)
238       .then()
239       .statusCode(200)
240       .extract()
241       .as(ResponseBody.class);
242     ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), referenceIO1.getId());
243     assertThat(result.getResultSet()).contains(triple1);
244     assertThat(result.getResults()[0].getId()).isEqualTo(referenceIO1.getId());
245     assertThat(result.getSearchParams()).isEqualTo(searchParams);
246   }
247 
248   @Test
249   @Order(2)
250   public void findNoReferenceWithoutTraveralRulesTest() {
251     SearchBody searchBody = new SearchBody();
252     SearchScope searchScope = new SearchScope();
253     searchScope.setCollectionId(collection.getId());
254     searchScope.setDataObjectId(dataObjectIO2.getId());
255     searchScope.setTraversalRules(new TraversalRules[] {});
256     searchBody.setScopes(new SearchScope[] { searchScope });
257     SearchParams searchParams = new SearchParams();
258     searchParams.setQueryType(QueryType.Reference);
259     String query =
260       """
261       	{
262             "property": "id",
263             "value": %d,
264             "operator": "eq"
265           }
266       """.formatted(referenceIO1.getId());
267     searchParams.setQuery(query);
268     searchBody.setSearchParams(searchParams);
269     var result = given()
270       .spec(requestSpecOfDefaultUser)
271       .body(searchBody)
272       .when()
273       .post(searchURL)
274       .then()
275       .statusCode(200)
276       .extract()
277       .as(ResponseBody.class);
278     assertEquals(0, result.getResultSet().length);
279   }
280 
281   @Test
282   @Order(3)
283   public void findTwoReferencesWithoutTraveralRulesTest() {
284     SearchBody searchBody = new SearchBody();
285     SearchScope searchScope = new SearchScope();
286     searchScope.setCollectionId(collection.getId());
287     searchScope.setDataObjectId(dataObjectIO1.getId());
288     searchScope.setTraversalRules(new TraversalRules[] {});
289     searchBody.setScopes(new SearchScope[] { searchScope });
290     SearchParams searchParams = new SearchParams();
291     searchParams.setQueryType(QueryType.Reference);
292     String query =
293       """
294       	{
295             "property": "name",
296             "value": "ummy",
297             "operator": "contains"
298           }
299       """;
300     searchParams.setQuery(query);
301     searchBody.setSearchParams(searchParams);
302     var result = given()
303       .spec(requestSpecOfDefaultUser)
304       .body(searchBody)
305       .when()
306       .post(searchURL)
307       .then()
308       .statusCode(200)
309       .extract()
310       .as(ResponseBody.class);
311     ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), referenceIO1.getId());
312     ResultTriple triple1a = new ResultTriple(collection.getId(), dataObjectIO1.getId(), referenceIO1a.getId());
313     assertThat(result.getResultSet()).contains(triple1, triple1a);
314   }
315 
316   @Test
317   @Order(4)
318   public void findReferenceViaSuccessorsTest() {
319     SearchBody searchBody = new SearchBody();
320     SearchScope searchScope = new SearchScope();
321     searchScope.setCollectionId(collection.getId());
322     searchScope.setDataObjectId(dataObjectIO1.getId());
323     searchScope.setTraversalRules(new TraversalRules[] { TraversalRules.successors });
324     searchBody.setScopes(new SearchScope[] { searchScope });
325     SearchParams searchParams = new SearchParams();
326     searchParams.setQueryType(QueryType.Reference);
327     String query =
328       """
329       	{
330             "property": "name",
331             "value": "ummy",
332             "operator": "contains"
333           }
334       """;
335     searchParams.setQuery(query);
336     searchBody.setSearchParams(searchParams);
337     var result = given()
338       .spec(requestSpecOfDefaultUser)
339       .body(searchBody)
340       .when()
341       .post(searchURL)
342       .then()
343       .statusCode(200)
344       .extract()
345       .as(ResponseBody.class);
346     ResultTriple triple4 = new ResultTriple(collection.getId(), dataObjectIO4.getId(), referenceIO4.getId());
347     assertThat(result.getResultSet()).contains(triple4);
348   }
349 
350   @Test
351   @Order(5)
352   public void findViaReferencedDataObjectTest() {
353     SearchBody searchBody = new SearchBody();
354     SearchScope searchScope = new SearchScope();
355     searchScope.setTraversalRules(new TraversalRules[] {});
356     searchBody.setScopes(new SearchScope[] { searchScope });
357     SearchParams searchParams = new SearchParams();
358     searchParams.setQueryType(QueryType.Reference);
359     String query =
360       """
361       {
362             "property": "referencedDataObjectId",
363             "value": %d,
364             "operator": "eq"
365           }
366       """.formatted(dataObjectIO4.getId());
367     searchParams.setQuery(query);
368     searchBody.setSearchParams(searchParams);
369     var result = given()
370       .spec(requestSpecOfDefaultUser)
371       .body(searchBody)
372       .when()
373       .post(searchURL)
374       .then()
375       .statusCode(200)
376       .extract()
377       .as(ResponseBody.class);
378     ResultTriple triple4 = new ResultTriple(collection.getId(), dataObjectIO4.getId(), referenceIO4.getId());
379     assertThat(result.getResultSet()).contains(triple4);
380   }
381 
382   @Test
383   @Order(6)
384   public void findViaFileContainerTest() {
385     SearchBody searchBody = new SearchBody();
386     SearchScope searchScope = new SearchScope();
387     searchScope.setTraversalRules(new TraversalRules[] {});
388     searchBody.setScopes(new SearchScope[] { searchScope });
389     SearchParams searchParams = new SearchParams();
390     searchParams.setQueryType(QueryType.Reference);
391     String query =
392       """
393       {
394             "property": "fileContainerId",
395             "value": %d,
396             "operator": "eq"
397           }
398       """.formatted(fileContainerIO.getId());
399     searchParams.setQuery(query);
400     searchBody.setSearchParams(searchParams);
401     var result = given()
402       .spec(requestSpecOfDefaultUser)
403       .body(searchBody)
404       .when()
405       .post(searchURL)
406       .then()
407       .statusCode(200)
408       .extract()
409       .as(ResponseBody.class);
410     ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), fileReferenceIO.getId());
411     assertThat(result.getResultSet()).contains(triple2);
412   }
413 
414   @Test
415   @Order(7)
416   public void findViaReferencedCollectionTest() {
417     CollectionReferenceIO toCreate = new CollectionReferenceIO();
418     toCreate.setName("CollectionReferenceDummy");
419     toCreate.setRelationship("integrationtests");
420     toCreate.setReferencedCollectionId(collection1.getId());
421     String referencesURL =
422       "/%s/%d/%s/%d/%s".formatted(
423           Constants.COLLECTIONS,
424           collection1.getId(),
425           Constants.DATA_OBJECTS,
426           collection1DataObject.getId(),
427           Constants.COLLECTION_REFERENCES
428         );
429     CollectionReferenceIO createdCollectionReference = given()
430       .spec(requestSpecOfDefaultUser)
431       .body(toCreate)
432       .when()
433       .post(referencesURL)
434       .then()
435       .statusCode(201)
436       .extract()
437       .as(CollectionReferenceIO.class);
438 
439     SearchBody searchBody = new SearchBody();
440     SearchScope searchScope = new SearchScope();
441     searchScope.setTraversalRules(new TraversalRules[] {});
442     searchBody.setScopes(new SearchScope[] { searchScope });
443     SearchParams searchParams = new SearchParams();
444     searchParams.setQueryType(QueryType.Reference);
445     String query =
446       """
447       {
448             "property": "referencedCollectionId",
449             "value": %d,
450             "operator": "eq"
451           }
452       """.formatted(collection1.getId());
453     searchParams.setQuery(query);
454     searchBody.setSearchParams(searchParams);
455     var result = given()
456       .spec(requestSpecOfDefaultUser)
457       .body(searchBody)
458       .when()
459       .post(searchURL)
460       .then()
461       .statusCode(200)
462       .extract()
463       .as(ResponseBody.class);
464     ResultTriple triple2 = new ResultTriple(
465       collection1.getId(),
466       collection1DataObject.getId(),
467       createdCollectionReference.getId()
468     );
469     assertThat(result.getResultSet()).contains(triple2);
470   }
471 
472   @Test
473   @Order(8)
474   public void dontFindViaReferencedCollectionTest() {
475     SearchBody searchBody = new SearchBody();
476     SearchScope searchScope = new SearchScope();
477     searchScope.setTraversalRules(new TraversalRules[] {});
478     searchBody.setScopes(new SearchScope[] { searchScope });
479     SearchParams searchParams = new SearchParams();
480     searchParams.setQueryType(QueryType.Reference);
481     String query =
482       """
483       {
484             "property": "referencedCollectionId",
485             "value": %d,
486             "operator": "eq"
487           }
488       """.formatted(collection.getId());
489     searchParams.setQuery(query);
490     searchBody.setSearchParams(searchParams);
491     var result = given()
492       .spec(requestSpecOfDefaultUser)
493       .body(searchBody)
494       .when()
495       .post(searchURL)
496       .then()
497       .statusCode(200)
498       .extract()
499       .as(ResponseBody.class);
500     assertEquals(0, result.getResultSet().length);
501   }
502 
503   @Test
504   @Order(9)
505   public void findViaStructuredDataTest() {
506     sDataCollection = createCollection("StructuredDataReferenceTestCollection");
507     sDataObject = createDataObject("StructuredDataReferenceTestDataObject", sDataCollection.getId());
508     sDataReferencesURL = "/%s/%d/%s/%d/%s".formatted(
509         Constants.COLLECTIONS,
510         sDataCollection.getId(),
511         Constants.DATA_OBJECTS,
512         sDataObject.getId(),
513         Constants.STRUCTURED_DATA_REFERENCES
514       );
515     sDataContainerURL = "/" + Constants.STRUCTURED_DATA_CONTAINERS;
516     StructuredDataContainerIO sDataContainerToCreate = new StructuredDataContainerIO();
517     sDataContainerToCreate.setName("StructuredDataContainer");
518     sDataContainer = given()
519       .spec(requestSpecOfDefaultUser)
520       .body(sDataContainerToCreate)
521       .when()
522       .post(sDataContainerURL)
523       .then()
524       .statusCode(201)
525       .extract()
526       .as(StructuredDataContainerIO.class);
527     StructuredData structuredData = new StructuredData();
528     structuredData.setName("My Structured Data");
529     sDataPayload = new StructuredDataPayload(
530       structuredData,
531       "{\"Hallo\":\"Welt\",\"number\":123,\"list\":[\"a\",\"b\"],\"object\":{\"a\":\"b\"}}"
532     );
533     StructuredData actual = given()
534       .spec(requestSpecOfDefaultUser)
535       .body(sDataPayload)
536       .when()
537       .post("%s/%d/%s".formatted(sDataContainerURL, sDataContainer.getId(), Constants.PAYLOAD))
538       .then()
539       .statusCode(201)
540       .extract()
541       .as(StructuredData.class);
542     sDataPayload.setStructuredData(actual);
543     StructuredDataReferenceIO sDataReferenceToCreate = new StructuredDataReferenceIO();
544     sDataReferenceToCreate.setName("StructuredDataReferenceDummy");
545     sDataReferenceToCreate.setStructuredDataOids(new String[] { sDataPayload.getStructuredData().getOid() });
546     sDataReferenceToCreate.setStructuredDataContainerId(sDataContainer.getId());
547     StructuredDataReferenceIO sDataReference = given()
548       .spec(requestSpecOfDefaultUser)
549       .body(sDataReferenceToCreate)
550       .when()
551       .post(sDataReferencesURL)
552       .then()
553       .statusCode(201)
554       .extract()
555       .as(StructuredDataReferenceIO.class);
556 
557     SearchBody searchBody = new SearchBody();
558     SearchScope searchScope = new SearchScope();
559     searchScope.setTraversalRules(new TraversalRules[] {});
560     searchBody.setScopes(new SearchScope[] { searchScope });
561     SearchParams searchParams = new SearchParams();
562     searchParams.setQueryType(QueryType.Reference);
563     String query =
564       """
565       {
566             "property": "structuredDataContainerId",
567             "value": %d,
568             "operator": "eq"
569           }
570       """.formatted(sDataContainer.getId());
571     searchParams.setQuery(query);
572     searchBody.setSearchParams(searchParams);
573     var result = given()
574       .spec(requestSpecOfDefaultUser)
575       .body(searchBody)
576       .when()
577       .post(searchURL)
578       .then()
579       .statusCode(200)
580       .extract()
581       .as(ResponseBody.class);
582     ResultTriple triple = new ResultTriple(sDataCollection.getId(), sDataObject.getId(), sDataReference.getId());
583     assertThat(result.getResultSet()).contains(triple);
584   }
585 
586   @Test
587   @Order(10)
588   public void findViaTimeseriesTest() {
589     tSerCollection = createCollection("TimeseriesReferenceSearchTestCollection");
590     tSerDataObject = createDataObject("TimeseriesReferenceSearchTestDataObject", tSerCollection.getId());
591     tSerReferencesURL = "/%s/%d/%s/%d/%s".formatted(
592         Constants.COLLECTIONS,
593         tSerCollection.getId(),
594         Constants.DATA_OBJECTS,
595         tSerDataObject.getId(),
596         Constants.TIMESERIES_REFERENCES
597       );
598     tSerContainerURL = "/" + Constants.TIMESERIES_CONTAINERS;
599     var tSerContainerToCreate = new TimeseriesContainerIO();
600     tSerContainerToCreate.setName("TimeseriesContainer");
601     tSerContainer = given()
602       .spec(requestSpecOfDefaultUser)
603       .body(tSerContainerToCreate)
604       .when()
605       .post(tSerContainerURL)
606       .then()
607       .statusCode(201)
608       .extract()
609       .as(TimeseriesContainerIO.class);
610     var currentTime = System.currentTimeMillis() * 1000000;
611     var slice = (2f * Math.PI) / (numPoints - 1);
612     List<TimeseriesDataPoint> dataPoints = new ArrayList<>();
613     for (int i = 0; i < numPoints; i++) {
614       var offset = i * 1000000000L;
615       var point = new TimeseriesDataPoint(currentTime + offset, Math.sin(slice * i));
616       dataPoints.add(point);
617     }
618     timeseriesWithDataPoints = new TimeseriesWithDataPoints(
619       new Timeseries("meas", "dev", "loc", "symName", "field"),
620       dataPoints
621     );
622 
623     given()
624       .spec(requestSpecOfDefaultUser)
625       .body(timeseriesWithDataPoints)
626       .when()
627       .post("%s/%d/%s".formatted(tSerContainerURL, tSerContainer.getId(), Constants.PAYLOAD))
628       .then()
629       .statusCode(201);
630     var nanos = timeseriesWithDataPoints.getPoints().getFirst().getTimestamp();
631     var tSerReferenceToCreate = new TimeseriesReferenceIO();
632     tSerReferenceToCreate.setName("TimeseriesReferenceDummy");
633     tSerReferenceToCreate.setStart(nanos - 1000000000L);
634     tSerReferenceToCreate.setEnd(nanos + 1000000000L * numPoints);
635     tSerReferenceToCreate.setTimeseries(List.of(timeseriesWithDataPoints.getTimeseries()));
636     tSerReferenceToCreate.setTimeseriesContainerId(tSerContainer.getId());
637     tSerReference = given()
638       .spec(requestSpecOfDefaultUser)
639       .body(tSerReferenceToCreate)
640       .when()
641       .post(tSerReferencesURL)
642       .then()
643       .statusCode(201)
644       .extract()
645       .as(TimeseriesReferenceIO.class);
646 
647     SearchBody searchBody = new SearchBody();
648     SearchScope searchScope = new SearchScope();
649     searchScope.setTraversalRules(new TraversalRules[] {});
650     searchBody.setScopes(new SearchScope[] { searchScope });
651     SearchParams searchParams = new SearchParams();
652     searchParams.setQueryType(QueryType.Reference);
653     String query =
654       """
655       {
656             "property": "timeseriesContainerId",
657             "value": %d,
658             "operator": "eq"
659           }
660       """.formatted(tSerContainer.getId());
661     searchParams.setQuery(query);
662     searchBody.setSearchParams(searchParams);
663     var result = given()
664       .spec(requestSpecOfDefaultUser)
665       .body(searchBody)
666       .when()
667       .post(searchURL)
668       .then()
669       .statusCode(200)
670       .extract()
671       .as(ResponseBody.class);
672     ResultTriple triple = new ResultTriple(tSerCollection.getId(), tSerDataObject.getId(), tSerReference.getId());
673     assertThat(result.getResultSet()).contains(triple);
674   }
675 
676   private static DataObjectIO createDataObject(DataObjectIO dataObjectIO) {
677     var dataObjectsURL =
678       "/%s/%d/%s/".formatted(Constants.COLLECTIONS, dataObjectIO.getCollectionId(), Constants.DATA_OBJECTS);
679     var createdDataObject = given()
680       .spec(requestSpecOfDefaultUser)
681       .body(dataObjectIO)
682       .when()
683       .post(dataObjectsURL)
684       .then()
685       .statusCode(201)
686       .extract()
687       .as(DataObjectIO.class);
688     return createdDataObject;
689   }
690 }