Quellcode durchsuchen

Added attributes 'fromTime' and 'toTime' in GeoJSON for '/locations' endpoints

Lukas Cerny vor 1 Jahr
Ursprung
Commit
df57817312

+ 1 - 1
src/main/java/cz/senslog/telemetry/database/repository/MapLogRepository.java

@@ -1240,7 +1240,7 @@ public class MapLogRepository implements SensLogRepository {
                     "ST_M (the_geom) AS angle " +
                 "FROM (SELECT *, row_number() OVER (PARTITION BY unit_id ORDER BY time_stamp "+ sort.name() +" ) AS rn " +
                 "FROM (SELECT obs.* FROM maplog.obs_telemetry obs JOIN maplog.unit_to_campaign utc ON obs.unit_id = utc.unit_id "+whereTimestampClause+") AS data) AS g " +
-                "WHERE rn <= $2" + whereFiltersClause;
+                "WHERE rn <= $2" + whereFiltersClause + " ORDER BY time_stamp";
 
         return client.preparedQuery(sql)
                 .execute(tupleParams)

+ 29 - 19
src/main/java/cz/senslog/telemetry/server/ws/OpenAPIHandler.java

@@ -7,6 +7,7 @@ import cz.senslog.telemetry.database.domain.UnitLocation;
 import cz.senslog.telemetry.database.domain.UnitTelemetry;
 import cz.senslog.telemetry.database.repository.SensLogRepository;
 import cz.senslog.telemetry.database.domain.Filter;
+import cz.senslog.telemetry.utils.ListUtils;
 import cz.senslog.telemetry.utils.TernaryCondition;
 import io.vertx.core.http.HttpServerRequest;
 import io.vertx.core.json.JsonArray;
@@ -24,9 +25,11 @@ import static cz.senslog.telemetry.database.validation.UnitTelemetryValidation.*
 import static cz.senslog.telemetry.server.ws.ContentType.GEOJSON;
 import static cz.senslog.telemetry.server.ws.ContentType.JSON;
 import static cz.senslog.telemetry.utils.FluentInvoke.fluentlyOf;
+import static cz.senslog.telemetry.utils.ListUtils.*;
 import static cz.senslog.telemetry.utils.TernaryCondition.ternaryIf;
 import static io.vertx.core.http.HttpHeaders.CONTENT_TYPE;
 import static java.lang.Boolean.parseBoolean;
+import static java.time.OffsetDateTime.ofInstant;
 import static java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME;
 import static java.util.Collections.emptyList;
 import static java.util.Comparator.comparing;
@@ -42,7 +45,7 @@ public class OpenAPIHandler {
     private static final ContentType DEFAULT_RESPONSE_FORMAT = JSON;
 
     private static final BiFunction<OffsetDateTime, ZoneId, String> DATE_TIME_FORMATTER = (dateTime, zoneId) ->
-            OffsetDateTime.ofInstant(dateTime.toInstant(), zoneId).format(ISO_OFFSET_DATE_TIME);
+            ofInstant(dateTime.toInstant(), zoneId).format(ISO_OFFSET_DATE_TIME);
 
     private final SensLogRepository repo;
 
@@ -223,7 +226,7 @@ public class OpenAPIHandler {
                         "data", new JsonArray(
                                 paging.data().stream().map(o -> JsonObject.of(
                                         "unitId", o.getUnitId(),
-                                        "timestamp", OffsetDateTime.ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                        "timestamp", ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                         "speed", o.getSpeed(),
                                         "location", JsonObject.of(
                                                 "longitude", o.getLocation().getLongitude(),
@@ -253,7 +256,7 @@ public class OpenAPIHandler {
                                             ),
                                             "properties", JsonObject.of(
                                                     "unitId", o.getUnitId(),
-                                                    "timestamp", OffsetDateTime.ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                                    "timestamp", ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                                     "speed", o.getSpeed(),
                                                     "observedValues", o.getObservedValues()
                                             )
@@ -343,7 +346,7 @@ public class OpenAPIHandler {
                                     "hasNext", paging.hasNext(),
                                     "data", new JsonArray(
                                             paging.data().stream().map(o -> JsonObject.of(
-                                                    "timestamp", OffsetDateTime.ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                                    "timestamp", ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                                     "speed", o.getSpeed(),
                                                     "location", JsonObject.of(
                                                             "longitude", o.getLocation().getLongitude(),
@@ -374,7 +377,7 @@ public class OpenAPIHandler {
                                                     ),
                                                     "properties", JsonObject.of(
                                                             "unitId", o.getUnitId(),
-                                                            "timestamp", OffsetDateTime.ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                                            "timestamp", ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                                             "speed", o.getSpeed(),
                                                             "observedValues", o.getObservedValues()
                                                     )
@@ -447,7 +450,7 @@ public class OpenAPIHandler {
                             "size", locations.size(),
                             "data", new JsonArray(locations.stream().map(l -> JsonObject.of(
                                     "unitId", l.getUnitId(),
-                                    "timestamp", OffsetDateTime.ofInstant(l.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                    "timestamp", ofInstant(l.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                     "location", JsonObject.of(
                                             "longitude", l.getLocation().getLongitude(),
                                             "latitude", l.getLocation().getLatitude(),
@@ -464,7 +467,9 @@ public class OpenAPIHandler {
                             "features", unitLocation.entrySet().stream().map(entry -> JsonObject.of(
                                     "type", "Feature",
                                     "properties", JsonObject.of(
-                                            "unitId", entry.getKey()),
+                                            "unitId", entry.getKey(),
+                                            "fromTime", firstOf(entry.getValue()).map(t -> ofInstant(t.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME)).orElse(null),
+                                            "toTime", lastOf(entry.getValue()).map(t -> ofInstant(t.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME)).orElse(null)),
                                     "geometry", JsonObject.of(
                                             "type", "MultiPoint",
                                             "coordinates", new JsonArray(entry.getValue().stream().map(l -> JsonArray.of(
@@ -559,7 +564,7 @@ public class OpenAPIHandler {
                             "hasNext", paging.hasNext(),
                             "data", new JsonArray(
                                     paging.data().stream().map(l -> JsonObject.of(
-                                            "timestamp", OffsetDateTime.ofInstant(l.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                            "timestamp", ofInstant(l.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                             "location", JsonObject.of(
                                                     "longitude", l.getLocation().getLongitude(),
                                                     "latitude", l.getLocation().getLatitude(),
@@ -573,10 +578,12 @@ public class OpenAPIHandler {
                                         "size", paging.size(),
                                         "offset", offset,
                                         "hasNext", paging.hasNext()
-                                ),
-                                "properties", JsonObject.of(
-                                        "unitId", unitId
-                                ),
+                                    ),
+                                "properties", ofNonEmpty(paging.data()).map(locs -> JsonObject.of(
+                                        "unitId", firstOf(locs).map(UnitLocation::getUnitId).orElse(null),
+                                        "fromTime", firstOf(locs).map(t -> ofInstant(t.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME)).orElse(null),
+                                        "toTime", lastOf(locs).map(t -> ofInstant(t.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME)).orElse(null)
+                                    )).orElseGet(JsonObject::new),
                                 "geometry", JsonObject.of(
                                         "type", "MultiPoint",
                                         "coordinates", new JsonArray(paging.data().stream().map(l -> JsonArray.of(
@@ -956,7 +963,7 @@ public class OpenAPIHandler {
                             "data", new JsonArray(
                                     paging.data().stream().map(l -> JsonObject.of(
                                             "observedValue", l.getValue(),
-                                            "timestamp", OffsetDateTime.ofInstant(l.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                            "timestamp", ofInstant(l.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                             "speed", l.getSpeed(),
                                             "location", JsonObject.of(
                                                     "longitude", l.getLocation().getLongitude(),
@@ -985,7 +992,7 @@ public class OpenAPIHandler {
                                             ),
                                             "properties", JsonObject.of(
                                                     "unitId", unitId,
-                                                    "timestamp", OffsetDateTime.ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                                    "timestamp", ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                                     "speed", o.getSpeed(),
                                                     "observedValues", JsonObject.of(
                                                             String.valueOf(sensorId), o.getValue()
@@ -1351,7 +1358,7 @@ public class OpenAPIHandler {
                             "hasNext", paging.hasNext(),
                             "data", new JsonArray(
                                     paging.data().stream().map(o -> JsonObject.of(
-                                            "timestamp", OffsetDateTime.ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                            "timestamp", ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                             "speed", o.getSpeed(),
                                             "location", JsonObject.of(
                                                     "longitude", o.getLocation().getLongitude(),
@@ -1381,7 +1388,7 @@ public class OpenAPIHandler {
                                             ),
                                             "properties", JsonObject.of(
                                                     "unitId", o.getUnitId(),
-                                                    "timestamp", OffsetDateTime.ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                                    "timestamp", ofInstant(o.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                                     "speed", o.getSpeed(),
                                                     "observedValues", o.getObservedValues()
                                             )
@@ -1469,7 +1476,7 @@ public class OpenAPIHandler {
                             "hasNext", paging.hasNext(),
                             "data", new JsonArray(
                                     paging.data().stream().map(l -> JsonObject.of(
-                                            "timestamp", OffsetDateTime.ofInstant(l.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
+                                            "timestamp", ofInstant(l.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME),
                                             "location", JsonObject.of(
                                                     "longitude", l.getLocation().getLongitude(),
                                                     "latitude", l.getLocation().getLatitude(),
@@ -1484,8 +1491,11 @@ public class OpenAPIHandler {
                                     "offset", offset,
                                     "hasNext", paging.hasNext()
                             ),
-                            "properties", ofNullable(paging.size() > 0  ? paging.data().get(0) : null)
-                                    .map(l -> JsonObject.of("unitId", l.getUnitId())).orElseGet(JsonObject::new),
+                            "properties", ofNonEmpty(paging.data()).map(locs -> JsonObject.of(
+                                    "unitId", firstOf(locs).map(UnitLocation::getUnitId).orElse(null),
+                                    "fromTime", firstOf(locs).map(t -> ofInstant(t.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME)).orElse(null),
+                                    "toTime", lastOf(locs).map(t -> ofInstant(t.getTimestamp().toInstant(), zone).format(ISO_OFFSET_DATE_TIME)).orElse(null)
+                            )).orElseGet(JsonObject::new),
                             "geometry", JsonObject.of(
                                     "type", "MultiPoint",
                                     "coordinates", new JsonArray(paging.data().stream().map(l -> JsonArray.of(

+ 32 - 0
src/main/java/cz/senslog/telemetry/utils/ListUtils.java

@@ -0,0 +1,32 @@
+package cz.senslog.telemetry.utils;
+
+import java.util.List;
+import java.util.Optional;
+
+public final class ListUtils {
+
+    public static <T> boolean isEmpty(List<T> list) {
+        return list == null || list.isEmpty();
+    }
+
+    public static <T> Optional<List<T>> ofNonEmpty(List<T> list) {
+        if (isEmpty(list)) {
+            return Optional.empty();
+        }
+        return Optional.of(list);
+    }
+
+    public static <T> Optional<T> firstOf(List<T> list) {
+        if (isEmpty(list)) {
+            return Optional.empty();
+        }
+        return Optional.of(list.get(0));
+    }
+
+    public static <T> Optional<T> lastOf(List<T> list) {
+        if (isEmpty(list)) {
+            return Optional.empty();
+        }
+        return Optional.of(list.get(list.size()-1));
+    }
+}

+ 8 - 0
src/main/resources/openAPISpec.yaml

@@ -1986,10 +1986,18 @@ components:
           type: object
           required:
             - unitId
+            - fromTime
+            - toTime
           properties:
             unitId:
               type: integer
               format: int64
+            fromTime:
+              type: string
+              format: date-time
+            toTime:
+              type: string
+              format: date-time
         geometry:
           $ref: '#/components/schemas/GeoMultiPoint'
 

+ 6 - 1
testing/access_token.json

@@ -1 +1,6 @@
-{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ii0xbW13UG9vM25ZeEF1akt2LVRieCJ9.eyJpc3MiOiJodHRwczovL2Rldi0wdXF2eHJyemJseWlyeXIyLnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJmQW4xNlgzbkFhWFVkTnZYVTZmSjhtaEdzOTY1MHpCOEBjbGllbnRzIiwiYXVkIjoiaHR0cDovLzEyNy4wLjAuMTo4MDgwIiwiaWF0IjoxNzA2NTM3NDEwLCJleHAiOjE3MDkxMjk0MTAsImF6cCI6ImZBbjE2WDNuQWFYVWROdlhVNmZKOG1oR3M5NjUwekI4Iiwic2NvcGUiOiJ0ZWxlbWV0cnk6cmVhZCIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyIsInBlcm1pc3Npb25zIjpbInRlbGVtZXRyeTpyZWFkIl19.g-XGG0qUFyOj2lVdDlL58FgyASfneIc1RQHS6AtRyrl-CwdrFqge1ClSARd7tAuSFlMe_sFy3IJZVgrTXnlxiNoyCu_y85wM6tsQ_ZqgpnpM-q2fokb3k7Tsi4kKxe3maRoZXzOAWofCCYkWzpsl3IXiu4SL1kniyCWea9D3T5vXytnzzpjhplqFgbUH2q367pGV5_IgJ_GN7WokB6z8cJL9gWWCquCZdNXO85v3SGW-OLYd7dCJUYlVAsp69TNaZwZRiZ3K5J2U7sSqwWhvyBHYlHQVFUP1MyRYhFyoK0Z-2z2XEf1zHGLe8qmbJm7V6xHtnUhUvEX6Kakj-Fjpow","scope":"telemetry:read","expires_in":2592000,"token_type":"Bearer"}
+{
+  "access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ii0xbW13UG9vM25ZeEF1akt2LVRieCJ9.eyJpc3MiOiJodHRwczovL2Rldi0wdXF2eHJyemJseWlyeXIyLnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJmQW4xNlgzbkFhWFVkTnZYVTZmSjhtaEdzOTY1MHpCOEBjbGllbnRzIiwiYXVkIjoiaHR0cDovLzEyNy4wLjAuMTo4MDgwIiwiaWF0IjoxNzA2NTM3NDEwLCJleHAiOjE3MDkxMjk0MTAsImF6cCI6ImZBbjE2WDNuQWFYVWROdlhVNmZKOG1oR3M5NjUwekI4Iiwic2NvcGUiOiJ0ZWxlbWV0cnk6cmVhZCIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyIsInBlcm1pc3Npb25zIjpbInRlbGVtZXRyeTpyZWFkIl19.g-XGG0qUFyOj2lVdDlL58FgyASfneIc1RQHS6AtRyrl-CwdrFqge1ClSARd7tAuSFlMe_sFy3IJZVgrTXnlxiNoyCu_y85wM6tsQ_ZqgpnpM-q2fokb3k7Tsi4kKxe3maRoZXzOAWofCCYkWzpsl3IXiu4SL1kniyCWea9D3T5vXytnzzpjhplqFgbUH2q367pGV5_IgJ_GN7WokB6z8cJL9gWWCquCZdNXO85v3SGW-OLYd7dCJUYlVAsp69TNaZwZRiZ3K5J2U7sSqwWhvyBHYlHQVFUP1MyRYhFyoK0Z-2z2XEf1zHGLe8qmbJm7V6xHtnUhUvEX6Kakj-Fjpow",
+  "scope":"telemetry:read",
+  "expires_in":2592000,
+  "token_type":"Bearer"
+}