Переглянути джерело

Added API 'campaignIdUnitIdSensorIdGET'

Lukas Cerny 1 рік тому
батько
коміт
934b4abeb7

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

@@ -244,6 +244,19 @@ public class MapLogRepository implements SensLogRepository {
     }
 
     @Override
+    public Future<Sensor> findSensorByCampaignIdAndUnitId(long campaignId, long unitId, long sensorId) {
+        return client.preparedQuery("SELECT s.sensor_id, s.sensor_name, s.sensor_type, s.io_id, s.description, p.id AS phenomenon_id, p.name AS phenomenon_name, p.uom, p.uom_link " +
+                        "FROM maplog.sensor AS s " +
+                        "JOIN maplog.phenomenon AS p ON p.id = s.phenomenon_id " +
+                        "JOIN maplog.unit_to_sensor AS uts ON s.sensor_id = uts.sensor_id " +
+                        "JOIN maplog.unit_to_campaign AS utc ON utc.unit_id = uts.unit_id " +
+                        "WHERE s.sensor_id = $3 AND uts.unit_id = $2 AND utc.camp_id = $1")
+                .execute(Tuple.of(campaignId, unitId, sensorId))
+                .map(RowSet::iterator)
+                .map(iterator -> iterator.hasNext() ? ROW_TO_SENSOR.apply(iterator.next()) : null);
+    }
+
+    @Override
     public Future<List<Phenomenon>> allPhenomenons() {
         return client.query("SELECT id, name FROM maplog.phenomenon")
                 .execute()

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

@@ -146,6 +146,11 @@ public class MockMapLogRepository implements SensLogRepository {
     }
 
     @Override
+    public Future<Sensor> findSensorByCampaignIdAndUnitId(long campaignId, long unitId, long sensorId) {
+        return Future.succeededFuture(Sensor.of(sensorId, "mock(name)", "mock(type)", -1, Phenomenon.of(-1, "mock(name)"), "mock(description)"));
+    }
+
+    @Override
     public Future<List<Campaign>> findCampaignsByUnitId(long unitId, ZoneId zone) {
         return Future.succeededFuture(Collections.emptyList());
     }

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

@@ -34,6 +34,7 @@ public interface SensLogRepository {
     Future<List<Sensor>> findSensorsByUnitId(long unitId);
     Future<List<Sensor>> findSensorsByPhenomenonId(long phenomenonId);
     Future<List<Sensor>> findSensorsByCampaignIdAndUnitId(long campaignId, long unitId);
+    Future<Sensor> findSensorByCampaignIdAndUnitId(long campaignId, long unitId, long sensorId);
 
     Future<List<Phenomenon>> allPhenomenons();
     Future<Phenomenon> findPhenomenonById(long phenomenonId);

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

@@ -62,6 +62,7 @@ public final class HttpVertxServer extends AbstractVerticle {
                     openAPIRouterBuilder.operation("campaignIdUnitIdLocationsGET").handler(apiHandler::campaignIdUnitIdLocationsGET);
                     openAPIRouterBuilder.operation("campaignIdUnitIdGET").handler(apiHandler::campaignIdUnitIdGET);
                     openAPIRouterBuilder.operation("campaignIdUnitIdSensorsGET").handler(apiHandler::campaignIdUnitIdSensorsGET);
+                    openAPIRouterBuilder.operation("campaignIdUnitIdSensorIdGET").handler(apiHandler::campaignIdUnitIdSensorIdGET);
 
                     openAPIRouterBuilder.operation("unitsGET").handler(apiHandler::unitsGET);
                     openAPIRouterBuilder.operation("unitIdGET").handler(apiHandler::unitIdGET);

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

@@ -538,6 +538,7 @@ public class OpenAPIHandler {
                                 "Phenomenon@NavigationLink", String.format("%s/phenomenons/%d", host, s.getPhenomenon().getId())
                         ) : JsonObject.of()).mergeIn(JsonObject.of(
                                 "sensorId", s.getSensorId(),
+                                "ioId", s.getIoID(),
                                 "name", s.getName(),
                                 "description", s.getDescription(),
                                 "type", s.getType(),
@@ -696,4 +697,32 @@ public class OpenAPIHandler {
                 ).encode()))
                 .onFailure(th -> rc.fail(400, th));
     }
+
+    public void campaignIdUnitIdSensorIdGET(RoutingContext rc) {
+        String host =  hostURLFull(rc.request());
+
+        long campaignId = Long.parseLong(rc.pathParam("campaignId"));
+        long unitId = Long.parseLong(rc.pathParam("unitId"));
+        long sensorId = Long.parseLong(rc.pathParam("sensorId"));
+
+        List<String> paramNavigationLinks = rc.queryParam("navigationLinks");
+        boolean navigationLinks = paramNavigationLinks.isEmpty() ? DEFAULT_NAVIGATION_LINKS : parseBoolean(paramNavigationLinks.get(0));
+
+        repo.findSensorByCampaignIdAndUnitId(campaignId, unitId, sensorId)
+                .onSuccess(s -> rc.response().end((navigationLinks ? JsonObject.of(
+                                "self@NavigationLink", String.format("%s/campaigns/%d/units/%d/sensors/%d", host, campaignId, unitId, s.getSensorId()),
+                                "Sensor@NavigationLink", String.format("%s/sensors/%d", host, s.getSensorId()),
+                                "CampaignUnit@NavigationLink", String.format("%s/campaigns/%d/units/%d", host, campaignId, unitId),
+                                "Phenomenon@NavigationLink", String.format("%s/phenomenons/%d", host, s.getPhenomenon().getId()),
+                                "Observations@NavigationLink", String.format("%s/campaigns/%d/units/%d/sensors/%d/observations", host, campaignId, unitId, s.getSensorId())
+                        ) : JsonObject.of()).mergeIn(JsonObject.of(
+                                "sensorId", s.getSensorId(),
+                                "ioId", s.getIoID(),
+                                "name", s.getName(),
+                                "description", s.getDescription(),
+                                "type", s.getType(),
+                                "phenomenon", s.getPhenomenon().getName()
+                        )).encode())
+                        .onFailure(th -> rc.fail(400, th)));
+    }
 }

+ 97 - 1
src/main/resources/openAPISpec.yaml

@@ -491,7 +491,7 @@ paths:
                 $ref: '#/components/schemas/Error'
 
   /campaigns/{campaignId}/units/{unitId}/sensors:
-    get:
+    get: # done
       operationId: campaignIdUnitIdSensorsGET
       summary: Publish info about all sensors of the unit within the campaign
       parameters:
@@ -531,6 +531,51 @@ paths:
               schema:
                 $ref: '#/components/schemas/Error'
 
+  /campaigns/{campaignId}/units/{unitId}/sensors/{sensorId}:
+    get: # done
+      operationId: campaignIdUnitIdSensorIdGET
+      summary: Publish info about all sensors asociated with the unit and the campaign
+      parameters:
+        - in: path
+          name: campaignId
+          schema:
+            type: integer
+            format: int64
+          required: true
+          description: Numeric ID of the campaign to get
+        - in: path
+          name: unitId
+          schema:
+            type: integer
+            format: int64
+          required: true
+          description: Numeric ID of the unit to get
+        - in: path
+          name: sensorId
+          schema:
+            type: integer
+          required: true
+          description: Numeric ID of the sensor to get
+        - in: query
+          name: navigationLinks
+          schema:
+            type: boolean
+            default: true
+          description: Option to disable @NavigationLinks in a response
+      responses:
+        200:
+          description: JSON Object containing info about the sensor
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/CampaignUnitDetailedSensor'
+        default:
+          description: unexpected error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
+
   /campaigns/{campaignId}/units/{unitId}/sensors/{sensorId}/observations:
     get:
       operationId: campaignIdUnitIdSensorIdObservationsGET
@@ -1093,6 +1138,53 @@ components:
         name: "Sensor 105"
         type: "X"
 
+    CampaignUnitDetailedSensor:
+      type: object
+      required:
+        - sensorId
+        - name
+        - phenomenon
+        - type
+      properties:
+        self@NavigationLink:
+          type: string
+          format: uri
+        Sensor@NavigationLink:
+          type: string
+          format: uri
+        CampaignUnit@NavigationLink:
+          type: string
+          format: uri
+        Phenomenon@NavigationLink:
+          type: string
+          format: uri
+        Observations@NavigationLink:
+          type: string
+          format: uri
+        sensorId:
+          type: integer
+          format: int64
+        name:
+          type: string
+        phenomenon:
+          type: string
+        type:
+          type: string
+        description:
+          type: string
+      example:
+        self@NavigationLink: "<domain>/campaigns/1/units/25/sensors/105"
+        Sensor@NavigationLink: "<domain>/sensors/105"
+        CampaignUnit@NavigationLink: "<domain>/campaigns/1/units/25"
+        Phenomenon@NavigationLink: "<domain>/phenomenons/15"
+        Observations@NavigationLink: "<domain>/campaigns/1/units/25/sensors/105/observations"
+        sensorId: 105
+        name: "Sensor 105"
+        description: "Description of the sensor 105"
+        type: "type of sensor"
+        phenomenon: "Temperature"
+
+
     CampaignObservation:
       type: object
       required:
@@ -1530,6 +1622,7 @@ components:
       type: object
       required:
         - sensorId
+        - ioId
         - name
         - phenomenon
       properties:
@@ -1545,6 +1638,9 @@ components:
         sensorId:
           type: integer
           format: int64
+        ioId:
+          type: integer
+          format: int16
         name:
           type: string
         phenomenon: