View Javadoc
1   package de.dlr.shepard.context.references.timeseriesreference.services;
2   
3   import de.dlr.shepard.context.collection.services.DataObjectService;
4   import de.dlr.shepard.context.references.timeseriesreference.io.MetricsIO;
5   import de.dlr.shepard.context.references.timeseriesreference.model.TimeseriesReference;
6   import de.dlr.shepard.data.timeseries.model.TimeseriesDataPointsQueryParams;
7   import de.dlr.shepard.data.timeseries.model.TimeseriesTuple;
8   import de.dlr.shepard.data.timeseries.model.enums.AggregateFunction;
9   import de.dlr.shepard.data.timeseries.model.enums.DataPointValueType;
10  import de.dlr.shepard.data.timeseries.repositories.TimeseriesDataPointRepository;
11  import de.dlr.shepard.data.timeseries.services.TimeseriesService;
12  import io.quarkus.logging.Log;
13  import jakarta.enterprise.context.RequestScoped;
14  import jakarta.inject.Inject;
15  import jakarta.ws.rs.NotFoundException;
16  import java.util.List;
17  import java.util.UUID;
18  import java.util.stream.Collectors;
19  
20  @RequestScoped
21  public class TimeseriesReferenceMetricsService {
22  
23    @Inject
24    TimeseriesService timeseriesService;
25  
26    @Inject
27    TimeseriesDataPointRepository timeseriesDataPointRepository;
28  
29    @Inject
30    TimeseriesReferenceService timeseriesReferenceService;
31  
32    @Inject
33    DataObjectService dataObjectService;
34  
35    public List<MetricsIO> getTimeseriesReferenceMetrics(
36      long collectionId,
37      long dataObjectId,
38      long timeseriesReferenceId,
39      UUID versionUID,
40      TimeseriesTuple timeseries
41    ) {
42      return getTimeseriesReferenceMetrics(
43        collectionId,
44        dataObjectId,
45        timeseriesReferenceId,
46        versionUID,
47        timeseries,
48        List.of(
49          AggregateFunction.COUNT,
50          AggregateFunction.MAX,
51          AggregateFunction.MIN,
52          AggregateFunction.STDDEV,
53          AggregateFunction.MEAN,
54          AggregateFunction.MEDIAN,
55          AggregateFunction.FIRST,
56          AggregateFunction.LAST
57        )
58      );
59    }
60  
61    public List<MetricsIO> getTimeseriesReferenceMetrics(
62      long collectionId,
63      long dataObjectId,
64      long timeseriesReferenceId,
65      UUID versionUID,
66      TimeseriesTuple timeseriesTuple,
67      List<AggregateFunction> metrics
68    ) {
69      dataObjectService.getDataObject(collectionId, dataObjectId, versionUID);
70  
71      TimeseriesReference timeseriesReference = timeseriesReferenceService.getReference(
72        collectionId,
73        dataObjectId,
74        timeseriesReferenceId,
75        versionUID
76      );
77  
78      if (
79        timeseriesReference.getTimeseriesContainer() == null || timeseriesReference.getTimeseriesContainer().isDeleted()
80      ) {
81        String errorMsg =
82          "Referenced TimeseriesContainer is not set or deleted in TimeseriesReference with id %s".formatted(
83              timeseriesReferenceId
84            );
85        Log.error(errorMsg);
86        throw new NotFoundException(errorMsg);
87      }
88  
89      var timeseries = timeseriesService
90        .getTimeseries(timeseriesReference.getTimeseriesContainer().getId(), timeseriesTuple)
91        .orElseThrow(() -> {
92          String errorMsg =
93            "Timeseries (%s, %s, %s, %s, %s) in the referenced TimeseriesContainer under TimeseriesReference with id %s".formatted(
94                timeseriesTuple.getMeasurement(),
95                timeseriesTuple.getDevice(),
96                timeseriesTuple.getLocation(),
97                timeseriesTuple.getSymbolicName(),
98                timeseriesTuple.getField(),
99                timeseriesReferenceId
100             );
101         Log.error(errorMsg);
102         return new NotFoundException(errorMsg);
103       });
104 
105     return metrics
106       .stream()
107       .map(metric -> {
108         DataPointValueType valueType = timeseries.getValueType();
109         TimeseriesDataPointsQueryParams queryParams = new TimeseriesDataPointsQueryParams(
110           timeseriesReference.getStart(),
111           timeseriesReference.getEnd(),
112           null,
113           null,
114           metric
115         );
116         // String and boolean can get metrics only on COUNT, LAST and FIRST
117         if (
118           (valueType == DataPointValueType.String || valueType == DataPointValueType.Boolean) &&
119           (metric != AggregateFunction.COUNT && metric != AggregateFunction.FIRST && metric != AggregateFunction.LAST)
120         ) return new MetricsIO(metric, "N/A");
121         var dataPoints =
122           this.timeseriesDataPointRepository.queryAggregationFunction(
123               timeseries.getTimeseriesId(),
124               valueType,
125               queryParams
126             );
127         return new MetricsIO(metric, dataPoints.getFirst().getValue());
128       })
129       .collect(Collectors.toList());
130   }
131 }