View Javadoc
1   package de.dlr.shepard.common.search.services;
2   
3   import static org.junit.jupiter.api.Assertions.assertEquals;
4   import static org.junit.jupiter.api.Assertions.assertThrows;
5   
6   import de.dlr.shepard.auth.security.AuthenticationContext;
7   import de.dlr.shepard.auth.security.JWTPrincipal;
8   import de.dlr.shepard.auth.users.entities.User;
9   import de.dlr.shepard.auth.users.services.UserService;
10  import de.dlr.shepard.common.exceptions.ShepardParserException;
11  import de.dlr.shepard.common.search.io.ResponseBody;
12  import de.dlr.shepard.common.search.io.SearchBody;
13  import de.dlr.shepard.common.search.io.SearchParams;
14  import de.dlr.shepard.common.search.io.SearchScope;
15  import de.dlr.shepard.common.util.TraversalRules;
16  import de.dlr.shepard.context.collection.entities.Collection;
17  import de.dlr.shepard.context.collection.entities.DataObject;
18  import de.dlr.shepard.context.collection.io.CollectionIO;
19  import de.dlr.shepard.context.collection.io.DataObjectIO;
20  import de.dlr.shepard.context.collection.services.CollectionService;
21  import de.dlr.shepard.context.collection.services.DataObjectService;
22  import de.dlr.shepard.context.references.timeseriesreference.io.TimeseriesReferenceIO;
23  import de.dlr.shepard.context.references.timeseriesreference.model.TimeseriesReference;
24  import de.dlr.shepard.context.references.timeseriesreference.services.TimeseriesReferenceService;
25  import de.dlr.shepard.context.semantic.SemanticRepositoryType;
26  import de.dlr.shepard.context.semantic.entities.SemanticRepository;
27  import de.dlr.shepard.context.semantic.io.SemanticAnnotationIO;
28  import de.dlr.shepard.context.semantic.io.SemanticRepositoryIO;
29  import de.dlr.shepard.context.semantic.services.AnnotatableTimeseriesService;
30  import de.dlr.shepard.context.semantic.services.SemanticAnnotationService;
31  import de.dlr.shepard.context.semantic.services.SemanticRepositoryService;
32  import de.dlr.shepard.data.timeseries.io.TimeseriesContainerIO;
33  import de.dlr.shepard.data.timeseries.model.Timeseries;
34  import de.dlr.shepard.data.timeseries.model.TimeseriesContainer;
35  import de.dlr.shepard.data.timeseries.model.TimeseriesDataPoint;
36  import de.dlr.shepard.data.timeseries.model.TimeseriesEntity;
37  import de.dlr.shepard.data.timeseries.services.TimeseriesContainerService;
38  import de.dlr.shepard.data.timeseries.services.TimeseriesService;
39  import de.dlr.shepard.integrationtests.WireMockResource;
40  import io.quarkus.test.common.WithTestResource;
41  import io.quarkus.test.junit.QuarkusTest;
42  import jakarta.inject.Inject;
43  import jakarta.transaction.Transactional;
44  import java.util.ArrayList;
45  import java.util.List;
46  import org.junit.jupiter.api.BeforeEach;
47  import org.junit.jupiter.api.Test;
48  
49  @QuarkusTest
50  @WithTestResource(WireMockResource.class)
51  public class ReferenceSearchServiceQuarkusTest {
52  
53    @Inject
54    CollectionService collectionService;
55  
56    @Inject
57    DataObjectService dataObjectService;
58  
59    @Inject
60    ReferenceSearchService referenceSearcher;
61  
62    @Inject
63    TimeseriesReferenceService timeseriesReferenceService;
64  
65    @Inject
66    TimeseriesService timeseriesService;
67  
68    @Inject
69    AnnotatableTimeseriesService annotatableTimeseriesService;
70  
71    @Inject
72    SemanticRepositoryService semanticRepositoryService;
73  
74    @Inject
75    TimeseriesContainerService timeseriesContainerService;
76  
77    @Inject
78    AuthenticationContext authenticationContext;
79  
80    @Inject
81    UserService userService;
82  
83    @Inject
84    SemanticAnnotationService semanticAnnotationService;
85  
86    private static Collection collection1;
87    private static DataObject dataObjectc1d1;
88    private static TimeseriesReference annoReference;
89    private static TimeseriesReference noAnnoReference;
90    private static TimeseriesContainer tsCon;
91    private static TimeseriesEntity timeseriesEntity1;
92    private static TimeseriesEntity timeseriesEntity2;
93    private static SemanticRepository repository;
94    private static User user;
95    private static SemanticAnnotationIO AnnoToCreate;
96    private static String username = "username";
97    private static SearchScope scope;
98    private static SearchBody body;
99    private static SearchParams params;
100   private static String query;
101   private static ResponseBody response;
102 
103   @BeforeEach
104   public void setUp() {
105     //create user
106     if (user == null) {
107       User user = new User(username);
108       userService.createOrUpdateUser(user);
109       authenticationContext.setPrincipal(new JWTPrincipal(username, "key"));
110     }
111     //create collection
112     if (collection1 == null) {
113       CollectionIO collection1IO = new CollectionIO();
114       collection1IO.setName("collection1" + System.currentTimeMillis());
115       collection1 = collectionService.createCollection(collection1IO);
116     }
117     //create dataobject
118     if (dataObjectc1d1 == null) {
119       DataObjectIO dataObjectc1d1IO = new DataObjectIO();
120       dataObjectc1d1IO.setName("c1do1" + System.currentTimeMillis());
121       dataObjectc1d1 = dataObjectService.createDataObject(collection1.getShepardId(), dataObjectc1d1IO);
122     }
123     //create timeseriesContainer with content
124     if (tsCon == null) {
125       //create container
126       TimeseriesContainerIO tsConIO = new TimeseriesContainerIO();
127       tsConIO.setName("container");
128       tsCon = timeseriesContainerService.createContainer(tsConIO);
129       //create two timeseries
130       TimeseriesDataPoint dataPoint = new TimeseriesDataPoint(4l, true);
131       List<TimeseriesDataPoint> points = new ArrayList<TimeseriesDataPoint>();
132       points.add(dataPoint);
133       Timeseries ts1 = new Timeseries("m1", "d1", "l1", "s1", "f1");
134       Timeseries ts2 = new Timeseries("m2", "d2", "l2", "s2", "f2");
135       timeseriesEntity1 = timeseriesService.saveDataPoints(tsCon.getId(), ts1, points);
136       timeseriesEntity2 = timeseriesService.saveDataPoints(tsCon.getId(), ts2, points);
137       //create annotation for first timeseries
138       SemanticRepositoryIO repToCreate = new SemanticRepositoryIO();
139       repToCreate.setName("SemanticRepository");
140       repToCreate.setType(SemanticRepositoryType.SPARQL);
141       repToCreate.setEndpoint(WireMockResource.getWireMockServerURlWithPath("/sparql"));
142       repository = semanticRepositoryService.createRepository(repToCreate);
143       //create Reference on annotated Timeseries
144       TimeseriesReferenceIO ref1IO = new TimeseriesReferenceIO();
145       ref1IO.setName("refAnno");
146       ref1IO.setStart(0l);
147       ref1IO.setEnd(9l);
148       List<Timeseries> timeseries1 = new ArrayList<Timeseries>();
149       timeseries1.add(ts1);
150       ref1IO.setTimeseries(timeseries1);
151       ref1IO.setTimeseriesContainerId(tsCon.getId());
152       annoReference = timeseriesReferenceService.createReference(
153         collection1.getShepardId(),
154         dataObjectc1d1.getShepardId(),
155         ref1IO
156       );
157       //create Reference on timeseries without annotation
158       TimeseriesReferenceIO ref2IO = new TimeseriesReferenceIO();
159       ref2IO.setName("refWithoutAnno");
160       ref2IO.setStart(0l);
161       ref2IO.setEnd(9l);
162       List<Timeseries> timeseries2 = new ArrayList<Timeseries>();
163       timeseries2.add(ts2);
164       ref2IO.setTimeseries(timeseries2);
165       ref2IO.setTimeseriesContainerId(tsCon.getId());
166       annoReference = timeseriesReferenceService.createReference(
167         collection1.getShepardId(),
168         dataObjectc1d1.getShepardId(),
169         ref2IO
170       );
171     }
172     if (AnnoToCreate == null) {
173       AnnoToCreate = new SemanticAnnotationIO();
174       AnnoToCreate.setPropertyIRI("http://dbpedia.org/ontology/ingredient");
175       AnnoToCreate.setPropertyRepositoryId(repository.getId());
176       AnnoToCreate.setValueIRI("http://dbpedia.org/resource/Almond_milk");
177       AnnoToCreate.setValueRepositoryId(repository.getId());
178       semanticAnnotationService.createAnnotationByShepardId(annoReference.getId(), AnnoToCreate);
179     }
180     if (scope == null) scope = new SearchScope();
181     if (body == null) {
182       body = new SearchBody();
183       TraversalRules[] rules = {};
184       scope.setTraversalRules(rules);
185     }
186     if (params == null) params = new SearchParams();
187   }
188 
189   @Test
190   @Transactional
191   public void findNoReference() {
192     scope.setCollectionId(collection1.getShepardId());
193     scope.setDataObjectId(dataObjectc1d1.getShepardId());
194     SearchScope[] scopes = { scope };
195     query = "{\"property\": \"hasAnnotation\", \"value\": \"ingre.*::Almon.*\", \"operator\": \"eq\"}";
196     params.setQuery(query);
197     body.setSearchParams(params);
198     body.setScopes(scopes);
199     response = referenceSearcher.search(body);
200     assertEquals(0, response.getResults().length);
201   }
202 
203   @Test
204   @Transactional
205   public void findExactlyOneReferenceByeIRIEquality() {
206     scope.setCollectionId(collection1.getShepardId());
207     scope.setDataObjectId(dataObjectc1d1.getShepardId());
208     SearchScope[] scopes = { scope };
209     query =
210       "{\"property\": \"hasAnnotationIRI\", \"value\": \"http://dbpedia.org/ontology/ingredient::http://dbpedia.org/resource/Almond_milk\", \"operator\": \"eq\"}";
211     params.setQuery(query);
212     body.setSearchParams(params);
213     body.setScopes(scopes);
214     response = referenceSearcher.search(body);
215     assertEquals(1, response.getResults().length);
216     assertEquals(annoReference.getId(), response.getResultSet()[0].getReferenceId());
217   }
218 
219   @Test
220   @Transactional
221   public void findByPropertyIRIContains() {
222     scope.setCollectionId(collection1.getShepardId());
223     scope.setDataObjectId(dataObjectc1d1.getShepardId());
224     SearchScope[] scopes = { scope };
225     query = "{\"property\": \"propertyIRI\", \"value\": \"dbpedia\", \"operator\": \"contains\"}";
226     params.setQuery(query);
227     body.setSearchParams(params);
228     body.setScopes(scopes);
229     response = referenceSearcher.search(body);
230     assertEquals(true, response.getResults().length > 0);
231     //assertEquals(annoReference.getId(), response.getResultSet()[0].getReferenceId());
232   }
233 
234   @Test
235   @Transactional
236   public void findByValueIRIContains() {
237     scope.setCollectionId(collection1.getShepardId());
238     scope.setDataObjectId(dataObjectc1d1.getShepardId());
239     SearchScope[] scopes = { scope };
240     query = "{\"property\": \"valueIRI\", \"value\": \"Almond\", \"operator\": \"contains\"}";
241     params.setQuery(query);
242     body.setSearchParams(params);
243     body.setScopes(scopes);
244     response = referenceSearcher.search(body);
245     assertEquals(true, response.getResults().length > 0);
246     //assertEquals(annoReference.getId(), response.getResultSet()[0].getReferenceId());
247   }
248 
249   @Test
250   @Transactional
251   public void findExactlyOneReferenceByeAnnotationRegMatch() {
252     scope.setCollectionId(collection1.getShepardId());
253     scope.setDataObjectId(dataObjectc1d1.getShepardId());
254     SearchScope[] scopes = { scope };
255     query = "{\"property\": \"hasAnnotation\", \"value\": \"ingre.*::Almon.*\", \"operator\": \"regmatch\"}";
256     body.setScopes(scopes);
257     params.setQuery(query);
258     body.setSearchParams(params);
259     ResponseBody response = referenceSearcher.search(body);
260     assertEquals(1, response.getResults().length);
261     assertEquals(annoReference.getId(), response.getResultSet()[0].getReferenceId());
262   }
263 
264   @Test
265   @Transactional
266   public void provokeExceptionByInvalidAnnotationIRI() {
267     scope.setCollectionId(collection1.getShepardId());
268     scope.setDataObjectId(dataObjectc1d1.getShepardId());
269     TraversalRules[] rules = {};
270     scope.setTraversalRules(rules);
271     SearchScope[] scopes = { scope };
272     String wrongAnnotation = "http://dbpedia.org/ontology/ingredienthttp://dbpedia.org/resource/Almond_milk";
273     query = "{\"property\": \"hasAnnotationIRI\", \"value\": \"" + wrongAnnotation + "\", \"operator\": \"eq\"}";
274     body.setScopes(scopes);
275     SearchParams params = new SearchParams();
276     params.setQuery(query);
277     body.setSearchParams(params);
278     assertThrows(ShepardParserException.class, () -> referenceSearcher.search(body));
279   }
280 
281   @Test
282   @Transactional
283   public void provokeExceptionByTooManyDoubleColons() {
284     scope.setCollectionId(collection1.getShepardId());
285     scope.setDataObjectId(dataObjectc1d1.getShepardId());
286     TraversalRules[] rules = {};
287     scope.setTraversalRules(rules);
288     SearchScope[] scopes = { scope };
289     String wrongAnnotation = "::B::";
290     query = "{\"property\": \"hasAnnotationIRI\", \"value\": \"" + wrongAnnotation + "\", \"operator\": \"eq\"}";
291     body.setScopes(scopes);
292     SearchParams params = new SearchParams();
293     params.setQuery(query);
294     body.setSearchParams(params);
295     assertThrows(ShepardParserException.class, () -> referenceSearcher.search(body));
296   }
297 
298   @Test
299   @Transactional
300   public void provokeExceptionByThreeConsecutiveColons() {
301     scope.setCollectionId(collection1.getShepardId());
302     scope.setDataObjectId(dataObjectc1d1.getShepardId());
303     TraversalRules[] rules = {};
304     scope.setTraversalRules(rules);
305     SearchScope[] scopes = { scope };
306     String wrongAnnotation = ":::";
307     query = "{\"property\": \"hasAnnotationIRI\", \"value\": \"" + wrongAnnotation + "\", \"operator\": \"eq\"}";
308     body.setScopes(scopes);
309     SearchParams params = new SearchParams();
310     params.setQuery(query);
311     body.setSearchParams(params);
312     assertThrows(ShepardParserException.class, () -> referenceSearcher.search(body));
313   }
314 }