/*******************************************************************************
* Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2015-2019)
*
* contact.vitam@culture.gouv.fr
*
* This software is a computer program whose purpose is to implement a digital archiving back-office system managing
* high volumetry securely and efficiently.
*
* This software is governed by the CeCILL 2.1 license under French law and abiding by the rules of distribution of free
* software. You can use, modify and/ or redistribute the software under the terms of the CeCILL 2.1 license as
* circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license,
* users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the
* successive licensors have only limited liability.
*
* In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or
* developing or reproducing the software by the user in light of its specific status of free software, that may mean
* that it is complicated to manipulate, and that also therefore means that it is reserved for developers and
* experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the
* software's suitability as regards their requirements in conditions enabling the security of their systems and/or data
* to be ensured and, more generally, to use and operate it in the same conditions as regards security.
*
* The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you
* accept its terms.
*******************************************************************************/
package fr.gouv.vitam.logbook.rest;
import java.io.File;
import java.io.IOException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Strings;
import fr.gouv.vitam.common.GlobalDataRest;
import fr.gouv.vitam.common.ParametersChecker;
import fr.gouv.vitam.common.PropertiesUtils;
import fr.gouv.vitam.common.ServerIdentity;
import fr.gouv.vitam.common.client.VitamRequestIterator;
import fr.gouv.vitam.common.database.builder.request.exception.InvalidCreateOperationException;
import fr.gouv.vitam.common.error.VitamError;
import fr.gouv.vitam.common.exception.InvalidParseOperationException;
import fr.gouv.vitam.common.guid.GUID;
import fr.gouv.vitam.common.json.JsonHandler;
import fr.gouv.vitam.common.logging.SysErrLogger;
import fr.gouv.vitam.common.logging.VitamLogger;
import fr.gouv.vitam.common.logging.VitamLoggerFactory;
import fr.gouv.vitam.common.model.LifeCycleStatusCode;
import fr.gouv.vitam.common.model.RequestResponseOK;
import fr.gouv.vitam.common.parameter.ParameterHelper;
import fr.gouv.vitam.common.server.application.resources.ApplicationStatusResource;
import fr.gouv.vitam.common.thread.VitamThreadUtils;
import fr.gouv.vitam.common.timestamp.TimeStampSignature;
import fr.gouv.vitam.common.timestamp.TimeStampSignatureWithKeystore;
import fr.gouv.vitam.common.timestamp.TimestampGenerator;
import fr.gouv.vitam.logbook.administration.core.LogbookAdministration;
import fr.gouv.vitam.logbook.administration.core.TraceabilityException;
import fr.gouv.vitam.logbook.common.parameters.LogbookLifeCycleObjectGroupParameters;
import fr.gouv.vitam.logbook.common.parameters.LogbookLifeCycleUnitParameters;
import fr.gouv.vitam.logbook.common.parameters.LogbookOperationParameters;
import fr.gouv.vitam.logbook.common.server.LogbookConfiguration;
import fr.gouv.vitam.logbook.common.server.LogbookDbAccess;
import fr.gouv.vitam.logbook.common.server.database.collections.LogbookCollections;
import fr.gouv.vitam.logbook.common.server.database.collections.LogbookLifeCycle;
import fr.gouv.vitam.logbook.common.server.database.collections.LogbookMongoDbAccessFactory;
import fr.gouv.vitam.logbook.common.server.database.collections.LogbookOperation;
import fr.gouv.vitam.logbook.common.server.exception.LogbookAlreadyExistsException;
import fr.gouv.vitam.logbook.common.server.exception.LogbookDatabaseException;
import fr.gouv.vitam.logbook.common.server.exception.LogbookException;
import fr.gouv.vitam.logbook.common.server.exception.LogbookNotFoundException;
import fr.gouv.vitam.logbook.lifecycles.api.LogbookLifeCycles;
import fr.gouv.vitam.logbook.lifecycles.core.LogbookLifeCyclesImpl;
import fr.gouv.vitam.logbook.operations.api.LogbookOperations;
import fr.gouv.vitam.logbook.operations.core.LogbookOperationsImpl;
import fr.gouv.vitam.workspace.client.WorkspaceClientFactory;
/**
* Logbook Resource implementation
*/
@Path("/logbook/v1")
@javax.ws.rs.ApplicationPath("webresources")
public class LogbookResource extends ApplicationStatusResource {
private static final int MAX_NB_PART_ITERATOR = 100;
private static final VitamLogger LOGGER = VitamLoggerFactory.getInstance(LogbookResource.class);
public static final String CERTIFICATE_ALIAS = "localhost";
private final LogbookOperations logbookOperation;
private final LogbookLifeCycles logbookLifeCycle;
private final LogbookConfiguration logbookConfiguration;
private final LogbookDbAccess mongoDbAccess;
private final LogbookAdministration logbookAdministration;
private static final String MISSING_THE_TENANT_ID_X_TENANT_ID =
"Missing the tenant ID (X-Tenant-Id) or wrong object Type";
/**
* Constructor
*
* @param configuration
*/
public LogbookResource(LogbookConfiguration configuration) {
if (configuration.isDbAuthentication()) {
logbookConfiguration =
new LogbookConfiguration(configuration.getMongoDbNodes(), configuration.getDbName(),
configuration.getClusterName(), configuration.getElasticsearchNodes(), true,
configuration.getDbUserName(), configuration.getDbPassword());
} else {
logbookConfiguration =
new LogbookConfiguration(configuration.getMongoDbNodes(), configuration.getDbName(),
configuration.getClusterName(), configuration.getElasticsearchNodes());
}
logbookConfiguration.setTenants(configuration.getTenants());
mongoDbAccess = LogbookMongoDbAccessFactory.create(logbookConfiguration);
logbookOperation = new LogbookOperationsImpl(mongoDbAccess);
TimeStampSignature timeStampSignature;
try {
final File file = PropertiesUtils.findFile(configuration.getP12LogbookFile());
timeStampSignature =
new TimeStampSignatureWithKeystore(file, configuration.getP12LogbookPassword().toCharArray());
} catch (KeyStoreException | CertificateException | IOException | UnrecoverableKeyException |
NoSuchAlgorithmException e) {
LOGGER.error("unable to instanciate TimeStampGenerator", e);
throw new RuntimeException(e);
}
final TimestampGenerator timestampGenerator = new TimestampGenerator(timeStampSignature);
final WorkspaceClientFactory clientFactory = WorkspaceClientFactory.getInstance();
WorkspaceClientFactory.changeMode(configuration.getWorkspaceUrl());
logbookAdministration = new LogbookAdministration(logbookOperation, timestampGenerator,
clientFactory);
LOGGER.debug("LogbookResource operation initialized");
logbookLifeCycle = new LogbookLifeCyclesImpl(mongoDbAccess);
LOGGER.debug("LogbookResource lifecycles initialized");
}
LogbookDbAccess getLogbookDbAccess() {
return mongoDbAccess;
}
/**
* Selects an operation
*
* @param id operation ID
* @param queryDsl the query containing the ID
* @return the response with a specific HTTP status
*/
@GET
@Path("/operations/{id_op}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getOperation(@PathParam("id_op") String id, JsonNode queryDsl) {
Status status;
try {
if (queryDsl == null) {
final LogbookOperation result = logbookOperation.getById(id);
return Response.status(Status.OK)
.entity(
new RequestResponseOK().setHits(1, 0, 1).addResult(JsonHandler.getFromString(result.toJson())))
.build();
} else {
final List<LogbookOperation> result = logbookOperation.select(queryDsl, false);
if (result.size() != 1) {
throw new LogbookDatabaseException("Result size different than 1.");
}
return Response.status(Status.OK)
.entity(new RequestResponseOK()
.setHits(1, 0, 1)
.addResult(JsonHandler.getFromString(result.get(0).toJson())))
.build();
}
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
status = Status.NOT_FOUND;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final InvalidParseOperationException | IllegalArgumentException | LogbookException exc) {
LOGGER.error(exc);
status = Status.PRECONDITION_FAILED;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
}
/**
* Create or Select a new operation
*
* @param operationId path param, the operation id
* @param operation the json serialized as a LogbookOperationParameters.
* @return the response with a specific HTTP status
*/
@POST
@Path("/operations/{id_op}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createOperation(@PathParam("id_op") String operationId,
LogbookOperationParameters operation) {
Response finalResponse;
finalResponse = Response.status(Response.Status.CREATED).build();
try {
LOGGER.debug(
operation.getParameterValue(LogbookOperation.getIdParameterName()).equals(operationId) + " " +
operation.getParameterValue(LogbookOperation.getIdParameterName()) + " =? " + operationId);
try {
ParameterHelper.checkNullOrEmptyParameters(operation);
} catch (final IllegalArgumentException e) {
LOGGER.error("Operations is incorrect", e);
return Response.status(Response.Status.BAD_REQUEST).build();
}
if (!operation.getParameterValue(LogbookOperation.getIdParameterName()).equals(operationId)) {
LOGGER.error("OperationId is not the same as in the operation parameter");
return Response.status(Response.Status.BAD_REQUEST).build();
}
logbookOperation.create(operation);
} catch (final LogbookAlreadyExistsException exc) {
LOGGER.error(exc);
finalResponse = Response.status(Response.Status.CONFLICT).build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
finalResponse = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
finalResponse = Response.status(Response.Status.BAD_REQUEST).build();
}
return finalResponse;
}
/**
* Append a new item on the given operation
*
* @param operationId the operation id
* @param operation the json serialized as a LogbookOperationParameters.
* @return the response with a specific HTTP status
*/
@PUT
@Path("/operations/{id_op}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updateOperation(@PathParam("id_op") String operationId, LogbookOperationParameters operation) {
Response finalResponse = Response.status(Response.Status.OK).build();
try {
ParameterHelper.checkNullOrEmptyParameters(operation);
} catch (final IllegalArgumentException e) {
LOGGER.error("Operations is incorrect", e);
return Response.status(Response.Status.BAD_REQUEST).build();
}
if (!operation.getParameterValue(LogbookOperation.getIdParameterName()).equals(operationId)) {
LOGGER.error("OperationId is not the same as in the operation parameter");
return Response.status(Response.Status.BAD_REQUEST).build();
}
try {
logbookOperation.update(operation);
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
finalResponse = Response.status(Response.Status.NOT_FOUND).build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
finalResponse = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
finalResponse = Response.status(Response.Status.BAD_REQUEST).build();
}
return finalResponse;
}
/**
* Run traceability secure operation for logbook
*
* @param xTenantId the tenant id
* @return the response with a specific HTTP status
*/
@POST
@Path("/operations/traceability")
@Produces(MediaType.APPLICATION_JSON)
public Response traceability(@HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId) {
if (Strings.isNullOrEmpty(xTenantId)) {
LOGGER.error(MISSING_THE_TENANT_ID_X_TENANT_ID);
return Response.status(Response.Status.BAD_REQUEST).build();
}
try {
Integer tenantId = Integer.parseInt(xTenantId);
VitamThreadUtils.getVitamSession().setTenantId(tenantId);
final GUID guid = logbookAdministration.generateSecureLogbook();
final List<String> resultAsJson = new ArrayList<>();
resultAsJson.add(guid.toString());
return Response.status(Status.OK)
.entity(new RequestResponseOK<String>()
.setHits(1, 0, 1)
.addAllResults(resultAsJson))
.build();
} catch (TraceabilityException | LogbookNotFoundException | LogbookDatabaseException |
InvalidCreateOperationException | InvalidParseOperationException e) {
LOGGER.error("unable to generate traceability log", e);
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(new RequestResponseOK())
.build();
}
}
/**
* Bulk Create Operation
*
* @param query as JsonNode or Operations Logbooks as ArrayNode
* @return Response of SELECT query with POST method or CREATED
*/
@POST
@Path("/operations")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response bulkCreateOperation(JsonNode query) {
// query is in fact a bulk LogbookOperationsParameter
try {
ParametersChecker.checkParameter("Logbook parameters", query);
} catch (final IllegalArgumentException e) {
LOGGER.error("Operations is incorrect", e);
return Response.status(Response.Status.BAD_REQUEST).build();
}
try {
final LogbookOperationParameters[] arrayOperations =
JsonHandler.getFromJsonNode(query, LogbookOperationParameters[].class);
logbookOperation.createBulkLogbookOperation(arrayOperations);
} catch (final LogbookDatabaseException e) {
LOGGER.error(e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (final LogbookAlreadyExistsException e) {
LOGGER.error(e);
return Response.status(Response.Status.CONFLICT).build();
} catch (InvalidParseOperationException | IllegalArgumentException e) {
LOGGER.error(e);
final Status status = Status.PRECONDITION_FAILED;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(e.getMessage()))
.build();
}
return Response.status(Response.Status.CREATED).build();
}
/**
* Select a list of operations
*
* @param query DSL as JsonNode
* @return Response containt the list of loglook operation
*/
@GET
@Path("/operations")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response selectOperation(JsonNode query) {
Status status;
try {
final List<LogbookOperation> result = logbookOperation.select(query);
return Response.status(Status.OK)
.entity(new RequestResponseOK<LogbookOperation>()
.setHits(result.size(), 0, 1)
.setQuery(query)
.addAllResults(result))
.build();
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
status = Status.NOT_FOUND;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final InvalidParseOperationException | IllegalArgumentException | LogbookException exc) {
LOGGER.error(exc);
status = Status.PRECONDITION_FAILED;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
}
/**
* Update Operation With Bulk Mode
*
* @param arrayNodeOperations as ArrayNode of operations to add to existing Operation Logbook entry
* @return Response with a status of OK if updated
*/
@PUT
@Path("/operations")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
// Note: here let String since we need JsonHandler to parser the object
public Response updateOperationBulk(String arrayNodeOperations) {
try {
final LogbookOperationParameters[] arrayOperations =
JsonHandler.getFromString(arrayNodeOperations, LogbookOperationParameters[].class);
logbookOperation.updateBulkLogbookOperation(arrayOperations);
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.NOT_FOUND).build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (final IllegalArgumentException | InvalidParseOperationException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.BAD_REQUEST).build();
}
return Response.status(Response.Status.OK).build();
}
/***** LIFE CYCLES UNIT - START *****/
/**
* GET multiple Unit Life Cycles through VitamRequestIterator
*
* @param operationId the operation id
* @param xcursor if True means new query, if False means end of query from client side
* @param xcursorId if present, means continue on Cursor
* @param evtStatus the evenement status (commited / not_commited)
* @param query as JsonNode
* @return the response with a specific HTTP status
*/
@GET
@Path("/operations/{id_op}/unitlifecycles")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getUnitLifeCyclesByOperation(@PathParam("id_op") String operationId,
@HeaderParam(GlobalDataRest.X_CURSOR) boolean xcursor,
@HeaderParam(GlobalDataRest.X_CURSOR_ID) String xcursorId,
@HeaderParam(GlobalDataRest.X_EVENT_STATUS) String evtStatus, JsonNode query) {
Status status;
try {
String cursorId = xcursorId;
if (VitamRequestIterator.isEndOfCursor(xcursor, xcursorId)) {
// terminate the cursor
logbookLifeCycle.finalizeCursor(cursorId);
final ResponseBuilder builder = Response.status(Status.NO_CONTENT);
return VitamRequestIterator.setHeaders(builder, xcursor, null).build();
}
final JsonNode nodeQuery = JsonHandler.createObjectNode();
if (VitamRequestIterator.isNewCursor(xcursor, xcursorId)) {
// check null or empty parameters
ParametersChecker.checkParameter("Arguments must not be null", operationId, query);
LifeCycleStatusCode lifeCycleStatus = getSelectLifeCycleStatusCode(evtStatus);
// create the cursor
cursorId = logbookLifeCycle.createCursorUnit(operationId, query,
fromLifeCycleStatusToUnitCollection(lifeCycleStatus));
}
final RequestResponseOK responseOK =
new RequestResponseOK().setQuery(nodeQuery);
int nb = 0;
try {
for (; nb < MAX_NB_PART_ITERATOR; nb++) {
final LogbookLifeCycle lcUnit = logbookLifeCycle.getCursorUnitNext(cursorId);
responseOK.addResult(JsonHandler.toJsonNode(lcUnit));
}
} catch (final LogbookNotFoundException e) {
// Ignore
LOGGER.debug(e);
}
final ResponseBuilder builder =
Response.status(nb < MAX_NB_PART_ITERATOR ? Status.OK : Status.PARTIAL_CONTENT)
.entity(responseOK
.setHits(nb, 0, nb).setQuery(nodeQuery));
return VitamRequestIterator.setHeaders(builder, xcursor, cursorId).build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
final ResponseBuilder builder = Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext(ServerIdentity.getInstance().getRole()).setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()));
return VitamRequestIterator.setHeaders(builder, xcursor, null).build();
} catch (final IllegalArgumentException | InvalidParseOperationException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
final ResponseBuilder builder = Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext(ServerIdentity.getInstance().getRole()).setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()));
return VitamRequestIterator.setHeaders(builder, xcursor, null).build();
}
}
/**
* Create Unit Life Cycle
*
* @param operationId the operation id
* @param unitLcId the life cycle id
* @param parameters the json serialized as a LogbookLifeCycleUnitParameters.
* @return the response with a specific HTTP status
*/
@POST
@Path("/operations/{id_op}/unitlifecycles/{id_lc}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createUnitLifeCyclesByOperation(@PathParam("id_op") String operationId,
@PathParam("id_lc") String unitLcId, LogbookLifeCycleUnitParameters parameters) {
Status status;
try {
try {
// check null or empty parameters
ParameterHelper.checkNullOrEmptyParameters(parameters);
} catch (final IllegalArgumentException e) {
LOGGER.error("unit lifecycles is incorrect", e);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(e.getMessage()))
.build();
}
/**
* create unit logbook Life cycle
*/
logbookLifeCycle.createUnit(operationId, unitLcId, parameters);
} catch (final LogbookAlreadyExistsException exc) {
LOGGER.error(exc);
status = Status.CONFLICT;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
return Response.status(Response.Status.CREATED).build();
}
/**
* Update Unit Life Cycle
*
* @param operationId the operation id
* @param unitLcId the life cycle id
* @param evtStatus the operation type : Update or Commit the lifeCycle
* @param parameters the json serialized as a LogbookLifeCycleUnitParameters.
* @return the response with a specific HTTP status
*/
@PUT
@Path("/operations/{id_op}/unitlifecycles/{id_lc}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updateUnitLifeCyclesByOperation(@PathParam("id_op") String operationId,
@PathParam("id_lc") String unitLcId, @HeaderParam(GlobalDataRest.X_EVENT_STATUS) String evtStatus,
LogbookLifeCycleUnitParameters parameters) {
Status status;
try {
// Decide which operation to execute : Update a Temporary LifeCycle or Commit the unit lifeCycle based on
// X-EVENT-STATUS header value
// Note : By default, the operation is an update process if the header wasn't given
LifeCycleStatusCode lifeCycleStatus = getUpdateOrCommitLifeCycleStatusCode(evtStatus);
// It is an update on a temporary lifeCycle
if (LifeCycleStatusCode.LIFE_CYCLE_IN_PROCESS.equals(lifeCycleStatus)) {
try {
// check null or empty parameters
ParameterHelper.checkNullOrEmptyParameters(parameters);
} catch (final IllegalArgumentException e) {
LOGGER.error("unit lifecycles is incorrect", e);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(e.getMessage()))
.build();
}
logbookLifeCycle.updateUnit(operationId, unitLcId, parameters);
} else {
// Commit the given unit lifeCycle
logbookLifeCycle.commitUnit(operationId, unitLcId);
}
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
status = Status.NOT_FOUND;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (LogbookAlreadyExistsException exc) {
LOGGER.error(exc);
status = Status.CONFLICT;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
return Response.status(Response.Status.OK).build();
}
/**
* Delete Unit Life Cycle
*
* @param operationId the operation id
* @param unitLcId the life cycle id
* @return the response with a specific HTTP status
*/
@DELETE
@Path("/operations/{id_op}/unitlifecycles/{id_lc}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response deleteUnitLifeCyclesByOperation(@PathParam("id_op") String operationId,
@PathParam("id_lc") String unitLcId) {
Status status;
try {
logbookLifeCycle.rollbackUnit(operationId, unitLcId);
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
status = Status.NOT_FOUND;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
return Response.status(Response.Status.OK).build();
}
/**
* Commit Unit Life Cycle
*
* @param operationId the operation id
* @param unitLcId the life cycle id
* @return the response with a specific HTTP status
*/
@Deprecated
@PUT
@Path("/operations/{id_op}/unitlifecycles/{id_lc}/commit")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response commitUnitLifeCyclesByOperation(@PathParam("id_op") String operationId,
@PathParam("id_lc") String unitLcId) {
LOGGER.debug("UnitLifeCycle commited: " + unitLcId);
try {
logbookLifeCycle.commitUnit(operationId, unitLcId);
} catch (LogbookDatabaseException e) {
LOGGER.error(e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (LogbookNotFoundException e) {
LOGGER.error(e);
return Response.status(Response.Status.NOT_FOUND).build();
} catch (LogbookAlreadyExistsException e) {
LOGGER.error(e);
return Response.status(Response.Status.CONFLICT).build();
}
return Response.status(Response.Status.OK).build();
}
/**
* Lifecycle Unit Bulk Create
*
* @param idOp
* @param array Lifecycle Unit Logbooks as ArrayNode
* @return Response of CREATED
*/
@POST
@Path("/operations/{id_op}/unitlifecycles")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response bulkCreateUnit(@PathParam("id_op") String idOp, String array) {
// array as a bulk LogbookLifeCycleParameters
try {
ParametersChecker.checkParameter("Logbook parameters", array);
} catch (final IllegalArgumentException e) {
LOGGER.error("Lifecycles is incorrect", e);
return Response.status(Response.Status.BAD_REQUEST).build();
}
try {
final LogbookLifeCycleUnitParameters[] arrayLifecycles =
JsonHandler.getFromString(array, LogbookLifeCycleUnitParameters[].class);
logbookLifeCycle.createBulkLogbookLifecycle(idOp, arrayLifecycles);
} catch (final LogbookDatabaseException e) {
LOGGER.error(e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (final LogbookAlreadyExistsException e) {
LOGGER.error(e);
return Response.status(Response.Status.CONFLICT).build();
} catch (InvalidParseOperationException | IllegalArgumentException e) {
LOGGER.error(e);
final Status status = Status.PRECONDITION_FAILED;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(e.getMessage()))
.build();
}
return Response.status(Response.Status.CREATED).build();
}
/**
* Update Lifecycle With Bulk Mode
*
* @param idOp
* @param arrayNodeLifecycle as ArrayNode of operations to add to existing Lifecycle Logbook entry
* @return Response with a status of OK if updated
*/
@PUT
@Path("/operations/{id_op}/unitlifecycles")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
// Note: here let String since we need JsonHandler to parser the object
public Response updateBulkUnit(@PathParam("id_op") String idOp, String arrayNodeLifecycle) {
try {
final LogbookLifeCycleUnitParameters[] arrayLifecycles =
JsonHandler.getFromString(arrayNodeLifecycle, LogbookLifeCycleUnitParameters[].class);
logbookLifeCycle.updateBulkLogbookLifecycle(idOp, arrayLifecycles);
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.NOT_FOUND).build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (final IllegalArgumentException | InvalidParseOperationException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.BAD_REQUEST).build();
} catch (LogbookAlreadyExistsException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.CONFLICT).build();
}
return Response.status(Response.Status.OK).build();
}
/**
* gets the unit life cycle based on its id
*
* @param unitLifeCycleId the unit life cycle id
* @param evtStatus the lifeCycle Status that we are looking for : COMMITTED or IN_PROCESS
* @param queryDsl
* @return the unit life cycle
*/
@GET
@Path("/unitlifecycles/{id_lc}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUnitLifeCycleById(@PathParam("id_lc") String unitLifeCycleId,
@HeaderParam(GlobalDataRest.X_EVENT_STATUS) String evtStatus, JsonNode queryDsl) {
Status status;
try {
LifeCycleStatusCode lifeCycleStatusCode = getSelectLifeCycleStatusCode(evtStatus);
final LogbookLifeCycle result =
logbookLifeCycle.getUnitById(queryDsl, fromLifeCycleStatusToUnitCollection(lifeCycleStatusCode));
return Response.status(Status.OK)
.entity(new RequestResponseOK()
.setHits(1, 0, 1)
.addResult(JsonHandler.getFromString(result.toJson())))
.build();
} catch (final LogbookNotFoundException exc) {
LOGGER.debug(exc);
return Response.status(Status.NOT_FOUND)
.entity(new RequestResponseOK()
.setHits(0, 0, 1)
.addResult(JsonHandler.createArrayNode()))
.build();
} catch (final LogbookException | InvalidParseOperationException exc) {
LOGGER.error(exc);
status = Status.PRECONDITION_FAILED;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
}
/**
* Gets the unit life cycle status based on its id
*
* @param unitLifeCycleId the unit life cycle id
* @return the unit life cycle status : Committed or In process
*/
@HEAD
@Path("/unitlifecycles/{id_lc}")
public Response getUnitLifeCycleStatus(@PathParam("id_lc") String unitLifeCycleId) {
Status status;
try {
LifeCycleStatusCode lifeCycleStatusCode = logbookLifeCycle.getUnitLifeCycleStatus(unitLifeCycleId);
if (lifeCycleStatusCode != null) {
// Build the response
return Response.status(Status.OK)
.header(GlobalDataRest.X_EVENT_STATUS, lifeCycleStatusCode.toString())
.build();
} else {
throw new LogbookNotFoundException(
String.format("No lifeCycle found for the given id (%s).", unitLifeCycleId));
}
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
return Response.status(Status.NOT_FOUND)
.entity(new RequestResponseOK()
.setHits(0, 0, 1)
.addResult(JsonHandler.createArrayNode()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
}
/**
* Gets a list of unit lifeCycles using a queryDsl
*
* @param queryDsl a DSL query
* @param evtStatus the lifeCycle Status that we are looking for : COMMITTED or IN_PROCESS
* @return a list of unit lifeCycles
*/
@GET
@Path("/unitlifecycles")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getUnitLifeCycle(JsonNode queryDsl, @HeaderParam(GlobalDataRest.X_EVENT_STATUS) String evtStatus) {
Status status;
try {
LifeCycleStatusCode lifeCycleStatusCode = getSelectLifeCycleStatusCode(evtStatus);
final List<LogbookLifeCycle> result =
logbookLifeCycle.selectUnit(queryDsl, fromLifeCycleStatusToUnitCollection(lifeCycleStatusCode));
return Response.status(Status.OK)
.entity(new RequestResponseOK<LogbookOperation>()
.setHits(result.size(), 0, 1)
.setQuery(queryDsl)
.addAllResults(result))
.build();
} catch (final LogbookNotFoundException exc) {
LOGGER.debug(exc);
return Response.status(Status.NOT_FOUND)
.entity(new RequestResponseOK()
.setHits(0, 0, 1)
.addResult(JsonHandler.createArrayNode()))
.build();
} catch (final LogbookException | InvalidParseOperationException exc) {
LOGGER.error(exc);
status = Status.PRECONDITION_FAILED;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
}
/***** LIFE CYCLES UNIT - END *****/
/***** LIFE CYCLES OBJECT GROUP - START *****/
/**
* GET multiple Unit Life Cycles through VitamRequestIterator
*
* @param operationId the operation id
* @param xcursor if True means new query, if False means end of query from client side
* @param xcursorId if present, means continue on Cursor
* @param evtStatus the evenement status (commited / not_commited)
* @param query as JsonNode
* @return the response with a specific HTTP status
*/
@GET
@Path("/operations/{id_op}/objectgrouplifecycles")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getObjectGroupLifeCyclesByOperation(@PathParam("id_op") String operationId,
@HeaderParam(GlobalDataRest.X_CURSOR) boolean xcursor,
@HeaderParam(GlobalDataRest.X_CURSOR_ID) String xcursorId,
@HeaderParam(GlobalDataRest.X_EVENT_STATUS) String evtStatus, JsonNode query) {
Status status;
try {
String cursorId = xcursorId;
if (VitamRequestIterator.isEndOfCursor(xcursor, xcursorId)) {
// terminate the cursor
logbookLifeCycle.finalizeCursor(cursorId);
final ResponseBuilder builder = Response.status(Status.NO_CONTENT);
return VitamRequestIterator.setHeaders(builder, xcursor, null).build();
}
final JsonNode nodeQuery = JsonHandler.createObjectNode();
if (VitamRequestIterator.isNewCursor(xcursor, xcursorId)) {
// check null or empty parameters
ParametersChecker.checkParameter("Arguments must not be null", operationId, query);
// Note : By default, the select will be done on Production collection if the header wasn't given
LifeCycleStatusCode lifeCycleStatus = getSelectLifeCycleStatusCode(evtStatus);
// create the cursor
cursorId = logbookLifeCycle.createCursorObjectGroup(operationId, query,
fromLifeCycleStatusToObjectGroupCollection(lifeCycleStatus));
}
final RequestResponseOK responseOK = new RequestResponseOK().setQuery(nodeQuery);
int nb = 0;
try {
for (; nb < MAX_NB_PART_ITERATOR; nb++) {
final LogbookLifeCycle lcObjectGroup = logbookLifeCycle.getCursorObjectGroupNext(cursorId);
responseOK.addResult(JsonHandler.toJsonNode(lcObjectGroup));
}
} catch (final LogbookNotFoundException | InvalidParseOperationException e) {
// Ignore
LOGGER.debug(e);
}
final ResponseBuilder builder =
Response.status(nb < MAX_NB_PART_ITERATOR ? Status.OK : Status.PARTIAL_CONTENT)
.entity(responseOK
.setHits(nb, 0, nb).setQuery(nodeQuery));
return VitamRequestIterator.setHeaders(builder, xcursor, cursorId).build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
final ResponseBuilder builder = Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()));
return VitamRequestIterator.setHeaders(builder, xcursor, null).build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
final ResponseBuilder builder = Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()));
return VitamRequestIterator.setHeaders(builder, xcursor, null).build();
}
}
/**
* Create object Group Life Cycle
*
* @param operationId the operation id
* @param objGrpId the life cycle id
* @param parameters the json serialized as a LogbookLifeCycleObjectGroupParameters.
* @return the response with a specific HTTP status
*/
@POST
@Path("/operations/{id_op}/objectgrouplifecycles/{id_lc}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createObjectGroupLifeCyclesByOperation(@PathParam("id_op") String operationId,
@PathParam("id_lc") String objGrpId, LogbookLifeCycleObjectGroupParameters parameters) {
Status status;
try {
try {
// check null or empty parameters
ParameterHelper.checkNullOrEmptyParameters(parameters);
} catch (final IllegalArgumentException e) {
LOGGER.error("objectgrouplifecycles is incorrect", e);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(e.getMessage()))
.build();
}
/**
* create objectgroup logbook Life cycle
*/
logbookLifeCycle.createObjectGroup(operationId, objGrpId, parameters);
} catch (final LogbookAlreadyExistsException exc) {
LOGGER.error(exc);
status = Status.CONFLICT;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
return Response.status(Response.Status.CREATED).build();
}
/**
* Update object Group Life Cycle
*
* @param operationId the operation id
* @param objGrpId the life cycle id
* @param evtStatus the operation type : Update or Commit the lifeCycle
* @param parameters the json serialized as a LogbookLifeCycleObjectGroupParameters.
* @return the response with a specific HTTP status
*/
@PUT
@Path("/operations/{id_op}/objectgrouplifecycles/{id_lc}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updateObjectGroupLifeCyclesByOperation(@PathParam("id_op") String operationId,
@PathParam("id_lc") String objGrpId,
@HeaderParam(GlobalDataRest.X_EVENT_STATUS) String evtStatus,
LogbookLifeCycleObjectGroupParameters parameters) {
Status status;
try {
// Decide which operation to execute : Update a Temporary LifeCycle or Commit the objectGroup lifeCycle
// based on X-EVENT-STATUS header value
// Note : By default, the operation is an update process if the header wasn't given
LifeCycleStatusCode lifeCycleStatus = getUpdateOrCommitLifeCycleStatusCode(evtStatus);
// It is an update on a temporary lifeCycle
if (LifeCycleStatusCode.LIFE_CYCLE_IN_PROCESS.equals(lifeCycleStatus)) {
try {
// check null or empty parameters
ParameterHelper.checkNullOrEmptyParameters(parameters);
} catch (final IllegalArgumentException e) {
LOGGER.error("objectgrouplifecycles is incorrect", e);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(e.getMessage()))
.build();
}
/**
* update object group logbook Life cycle
*/
logbookLifeCycle.updateObjectGroup(operationId, objGrpId, parameters);
} else {
// Commit the given objectGroup lifeCycle
logbookLifeCycle.commitObjectGroup(operationId, objGrpId);
}
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
status = Status.NOT_FOUND;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (LogbookAlreadyExistsException exc) {
LOGGER.error(exc);
status = Status.CONFLICT;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
return Response.status(Response.Status.OK).build();
}
/**
* Delete object Group Life Cycle
*
* @param operationId the operation id
* @param objGrpId the life cycle id
* @return the response with a specific HTTP status
*/
@DELETE
@Path("/operations/{id_op}/objectgrouplifecycles/{id_lc}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response deleteObjectGroupLifeCyclesByOperation(@PathParam("id_op") String operationId,
@PathParam("id_lc") String objGrpId) {
Status status;
try {
logbookLifeCycle.rollbackObjectGroup(operationId, objGrpId);
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
status = Status.NOT_FOUND;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
return Response.status(Response.Status.OK).build();
}
/**
* Commit object Group Life Cycle
*
* @param operationId the operation id
* @param objGrpId the life cycle id
* @return the response with a specific HTTP status
*/
@Deprecated
@PUT
@Path("/operations/{id_op}/objectgrouplifecycles/{id_lc}/commit")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response commitObjectGroupLifeCyclesByOperation(@PathParam("id_op") String operationId,
@PathParam("id_lc") String objGrpId) {
LOGGER.debug("ObjectGroup commited: " + objGrpId);
try {
logbookLifeCycle.commitObjectGroup(operationId, objGrpId);
} catch (LogbookDatabaseException e) {
LOGGER.error(e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (LogbookNotFoundException e) {
LOGGER.error(e);
return Response.status(Response.Status.NOT_FOUND).build();
} catch (LogbookAlreadyExistsException e) {
LOGGER.error(e);
return Response.status(Response.Status.CONFLICT).build();
}
return Response.status(Response.Status.OK).build();
}
/**
* Lifecycle ObjectGroup Bulk Create
*
* @param idOp
* @param array Lifecycle ObjectGroup Logbooks as ArrayNode
* @return Response of CREATED
*/
@POST
@Path("/operations/{id_op}/objectgrouplifecycles")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response bulkCreateObjectGroup(@PathParam("id_op") String idOp, String array) {
// array as a bulk LogbookLifeCycleParameters
try {
ParametersChecker.checkParameter("Logbook parameters", array);
} catch (final IllegalArgumentException e) {
LOGGER.error("Lifecycles is incorrect", e);
return Response.status(Response.Status.BAD_REQUEST).build();
}
try {
final LogbookLifeCycleObjectGroupParameters[] arrayLifecycles =
JsonHandler.getFromString(array, LogbookLifeCycleObjectGroupParameters[].class);
logbookLifeCycle.createBulkLogbookLifecycle(idOp, arrayLifecycles);
} catch (final LogbookDatabaseException e) {
LOGGER.error(e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (final LogbookAlreadyExistsException e) {
LOGGER.error(e);
return Response.status(Response.Status.CONFLICT).build();
} catch (InvalidParseOperationException | IllegalArgumentException e) {
LOGGER.error(e);
final Status status = Status.PRECONDITION_FAILED;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(e.getMessage()))
.build();
}
return Response.status(Response.Status.CREATED).build();
}
/**
* Update Lifecycle ObjectGroup With Bulk Mode
*
* @param idOp
* @param arrayNodeLifecycle as ArrayNode of operations to add to existing Lifecycle Logbook entry
* @return Response with a status of OK if updated
*/
@PUT
@Path("/operations/{id_op}/objectgrouplifecycles")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
// Note: here let String since we need JsonHandler to parser the object
public Response updateBulkObjectGroup(@PathParam("id_op") String idOp, String arrayNodeLifecycle) {
try {
final LogbookLifeCycleObjectGroupParameters[] arrayLifecycles =
JsonHandler.getFromString(arrayNodeLifecycle, LogbookLifeCycleObjectGroupParameters[].class);
logbookLifeCycle.updateBulkLogbookLifecycle(idOp, arrayLifecycles);
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.NOT_FOUND).build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (final IllegalArgumentException | InvalidParseOperationException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.BAD_REQUEST).build();
} catch (LogbookAlreadyExistsException exc) {
LOGGER.error(exc);
return Response.status(Response.Status.CONFLICT).build();
}
return Response.status(Response.Status.OK).build();
}
/**
* Gets the object group life cycle based on its id and using the passed DSL query
*
* @param objectGroupLifeCycleId the object group life cycle id
* @param evtStatus the lifeCycle Status that we are looking for : COMMITTED or IN_PROCESS
* @param queryDsl the DSL query
* @return a Response that contains the object group life cycle
*/
@GET
@Path("/objectgrouplifecycles/{id_lc}")
@Produces(MediaType.APPLICATION_JSON)
public Response getObjectGroupLifeCycle(@PathParam("id_lc") String objectGroupLifeCycleId,
@HeaderParam(GlobalDataRest.X_EVENT_STATUS) String evtStatus, JsonNode queryDsl) {
Status status;
try {
LifeCycleStatusCode requiredLifeCycleStatus = getSelectLifeCycleStatusCode(evtStatus);
final List<LogbookLifeCycle> result = logbookLifeCycle.selectObjectGroup(queryDsl, false,
fromLifeCycleStatusToObjectGroupCollection(requiredLifeCycleStatus));
if (result.size() != 1) {
throw new LogbookDatabaseException("Result size different than 1.");
}
return Response.status(Status.OK)
.entity(new RequestResponseOK()
.setHits(1, 0, 1)
.addResult(JsonHandler.getFromString(result.get(0).toJson())))
.build();
} catch (final LogbookNotFoundException exc) {
LOGGER.debug(exc);
return Response.status(Status.NOT_FOUND)
.entity(new RequestResponseOK()
.setHits(0, 0, 1)
.addResult(JsonHandler.createArrayNode()))
.build();
} catch (final LogbookException | InvalidParseOperationException exc) {
LOGGER.error(exc);
status = Status.PRECONDITION_FAILED;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
}
/**
* Gets the objectGroup life cycle status based on its id
*
* @param objectGroupLifeCycleId the object group cycle id
* @return the object group cycle status : Committed or In process
*/
@HEAD
@Path("/objectgrouplifecycles/{id_lc}")
public Response getObjectGroupLifeCycleStatus(@PathParam("id_lc") String objectGroupLifeCycleId) {
Status status;
try {
LifeCycleStatusCode lifeCycleStatusCode =
logbookLifeCycle.getObjectGroupLifeCycleStatus(objectGroupLifeCycleId);
if (lifeCycleStatusCode != null) {
// Build the response
return Response.status(Status.OK)
.header(GlobalDataRest.X_EVENT_STATUS, lifeCycleStatusCode.toString())
.build();
} else {
throw new LogbookNotFoundException(
String.format("No lifeCycle found for the given id %s.", objectGroupLifeCycleId));
}
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
return Response.status(Status.NOT_FOUND)
.entity(new RequestResponseOK()
.setHits(0, 0, 1)
.addResult(JsonHandler.createArrayNode()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook")
.setState("code_vitam")
.setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
}
/***** LIFE CYCLES OBJECT GROUP - END *****/
/**
* Deletes all temporary Unit lifeCycles created during a given operation
*
* @param operationId the operation id
* @return a Response that contains the result of deletion operation
*/
@DELETE
@Path("/operations/{id_op}/unitlifecycles")
public Response rollBackUnitLifeCyclesByOperation(@PathParam("id_op") String operationId) {
Status status;
try {
logbookLifeCycle.rollBackUnitsByOperation(operationId);
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
status = Status.NOT_FOUND;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
return Response.status(Response.Status.OK).build();
}
/**
* Deletes all temporary ObjectGroup lifeCycles created during a given operation
*
* @param operationId the operation id
* @return a Response that contains the result of deletion operation
*/
@DELETE
@Path("/operations/{id_op}/objectgrouplifecycles")
public Response rollBackObjectGroupLifeCyclesByOperation(@PathParam("id_op") String operationId) {
Status status;
try {
logbookLifeCycle.rollBackObjectGroupsByOperation(operationId);
} catch (final LogbookNotFoundException exc) {
LOGGER.error(exc);
status = Status.NOT_FOUND;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final LogbookDatabaseException exc) {
LOGGER.error(exc);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
} catch (final IllegalArgumentException exc) {
LOGGER.error(exc);
status = Status.BAD_REQUEST;
return Response.status(status)
.entity(new VitamError(status.name()).setHttpCode(status.getStatusCode())
.setContext("logbook").setState("code_vitam").setMessage(status.getReasonPhrase())
.setDescription(exc.getMessage()))
.build();
}
return Response.status(Response.Status.OK).build();
}
private LogbookCollections fromLifeCycleStatusToUnitCollection(LifeCycleStatusCode lifeCycleStatusCode) {
switch (lifeCycleStatusCode) {
case LIFE_CYCLE_COMMITTED:
return LogbookCollections.LIFECYCLE_UNIT;
case LIFE_CYCLE_IN_PROCESS:
return LogbookCollections.LIFECYCLE_UNIT_IN_PROCESS;
default:
return LogbookCollections.LIFECYCLE_UNIT;
}
}
private LogbookCollections fromLifeCycleStatusToObjectGroupCollection(LifeCycleStatusCode lifeCycleStatusCode) {
switch (lifeCycleStatusCode) {
case LIFE_CYCLE_COMMITTED:
return LogbookCollections.LIFECYCLE_OBJECTGROUP;
case LIFE_CYCLE_IN_PROCESS:
return LogbookCollections.LIFECYCLE_OBJECTGROUP_IN_PROCESS;
default:
return LogbookCollections.LIFECYCLE_OBJECTGROUP;
}
}
private LifeCycleStatusCode getUpdateOrCommitLifeCycleStatusCode(String evtStatusHeader)
throws IllegalArgumentException {
if (evtStatusHeader == null) {
return LifeCycleStatusCode.LIFE_CYCLE_IN_PROCESS;
} else {
return LifeCycleStatusCode.valueOf(evtStatusHeader);
}
}
private LifeCycleStatusCode getSelectLifeCycleStatusCode(String evtStatusHeader) throws IllegalArgumentException {
if (evtStatusHeader == null) {
return LifeCycleStatusCode.LIFE_CYCLE_COMMITTED;
} else {
return LifeCycleStatusCode.valueOf(evtStatusHeader);
}
}
}