Forráskód Böngészése

Added API 'driverIdUnitIdActionIdEventsGET' and 'eventIdGET'

Lukas Cerny 1 éve
szülő
commit
596e71bbd1

+ 1 - 1
sql/init.sql

@@ -117,7 +117,7 @@ ALTER TABLE ONLY maplog.action ALTER COLUMN id SET DEFAULT nextval('maplog.actio
 
 
 CREATE TABLE maplog.driver_to_action (
-    id          INTEGER NOT NULL PRIMARY KEY,
+    id          BIGINT NOT NULL PRIMARY KEY,
     driver_id   INTEGER NOT NULL,
     action_id   INTEGER NOT NULL,
     unit_id     BIGINT NOT NULL,

+ 50 - 0
src/main/java/cz/senslog/telemetry/database/domain/Event.java

@@ -0,0 +1,50 @@
+package cz.senslog.telemetry.database.domain;
+
+import java.time.OffsetDateTime;
+
+public class Event {
+
+    private final long id;
+    private final int driverId;
+    private final int actionId;
+    private final long unitId;
+    private final OffsetDateTime fromTime;
+    private final OffsetDateTime toTime;
+
+    public static Event of(long id, int driverId, int actionId, long unitId, OffsetDateTime fromTime, OffsetDateTime toTime) {
+        return new Event(id, driverId, actionId, unitId, fromTime, toTime);
+    }
+
+    private Event(long id, int driverId, int actionId, long unitId, OffsetDateTime fromTime, OffsetDateTime toTime) {
+        this.id = id;
+        this.driverId = driverId;
+        this.actionId = actionId;
+        this.unitId = unitId;
+        this.fromTime = fromTime;
+        this.toTime = toTime;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public int getDriverId() {
+        return driverId;
+    }
+
+    public int getActionId() {
+        return actionId;
+    }
+
+    public long getUnitId() {
+        return unitId;
+    }
+
+    public OffsetDateTime getFromTime() {
+        return fromTime;
+    }
+
+    public OffsetDateTime getToTime() {
+        return toTime;
+    }
+}

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

@@ -379,6 +379,41 @@ public class MapLogRepository implements SensLogRepository {
     }
 
     @Override
+    public Future<List<Event>> findEventsByDriverIdAndUnitIdAndActionId(int driverId, long unitId, int actionId) {
+        return client.preparedQuery("SELECT id, driver_id, action_id, unit_id, from_time, to_time FROM maplog.driver_to_action " +
+                        "WHERE driver_id = $1 AND unit_id = $2 AND action_id = $3")
+                .execute(Tuple.of(driverId, unitId, actionId))
+                .map(rs -> StreamSupport.stream(rs.spliterator(), false)
+                        .map(row -> Event.of(
+                                row.getLong("id"),
+                                row.getInteger("driver_id"),
+                                row.getInteger("action_id"),
+                                row.getLong("unit_id"),
+                                row.getOffsetDateTime("from_time"),
+                                row.getOffsetDateTime("to_time")
+                        )).collect(toList()))
+                .onFailure(logger::catching);
+    }
+
+    private static final Function<Row, Event> ROW_TO_EVENT = (row) -> Event.of(
+            row.getLong("id"),
+            row.getInteger("driver_id"),
+            row.getInteger("action_id"),
+            row.getLong("unit_id"),
+            row.getOffsetDateTime("from_time"),
+            row.getOffsetDateTime("to_time")
+    );
+
+    @Override
+    public Future<Event> findEventById(long eventId) {
+        return client.preparedQuery("SELECT id, driver_id, action_id, unit_id, from_time, to_time FROM maplog.driver_to_action WHERE id = $1")
+                .execute(Tuple.of(eventId))
+                .map(RowSet::iterator)
+                .map(iterator -> iterator.hasNext() ? ROW_TO_EVENT.apply(iterator.next()) : null)
+                .onFailure(logger::catching);
+    }
+
+    @Override
     public Future<List<Unit>> findUnitsByDriverId(int driverId, OffsetDateTime from, OffsetDateTime to) {
         String whereTimestampClause;
         Tuple tupleParams;

+ 10 - 0
src/main/java/cz/senslog/telemetry/database/repository/MockMapLogRepository.java

@@ -196,6 +196,16 @@ public class MockMapLogRepository implements SensLogRepository {
     }
 
     @Override
+    public Future<List<Event>> findEventsByDriverIdAndUnitIdAndActionId(int driverId, long unitId, int actionId) {
+        return Future.succeededFuture(Collections.emptyList());
+    }
+
+    @Override
+    public Future<Event> findEventById(long eventId) {
+        return Future.succeededFuture(Event.of(eventId, -1, -1, -1, null, null));
+    }
+
+    @Override
     public Future<List<Unit>> findUnitsByDriverId(int driverId, OffsetDateTime from, OffsetDateTime to) {
         return Future.succeededFuture(Collections.emptyList());
     }

+ 4 - 0
src/main/java/cz/senslog/telemetry/database/repository/SensLogRepository.java

@@ -57,6 +57,10 @@ public interface SensLogRepository {
     Future<Action> findActionByIdAndDriverId(int actionId, int driverId);
     Future<Action> findActionByIdAndDriverIdAndUnitId(int actionId, int driverId, long unitId);
 
+
+    Future<List<Event>> findEventsByDriverIdAndUnitIdAndActionId(int driverId, long unitId, int actionId);
+    Future<Event> findEventById(long eventId);
+
     Future<List<Unit>> findUnitsByDriverId(int driverId, OffsetDateTime from, OffsetDateTime to);
     Future<List<UnitTelemetry>> findObservationsByCampaignId(long campaignId, OffsetDateTime from, OffsetDateTime to, ZoneId zone, int offset, int limit);
     Future<PagingRetrieve<List<UnitTelemetry>>> findObservationsByCampaignIdWithPaging(long campaignId, OffsetDateTime from, OffsetDateTime to, ZoneId zone, int offset, int limit);

+ 4 - 0
src/main/java/cz/senslog/telemetry/server/HttpVertxServer.java

@@ -88,6 +88,10 @@ public final class HttpVertxServer extends AbstractVerticle {
                     openAPIRouterBuilder.operation("driverIdActionIdUnitsGET").handler(apiHandler::driverIdActionIdUnitsGET);
                     openAPIRouterBuilder.operation("driverIdActionIdUnitIdGET").handler(apiHandler::driverIdActionIdUnitIdGET);
                     openAPIRouterBuilder.operation("driverIdUnitIdActionIdGET").handler(apiHandler::driverIdUnitIdActionIdGET);
+                    openAPIRouterBuilder.operation("driverIdUnitIdActionIdEventsGET").handler(apiHandler::driverIdUnitIdActionIdEventsGET);
+
+                    openAPIRouterBuilder.operation("eventIdGET").handler(apiHandler::eventIdGET);
+
 
                     Router mainRouter = openAPIRouterBuilder.createRouter();
 //                    mainRouter.route().handler(LoggerHandler.create());

+ 56 - 0
src/main/java/cz/senslog/telemetry/server/OpenAPIHandler.java

@@ -1023,4 +1023,60 @@ public class OpenAPIHandler {
                         )).encode())
                         .onFailure(th -> rc.fail(400, th)));
     }
+
+    public void driverIdUnitIdActionIdEventsGET(RoutingContext rc) {
+        String host =  hostURLFull(rc.request());
+
+        int driverId = Integer.parseInt(rc.pathParam("driverId"));
+        int actionId = Integer.parseInt(rc.pathParam("actionId"));
+        long unitId = Integer.parseInt(rc.pathParam("unitId"));
+
+        List<String> paramZone = rc.queryParam("zone");
+        ZoneId zone = paramZone.isEmpty() ? DEFAULT_ZONE_ID : ZoneId.of(paramZone.get(0));
+
+        List<String> paramNavigationLinks = rc.queryParam("navigationLinks");
+        boolean navigationLinks = paramNavigationLinks.isEmpty() ? DEFAULT_NAVIGATION_LINKS : parseBoolean(paramNavigationLinks.get(0));
+
+        repo.findEventsByDriverIdAndUnitIdAndActionId(driverId, unitId, actionId)
+                .onSuccess(events -> rc.response().end(new JsonArray(
+                        events.stream().map(e -> (navigationLinks ? JsonObject.of(
+                                "Event@NavigationLink", String.format("%s/events/%d",host, e.getId())
+                        ) : JsonObject.of()).mergeIn(JsonObject.of(
+                                "id", e.getId(),
+                                "fromTime", DATE_TIME_FORMATTER.apply(e.getFromTime(), zone),
+                                "description", DATE_TIME_FORMATTER.apply(e.getToTime(), zone)
+                        ))).collect(toList())
+                ).encode()))
+                .onFailure(th -> rc.fail(400, th));
+    }
+
+    public void eventIdGET(RoutingContext rc) {
+        String host =  hostURLFull(rc.request());
+
+        int eventId = Integer.parseInt(rc.pathParam("eventId"));
+
+        List<String> paramZone = rc.queryParam("zone");
+        ZoneId zone = paramZone.isEmpty() ? DEFAULT_ZONE_ID : ZoneId.of(paramZone.get(0));
+
+        List<String> paramNavigationLinks = rc.queryParam("navigationLinks");
+        boolean navigationLinks = paramNavigationLinks.isEmpty() ? DEFAULT_NAVIGATION_LINKS : parseBoolean(paramNavigationLinks.get(0));
+
+        repo.findEventById(eventId)
+                .onSuccess(e -> rc.response().end((navigationLinks ? JsonObject.of(
+                                "self@NavigationLink", String.format("%s/events/%d", host, e.getId()),
+                                "Driver@NavigationLink", String.format("%s/drivers/%d", host, e.getDriverId()),
+                                "DriverUnit@NavigationLink", String.format("%s/drivers/%d/units/%d", host, e.getDriverId(), e.getUnitId()),
+                                "Actions@NavigationLink", String.format("%s/actions/%d", host, e.getActionId()),
+                                "Observations@NavigationLink", String.format("%s/events/%d/observations", host, e.getId()),
+                                "Locations@NavigationLink", String.format("%s/events/%d/observations/locations", host, e.getId())
+                        ) : JsonObject.of()).mergeIn(JsonObject.of(
+                                "id", e.getId(),
+                                "driverId", e.getDriverId(),
+                                "actionId", e.getActionId(),
+                                "unitId", e.getUnitId(),
+                                "fromTime", DATE_TIME_FORMATTER.apply(e.getFromTime(), zone),
+                                "description", DATE_TIME_FORMATTER.apply(e.getToTime(), zone)
+                        )).encode())
+                        .onFailure(th -> rc.fail(400, th)));
+    }
 }

+ 26 - 12
src/main/resources/openAPISpec.yaml

@@ -726,7 +726,7 @@ paths:
                 $ref: '#/components/schemas/Error'
 
   /drivers/{driverId}/units/{unitId}/actions/{actionId}:
-    get:
+    get: # done
       operationId: driverIdUnitIdActionIdGET
       summary: Publish detailed info about the action performed on the unit by the driver
       parameters:
@@ -756,6 +756,7 @@ paths:
         - $ref: '#/components/parameters/driverIdParam'
         - $ref: '#/components/parameters/unitIdParam'
         - $ref: '#/components/parameters/actionIdParam'
+        - $ref: '#/components/parameters/zoneParam'
         - $ref: '#/components/parameters/navigationLinksParam'
       responses:
         200:
@@ -774,15 +775,13 @@ paths:
                 $ref: '#/components/schemas/Error'
 
 
-  /drivers/{driverId}/units/{unitId}/actions/{actionId}/events/{eventId}:
+  /events/{eventId}:
     get:
-      operationId: driverIdUnitIdActionIdEventsGET
+      operationId: eventIdGET
       summary: Publish basic info about events that where performed on the unit byt the driver with the specific action
       parameters:
-        - $ref: '#/components/parameters/driverIdParam'
-        - $ref: '#/components/parameters/unitIdParam'
-        - $ref: '#/components/parameters/actionIdParam'
         - $ref: '#/components/parameters/eventIdParam'
+        - $ref: '#/components/parameters/zoneParam'
         - $ref: '#/components/parameters/navigationLinksParam'
       responses:
         200:
@@ -798,9 +797,9 @@ paths:
               schema:
                 $ref: '#/components/schemas/Error'
 
-  /drivers/{driverId}/units/{unitId}/actions/{actionId}/events/{eventId}/observations:
+  /events/{eventId}/observations:
     get:
-      operationId: driverIdUnitIdActionIdEventIdObservationsGET
+      operationId: eventIdObservationsGET
       summary: Publish telemetry observations created by the driver while performing specific action on the unit at the time/event
       parameters:
         - $ref: '#/components/parameters/driverIdParam'
@@ -825,9 +824,9 @@ paths:
               schema:
                 $ref: '#/components/schemas/Error'
 
-  /drivers/{driverId}/units/{unitId}/actions/{actionId}/events/{eventId}/observations/locations:
+  /events/{eventId}/observations/locations:
     get:
-      operationId: driverIdUnitIdActionIdEventIdLocationsGET
+      operationId: eventIdLocationsGET
       summary: Publish locations created by the driver while performing specific action on the unit at the time/event
       parameters:
         - $ref: '#/components/parameters/driverIdParam'
@@ -2531,6 +2530,9 @@ components:
       type: object
       required:
         - id
+        - driverId
+        - actionId
+        - unitId
         - fromTime
         - toTime
       x-NavigationLinks:
@@ -2580,6 +2582,15 @@ components:
         id:
           type: integer
           format: int64
+        driverId:
+          type: integer
+          format: int64
+        actionId:
+          type: integer
+          format: int64
+        unitId:
+          type: integer
+          format: int64
         fromTime:
           description: Time when the event starts
           type: string
@@ -2593,9 +2604,12 @@ components:
         Driver@NavigationLink: "<domain>/drivers/42"
         DriverUnit@NavigationLink: "<domain>/drivers/42/units/105"
         Action@NavigationLink: "<domain>/actions/258"
-        Observations@NavigationLink: "<domain>/drivers/42/units/105/actions/258/events/999/observations"
-        Locations@NavigationLink: "<domain>/drivers/42/units/105/actions/258/events/999/observations/locations"
+        Observations@NavigationLink: "<domain>/events/999/observations"
+        Locations@NavigationLink: "<domain>/events/999/observations/locations"
         id: 999
+        driverId: 42
+        actionId: 258
+        unitId: 105
         fromTime: "2023-01-25 15:35:32Z"
         toTime: "2023-03-20 10:35:32Z"