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