diff --git a/phis2-ws/src/main/java/opensilex/service/dao/DataDAO.java b/phis2-ws/src/main/java/opensilex/service/dao/DataDAO.java index cc7918655..05b846a34 100644 --- a/phis2-ws/src/main/java/opensilex/service/dao/DataDAO.java +++ b/phis2-ws/src/main/java/opensilex/service/dao/DataDAO.java @@ -439,7 +439,7 @@ protected BasicDBObject prepareSearchQuery(String variableUri, String startDate, } // Objects filter - if (!objectsUris.isEmpty()) { + if (objectsUris != null && !objectsUris.isEmpty()) { if (objectsUris.size() > 1) { BasicDBList or = new BasicDBList(); for (String objectUri : objectsUris) { @@ -453,7 +453,7 @@ protected BasicDBObject prepareSearchQuery(String variableUri, String startDate, } //Provenance filter - if (!provenancesUris.isEmpty()) { + if (provenancesUris != null && !provenancesUris.isEmpty()) { if (provenancesUris.size() > 1) { BasicDBList or = new BasicDBList(); for (String provenanceUri : provenancesUris) { diff --git a/phis2-ws/src/main/java/opensilex/service/documentation/StatusCodeMsg.java b/phis2-ws/src/main/java/opensilex/service/documentation/StatusCodeMsg.java index ddefd61be..038f51483 100644 --- a/phis2-ws/src/main/java/opensilex/service/documentation/StatusCodeMsg.java +++ b/phis2-ws/src/main/java/opensilex/service/documentation/StatusCodeMsg.java @@ -12,7 +12,7 @@ /** * Web service return messages. * @see phenomeapi.service.view.brapi.Status - * @author Arnaud Charleroy , Morgane Vidal + * @author Arnaud Charleroy, Morgane Vidal */ @Singleton public final class StatusCodeMsg { @@ -28,6 +28,7 @@ public final class StatusCodeMsg { public static final String DATA_ERROR = "Data error"; public static final String DATA_INSERTED = "Data inserted"; public static final String DATA_REJECTED = "Data rejected"; + public static final String API_DEPRECATED_INFO_MESSAGE = "This api service should no longer be used. It will be change or removed"; public static final String ERR = "Error"; public static final String ERROR_WHILE_COMMITTING_OR_ROLLING_BACK_TRIPLESTORE_STATEMENT = "Error while committing or rolling back Triplestore statements: "; public static final String EMPTY_EVENT_LIST = "The event list to create is empty"; @@ -36,6 +37,7 @@ public final class StatusCodeMsg { public static final String FILE_ERROR = "File error"; public static final String INFO = "Info"; public static final String INTERNAL_ERROR = "An internal error occured. Please contact the administrator."; + public static final String INVALID_INPUT_PARAMETERS = "Wrong format parameter(s)"; public static final String MALFORMED_CREATE_QUERY = "Malformed create query"; public static final String MALFORMED_UPDATE_QUERY = "Malformed update query"; public static final String MALFORMED_URI = "Malformed URI"; @@ -57,5 +59,7 @@ public final class StatusCodeMsg { public static final String UNKNOWN_TYPE = "Unknown type %s"; public static final String UNKNOWN_EVENT_URI = "Unknown event URI"; public static final String WRONG_VALUE = "Wrong value"; - public static final String INVALID_INPUT_PARAMETERS = "Wrong format parameter(s)"; + public static final String WARNING = "Warning"; + + } diff --git a/phis2-ws/src/main/java/opensilex/service/resource/EnvironmentResourceService.java b/phis2-ws/src/main/java/opensilex/service/resource/EnvironmentResourceService.java index 99c2ded88..f0fd54e71 100644 --- a/phis2-ws/src/main/java/opensilex/service/resource/EnvironmentResourceService.java +++ b/phis2-ws/src/main/java/opensilex/service/resource/EnvironmentResourceService.java @@ -49,11 +49,15 @@ /** * Environmental measure resource service. - * @author Morgane Vidal + * @author Morgane Vidal */ @Api("/environments") @Path("/environments") +@Deprecated public class EnvironmentResourceService extends ResourceService { + + private final Status deprecatedStatus = new Status(StatusCodeMsg.WARNING, StatusCodeMsg.WARNING, StatusCodeMsg.API_DEPRECATED_INFO_MESSAGE); + /** * Generates environmental measures from a given list of environmental measures DTOs. * @param environmentMeasureDTOs @@ -105,6 +109,7 @@ private List environmentMeasurePostDTOsToEnvironmentMeasure( }) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) + @Deprecated public Response postEnvironmentMeasures( @ApiParam(value = DocumentationAnnotation.ENVIRONMENT_POST_DEFINITION) @Valid ArrayList environmentMeasures, @Context HttpServletRequest context) { @@ -116,7 +121,8 @@ public Response postEnvironmentMeasures( environmentDAO.user = userSession.getUser(); POSTResultsReturn result = environmentDAO.checkAndInsert(environmentMeasurePostDTOsToEnvironmentMeasure(environmentMeasures)); - + result.statusList.add(deprecatedStatus); + if (result.getHttpStatus().equals(Response.Status.CREATED)) { postResponse = new ResponseFormPOST(result.statusList); postResponse.getMetadata().setDatafiles(result.getCreatedResources()); @@ -127,7 +133,10 @@ public Response postEnvironmentMeasures( } return Response.status(result.getHttpStatus()).entity(postResponse).build(); } else { - postResponse = new ResponseFormPOST(new Status(StatusCodeMsg.REQUEST_ERROR, StatusCodeMsg.ERR, "Empty environment measure(s) to add")); + List statusList = new ArrayList<>(); + statusList.add(new Status(StatusCodeMsg.REQUEST_ERROR, StatusCodeMsg.ERR, "Empty environment measure(s) to add")); + statusList.add(deprecatedStatus); + postResponse = new ResponseFormPOST(statusList); return Response.status(Response.Status.BAD_REQUEST).entity(postResponse).build(); } } @@ -191,6 +200,7 @@ public Response postEnvironmentMeasures( example = GlobalWebserviceValues.AUTHENTICATION_SCHEME + " ") }) @Produces(MediaType.APPLICATION_JSON) + @Deprecated public Response getEnvironmentMeasures( @ApiParam(value = DocumentationAnnotation.PAGE_SIZE) @QueryParam(GlobalWebserviceValues.PAGE_SIZE) @DefaultValue(DefaultBrapiPaginationValues.PAGE_SIZE) @Min(0) int pageSize, @ApiParam(value = DocumentationAnnotation.PAGE) @QueryParam(GlobalWebserviceValues.PAGE) @DefaultValue(DefaultBrapiPaginationValues.PAGE) @Min(0) int page, @@ -224,7 +234,7 @@ public Response getEnvironmentMeasures( ArrayList list = new ArrayList<>(); ArrayList statusList = new ArrayList<>(); ResultForm getResponse; - + statusList.add(deprecatedStatus); if (measures == null) { // Request failure getResponse = new ResultForm<>(0, 0, list, true, 0); diff --git a/phis2-ws/src/main/java/opensilex/service/resource/SensorResourceService.java b/phis2-ws/src/main/java/opensilex/service/resource/SensorResourceService.java index 664e9c06a..e0de792fb 100644 --- a/phis2-ws/src/main/java/opensilex/service/resource/SensorResourceService.java +++ b/phis2-ws/src/main/java/opensilex/service/resource/SensorResourceService.java @@ -7,6 +7,7 @@ //****************************************************************************** package opensilex.service.resource; +import com.mongodb.BasicDBObjectBuilder; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -18,7 +19,6 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; -import javax.validation.constraints.Email; import javax.validation.constraints.Min; import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; @@ -36,11 +36,14 @@ import opensilex.service.configuration.DateFormat; import opensilex.service.configuration.DefaultBrapiPaginationValues; import opensilex.service.configuration.GlobalWebserviceValues; +import opensilex.service.dao.DataDAO; +import opensilex.service.dao.ProvenanceDAO; import opensilex.service.dao.SensorDAO; import opensilex.service.dao.SensorProfileDAO; import opensilex.service.dao.exception.DAOPersistenceException; import opensilex.service.documentation.DocumentationAnnotation; import opensilex.service.documentation.StatusCodeMsg; +import opensilex.service.model.Data; import opensilex.service.resource.validation.interfaces.Date; import opensilex.service.resource.validation.interfaces.Required; import opensilex.service.resource.validation.interfaces.URL; @@ -51,17 +54,19 @@ import opensilex.service.view.brapi.form.ResponseFormPOST; import opensilex.service.result.ResultForm; import opensilex.service.model.Sensor; +import opensilex.service.resource.dto.data.DataDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import opensilex.service.resource.dto.sensor.SensorDTO; import opensilex.service.resource.dto.sensor.SensorDetailDTO; import opensilex.service.resource.dto.sensor.SensorPostDTO; import opensilex.service.resource.dto.sensor.SensorProfileDTO; +import opensilex.service.view.model.provenance.Provenance; /** * Sensor resource service. * @update [Andreas Garcia] 15 Apr. 2019: handle DAO persistence exceptions thrown by property DAO functions. - * @author Morgane Vidal + * @author Morgane Vidal */ @Api("/sensors") @Path("/sensors") @@ -175,10 +180,12 @@ public Response getSensorsBySearch( SensorDAO sensorDAO = new SensorDAO(); //1. Get count Integer totalCount = sensorDAO.count(uri, rdfType, label, brand, serialNumber, model, inServiceDate, dateOfPurchase, dateOfLastCalibration, personInCharge); - - //2. Get sensors - ArrayList sensorsFounded = sensorDAO.find(page, pageSize, uri, rdfType, label, brand, serialNumber, model, inServiceDate, dateOfPurchase, dateOfLastCalibration, personInCharge); - + ArrayList sensorsFounded = new ArrayList<>(); + //2. Get sensors + if(totalCount > 0){ + sensorsFounded = sensorDAO.find(page, pageSize, uri, rdfType, label, brand, serialNumber, model, inServiceDate, dateOfPurchase, dateOfLastCalibration, personInCharge); + } + //3. Return result ArrayList statusList = new ArrayList<>(); ArrayList sensorsToReturn = new ArrayList<>(); @@ -649,4 +656,134 @@ public Response putMeasuredVariables( return Response.status(result.getHttpStatus()).entity(postResponse).build(); } -} + + /** + * Sensor Data GET service. + * + * @param pageSize + * @param page + * @param provenanceUri + * @param variablesUri + * @param startDate + * @param endDate + * @param object + * @param uri + * @return list of the data corresponding to the search params given + * @example + * { + * "metadata": { + * "pagination": { + * "pageSize": 20, + * "currentPage": 0, + * "totalCount": 3, + * "totalPages": 1 + * }, + * "status": [], + * "datafiles": [] + * }, + * "result": { + * "data": [ + * { + * "uri": "http://www.phenome-fppn.fr/diaphen/id/data/d2plf65my4rc2odiv2lbjgukc2zswkqyoddh25jtoy4b5pf3le3q4ec5c332f5cd44ce82977e404cebf83c", + * "provenanceUri": "http://www.phenome-fppn.fr/mtp/2018/pv181515071552", + * "objectUri": "http://www.phenome-fppn.fr/diaphen/2018/o18001199", + * "variableUri": "http://www.phenome-fppn.fr/diaphen/id/variables/v009", + * "date": "2017-06-15T00:00:00+0200", + * "value": 2.4 + * }, + * { + * "uri": "http://www.phenome-fppn.fr/diaphen/id/data/pttdrrqybxoyku4img323dyrhmpp267mhnpiw3vld2wm6tap3vwq93b344c429ec45bb9b185edfe5bc2b64", + * "provenanceUri": "http://www.phenome-fppn.fr/mtp/2018/pv181515071552", + * "objectUri": "http://www.phenome-fppn.fr/diaphen/2018/o18001199", + * "variableUri": "http://www.phenome-fppn.fr/diaphen/id/variables/v009", + * "date": "2017-06-16T00:00:00+0200", + * "value": "2017-06-15T00:00:00+0200" + * } + * ] + * } + * } + */ + @GET + @Path("{uri}/data") + @ApiOperation(value = "Get data mesured by a sensor") + @ApiResponses(value = { + @ApiResponse(code = 201, message = "Data mesured by a sensor", response = ResponseFormPOST.class), + @ApiResponse(code = 400, message = DocumentationAnnotation.BAD_USER_INFORMATION), + @ApiResponse(code = 401, message = DocumentationAnnotation.USER_NOT_AUTHORIZED), + @ApiResponse(code = 500, message = DocumentationAnnotation.ERROR_SEND_DATA) + }) + @ApiImplicitParams({ + @ApiImplicitParam(name = GlobalWebserviceValues.AUTHORIZATION, required = true, + dataType = GlobalWebserviceValues.DATA_TYPE_STRING, paramType = GlobalWebserviceValues.HEADER, + value = DocumentationAnnotation.ACCES_TOKEN, + example = GlobalWebserviceValues.AUTHENTICATION_SCHEME + " ") + }) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getSensorData( + @PathParam("uri") @Required @URL String uri, + @ApiParam(value = "Search by variable", example = DocumentationAnnotation.EXAMPLE_VARIABLE_URI, required = true) @QueryParam("variable") @Required @URL String variablesUri, + @ApiParam(value = "Search by provenance", example = DocumentationAnnotation.EXAMPLE_PROVENANCE_URI) @QueryParam("provenance") @URL String provenanceUri, + @ApiParam(value = "Search by minimal date", example = DocumentationAnnotation.EXAMPLE_XSDDATETIME) @QueryParam("startDate") @Date({DateFormat.YMDTHMSZ, DateFormat.YMD}) String startDate, + @ApiParam(value = "Search by maximal date", example = DocumentationAnnotation.EXAMPLE_XSDDATETIME) @QueryParam("endDate") @Date({DateFormat.YMDTHMSZ, DateFormat.YMD}) String endDate, + @ApiParam(value = "Search by object uri", example = DocumentationAnnotation.EXAMPLE_SCIENTIFIC_OBJECT_URI) @QueryParam("object") @URL String object, + @ApiParam(value = DocumentationAnnotation.PAGE_SIZE) @QueryParam(GlobalWebserviceValues.PAGE_SIZE) @DefaultValue(DefaultBrapiPaginationValues.PAGE_SIZE) @Min(0) int pageSize, + @ApiParam(value = DocumentationAnnotation.PAGE) @QueryParam(GlobalWebserviceValues.PAGE) @DefaultValue(DefaultBrapiPaginationValues.PAGE) @Min(0) int page + ) { + DataDAO dataDAO = new DataDAO(); + dataDAO.setPage(page); + dataDAO.setPageSize(pageSize); + + ProvenanceDAO provenanceDAO = new ProvenanceDAO(); + provenanceDAO.setPage(0); + provenanceDAO.setPageSize(500); + + //1. Get associated sensors + ArrayList provenanceUrisAssociatedToSensor = new ArrayList<>(); + if (provenanceUri != null) { + provenanceUrisAssociatedToSensor.add(provenanceUri); + } else { + Provenance searchProvenance = new Provenance(); + String jsonFilter = BasicDBObjectBuilder.start("metadata.prov:Agent.prov:id", uri).get().toString(); + ArrayList provenances = provenanceDAO.getProvenances(searchProvenance, jsonFilter); + + for (Provenance provenance : provenances) { + provenanceUrisAssociatedToSensor.add(provenance.getUri()); + } + } + List objectsUris = new ArrayList<>(); + List dataFounded = new ArrayList<>(); + Integer totalCount = 0; + if (!provenanceUrisAssociatedToSensor.isEmpty()) { + if (object != null) { + objectsUris.add(object); + } + //2. Get sensor data count + totalCount = dataDAO.count(variablesUri, startDate, endDate, objectsUris, provenanceUrisAssociatedToSensor); + //3. Get sensor data + if (totalCount > 0) { + dataFounded = dataDAO.find(page, pageSize, variablesUri, startDate, endDate, objectsUris, provenanceUrisAssociatedToSensor); + } + } + //4. Return result + ArrayList statusList = new ArrayList<>(); + ArrayList sensorsToReturn = new ArrayList<>(); + ResultForm getResponse; + if (dataFounded == null) { //Request failure + getResponse = new ResultForm<>(0, 0, sensorsToReturn, true); + return noResultFound(getResponse, statusList); + } else if (dataFounded.isEmpty()) { //No result found + getResponse = new ResultForm<>(0, 0, sensorsToReturn, true); + return noResultFound(getResponse, statusList); + } else { //Results + //Convert all objects to DTOs + dataFounded.forEach((data) -> { + sensorsToReturn.add(new DataDTO(data)); + }); + + getResponse = new ResultForm<>(pageSize, page, sensorsToReturn, true, totalCount); + getResponse.setStatus(statusList); + return Response.status(Response.Status.OK).entity(getResponse).build(); + } + } +} \ No newline at end of file diff --git a/phis2-ws/src/main/java/opensilex/service/resource/dto/data/DataPostDTO.java b/phis2-ws/src/main/java/opensilex/service/resource/dto/data/DataPostDTO.java index 90bae4863..91c3bb29d 100644 --- a/phis2-ws/src/main/java/opensilex/service/resource/dto/data/DataPostDTO.java +++ b/phis2-ws/src/main/java/opensilex/service/resource/dto/data/DataPostDTO.java @@ -56,8 +56,7 @@ public class DataPostDTO extends AbstractVerifiedClass { protected Object value; @URL - @Required - @ApiModelProperty(example = DocumentationAnnotation.EXAMPLE_SENSOR_URI) + @ApiModelProperty(example = DocumentationAnnotation.EXAMPLE_SCIENTIFIC_OBJECT_URI) public String getObjectUri() { return objectUri; } @@ -161,4 +160,4 @@ private BigDecimal getBigDecimalOrNullIfInvalid(String value) { return null; } } -} +} \ No newline at end of file