@Test public void bulkPutObjectsTest() throws Exception { checkOfferDatabaseEmptiness(); File file = PropertiesUtils.findFile(ARCHIVE_FILE_TXT); byte[] multiplexedStreamBody = getMultiplexedStreamBody(Arrays.asList("id1", "id"), Arrays.asList(file, file)); given().contentType(MediaType.APPLICATION_OCTET_STREAM) .header(GlobalDataRest.VITAM_CONTENT_LENGTH, multiplexedStreamBody.length) .header(GlobalDataRest.X_DIGEST_ALGORITHM, DigestType.SHA512.getName()) .contentType(MediaType.APPLICATION_OCTET_STREAM).body(multiplexedStreamBody).when() .put("/bulk/objects/{type}", UNIT_CODE).then().statusCode(400); given().contentType(MediaType.APPLICATION_OCTET_STREAM) .header(GlobalDataRest.X_TENANT_ID, "1") .header(GlobalDataRest.X_DIGEST_ALGORITHM, DigestType.SHA512.getName()) .contentType(MediaType.APPLICATION_OCTET_STREAM).body(multiplexedStreamBody).when() .put("/bulk/objects/{type}", UNIT_CODE).then().statusCode(400); given().contentType(MediaType.APPLICATION_OCTET_STREAM) .header(GlobalDataRest.X_TENANT_ID, "1") .header(GlobalDataRest.VITAM_CONTENT_LENGTH, multiplexedStreamBody.length) .contentType(MediaType.APPLICATION_OCTET_STREAM).body(multiplexedStreamBody).when() .put("/bulk/objects/{type}", UNIT_CODE).then().statusCode(400); given().contentType(MediaType.APPLICATION_OCTET_STREAM) .header(GlobalDataRest.X_TENANT_ID, "1") .header(GlobalDataRest.X_DIGEST_ALGORITHM, DigestType.SHA512.getName()) .header(GlobalDataRest.VITAM_CONTENT_LENGTH, multiplexedStreamBody.length - 50) .contentType(MediaType.APPLICATION_OCTET_STREAM).body(multiplexedStreamBody).when() .put("/bulk/objects/{type}", UNIT_CODE).then().statusCode(500); given().contentType(MediaType.APPLICATION_OCTET_STREAM) .header(GlobalDataRest.X_TENANT_ID, "1") .header(GlobalDataRest.X_DIGEST_ALGORITHM, DigestType.SHA512.getName()) .header(GlobalDataRest.VITAM_CONTENT_LENGTH, multiplexedStreamBody.length + 50) .contentType(MediaType.APPLICATION_OCTET_STREAM).body(multiplexedStreamBody).when() .put("/bulk/objects/{type}", UNIT_CODE).then().statusCode(500); given().header(GlobalDataRest.X_TENANT_ID, "2") .header(GlobalDataRest.VITAM_CONTENT_LENGTH, multiplexedStreamBody.length) .header(GlobalDataRest.X_DIGEST_ALGORITHM, DigestType.SHA512.getName()) .contentType(MediaType.APPLICATION_OCTET_STREAM).body(multiplexedStreamBody).when() .put("/bulk/objects/{type}", UNIT_CODE).then().statusCode(201); final StorageConfiguration conf = PropertiesUtils.readYaml(PropertiesUtils.findFile(DEFAULT_STORAGE_CONF), StorageConfiguration.class); final File container = new File(conf.getStoragePath() + "/2_unit"); assertTrue(container.exists()); assertTrue(container.isDirectory()); final File object = new File(container.getAbsolutePath(), "/id1"); assertTrue(object.exists()); assertFalse(object.isDirectory()); checkOfferDatabaseExistingDocument("2_unit", "id1"); assertThat(object).hasSameContentAs(file); }
@PUT @Path("/bulk/objects/{type}") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) public Response bulkPutObjects(@PathParam("type") DataCategory type, @Context HttpHeaders headers, InputStream input) { final String xTenantId = headers.getHeaderString(GlobalDataRest.X_TENANT_ID); if (Strings.isNullOrEmpty(xTenantId)) { LOGGER.error(MISSING_THE_TENANT_ID_X_TENANT_ID); return Response.status(Response.Status.BAD_REQUEST).build(); } final String containerName = buildContainerName(type, xTenantId); final String size = headers.getHeaderString(GlobalDataRest.VITAM_CONTENT_LENGTH); Long inputStreamSize; try { inputStreamSize = Long.valueOf(size); } catch (NumberFormatException e) { LOGGER.error("Bad or missing size '" + size + "'"); return Response.status(Response.Status.BAD_REQUEST).build(); } try { MultiplexedStreamReader multiplexedStreamReader = new MultiplexedStreamReader( new ExactSizeInputStream(input, inputStreamSize)); Optional<ExactSizeInputStream> headerEntry = multiplexedStreamReader.readNextEntry(); if (!headerEntry.isPresent()) { throw new IllegalStateException("Header entry not found"); } List<String> objectIds = JsonHandler.getFromInputStream(headerEntry.get(), List.class); String xDigestAlgorithm = headers.getHeaderString(GlobalDataRest.X_DIGEST_ALGORITHM); if (StringUtils.isEmpty(xDigestAlgorithm)) { LOGGER.error("Missing digest"); return Response.status(Response.Status.BAD_REQUEST).build(); } DigestType digestType = DigestType.fromValue(xDigestAlgorithm); StorageBulkPutResult storageBulkPutResult = defaultOfferService .bulkPutObjects(containerName, objectIds, multiplexedStreamReader, type, digestType); return Response.status(Status.CREATED).entity(storageBulkPutResult).build(); } catch (NonUpdatableContentAddressableStorageException e) { LOGGER.error("Object overriding forbidden", e); return Response.status(Status.CONFLICT).build(); } catch (Exception exc) { LOGGER.error("Cannot create object", exc); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } finally { StreamUtils.closeSilently(input); } }
DefaultOfferResource extends ApplicationStatusResource { @PUT @Path("/bulk/objects/{type}") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) public Response bulkPutObjects(@PathParam("type") DataCategory type, @Context HttpHeaders headers, InputStream input) { final String xTenantId = headers.getHeaderString(GlobalDataRest.X_TENANT_ID); if (Strings.isNullOrEmpty(xTenantId)) { LOGGER.error(MISSING_THE_TENANT_ID_X_TENANT_ID); return Response.status(Response.Status.BAD_REQUEST).build(); } final String containerName = buildContainerName(type, xTenantId); final String size = headers.getHeaderString(GlobalDataRest.VITAM_CONTENT_LENGTH); Long inputStreamSize; try { inputStreamSize = Long.valueOf(size); } catch (NumberFormatException e) { LOGGER.error("Bad or missing size '" + size + "'"); return Response.status(Response.Status.BAD_REQUEST).build(); } try { MultiplexedStreamReader multiplexedStreamReader = new MultiplexedStreamReader( new ExactSizeInputStream(input, inputStreamSize)); Optional<ExactSizeInputStream> headerEntry = multiplexedStreamReader.readNextEntry(); if (!headerEntry.isPresent()) { throw new IllegalStateException("Header entry not found"); } List<String> objectIds = JsonHandler.getFromInputStream(headerEntry.get(), List.class); String xDigestAlgorithm = headers.getHeaderString(GlobalDataRest.X_DIGEST_ALGORITHM); if (StringUtils.isEmpty(xDigestAlgorithm)) { LOGGER.error("Missing digest"); return Response.status(Response.Status.BAD_REQUEST).build(); } DigestType digestType = DigestType.fromValue(xDigestAlgorithm); StorageBulkPutResult storageBulkPutResult = defaultOfferService .bulkPutObjects(containerName, objectIds, multiplexedStreamReader, type, digestType); return Response.status(Status.CREATED).entity(storageBulkPutResult).build(); } catch (NonUpdatableContentAddressableStorageException e) { LOGGER.error("Object overriding forbidden", e); return Response.status(Status.CONFLICT).build(); } catch (Exception exc) { LOGGER.error("Cannot create object", exc); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } finally { StreamUtils.closeSilently(input); } } }
DefaultOfferResource extends ApplicationStatusResource { @PUT @Path("/bulk/objects/{type}") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) public Response bulkPutObjects(@PathParam("type") DataCategory type, @Context HttpHeaders headers, InputStream input) { final String xTenantId = headers.getHeaderString(GlobalDataRest.X_TENANT_ID); if (Strings.isNullOrEmpty(xTenantId)) { LOGGER.error(MISSING_THE_TENANT_ID_X_TENANT_ID); return Response.status(Response.Status.BAD_REQUEST).build(); } final String containerName = buildContainerName(type, xTenantId); final String size = headers.getHeaderString(GlobalDataRest.VITAM_CONTENT_LENGTH); Long inputStreamSize; try { inputStreamSize = Long.valueOf(size); } catch (NumberFormatException e) { LOGGER.error("Bad or missing size '" + size + "'"); return Response.status(Response.Status.BAD_REQUEST).build(); } try { MultiplexedStreamReader multiplexedStreamReader = new MultiplexedStreamReader( new ExactSizeInputStream(input, inputStreamSize)); Optional<ExactSizeInputStream> headerEntry = multiplexedStreamReader.readNextEntry(); if (!headerEntry.isPresent()) { throw new IllegalStateException("Header entry not found"); } List<String> objectIds = JsonHandler.getFromInputStream(headerEntry.get(), List.class); String xDigestAlgorithm = headers.getHeaderString(GlobalDataRest.X_DIGEST_ALGORITHM); if (StringUtils.isEmpty(xDigestAlgorithm)) { LOGGER.error("Missing digest"); return Response.status(Response.Status.BAD_REQUEST).build(); } DigestType digestType = DigestType.fromValue(xDigestAlgorithm); StorageBulkPutResult storageBulkPutResult = defaultOfferService .bulkPutObjects(containerName, objectIds, multiplexedStreamReader, type, digestType); return Response.status(Status.CREATED).entity(storageBulkPutResult).build(); } catch (NonUpdatableContentAddressableStorageException e) { LOGGER.error("Object overriding forbidden", e); return Response.status(Status.CONFLICT).build(); } catch (Exception exc) { LOGGER.error("Cannot create object", exc); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } finally { StreamUtils.closeSilently(input); } } DefaultOfferResource(DefaultOfferService defaultOfferService); }
DefaultOfferResource extends ApplicationStatusResource { @PUT @Path("/bulk/objects/{type}") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) public Response bulkPutObjects(@PathParam("type") DataCategory type, @Context HttpHeaders headers, InputStream input) { final String xTenantId = headers.getHeaderString(GlobalDataRest.X_TENANT_ID); if (Strings.isNullOrEmpty(xTenantId)) { LOGGER.error(MISSING_THE_TENANT_ID_X_TENANT_ID); return Response.status(Response.Status.BAD_REQUEST).build(); } final String containerName = buildContainerName(type, xTenantId); final String size = headers.getHeaderString(GlobalDataRest.VITAM_CONTENT_LENGTH); Long inputStreamSize; try { inputStreamSize = Long.valueOf(size); } catch (NumberFormatException e) { LOGGER.error("Bad or missing size '" + size + "'"); return Response.status(Response.Status.BAD_REQUEST).build(); } try { MultiplexedStreamReader multiplexedStreamReader = new MultiplexedStreamReader( new ExactSizeInputStream(input, inputStreamSize)); Optional<ExactSizeInputStream> headerEntry = multiplexedStreamReader.readNextEntry(); if (!headerEntry.isPresent()) { throw new IllegalStateException("Header entry not found"); } List<String> objectIds = JsonHandler.getFromInputStream(headerEntry.get(), List.class); String xDigestAlgorithm = headers.getHeaderString(GlobalDataRest.X_DIGEST_ALGORITHM); if (StringUtils.isEmpty(xDigestAlgorithm)) { LOGGER.error("Missing digest"); return Response.status(Response.Status.BAD_REQUEST).build(); } DigestType digestType = DigestType.fromValue(xDigestAlgorithm); StorageBulkPutResult storageBulkPutResult = defaultOfferService .bulkPutObjects(containerName, objectIds, multiplexedStreamReader, type, digestType); return Response.status(Status.CREATED).entity(storageBulkPutResult).build(); } catch (NonUpdatableContentAddressableStorageException e) { LOGGER.error("Object overriding forbidden", e); return Response.status(Status.CONFLICT).build(); } catch (Exception exc) { LOGGER.error("Cannot create object", exc); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } finally { StreamUtils.closeSilently(input); } } DefaultOfferResource(DefaultOfferService defaultOfferService); @HEAD @Path("/objects/{type}") @Produces(MediaType.APPLICATION_JSON) Response getCapacity(@HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @PathParam("type") DataCategory type); @GET @Path("/objects/{type}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response getContainerList(
        @HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @PathParam("type") DataCategory type); @GET @Path("/objects/{type}/logs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response getOfferLogs(@HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @PathParam("type") DataCategory type, OfferLogRequest offerLogRequest); @GET @Path("/objects/{type}/{id_object}") @Consumes(MediaType.APPLICATION_JSON) @Produces({MediaType.APPLICATION_OCTET_STREAM, CommonMediaType.ZIP}) Response getObject(@PathParam("type") DataCategory type, @NotNull @PathParam("id_object") String objectId,
        @Context HttpHeaders headers); @POST @Path("/readorder/{type}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response createReadOrderRequest(@PathParam("type") DataCategory type, List<String> objectsIds,
        @Context HttpHeaders headers); @GET @Path("/readorder/{readOrderRequestId}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response getReadOrderRequest(@PathParam("readOrderRequestId") String readOrderRequestId,
        @Context HttpHeaders headers); @DELETE @Path("/readorder/{readOrderRequestId}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response removeReadOrderRequest(@PathParam("readOrderRequestId") String readOrderRequestId,
        @Context HttpHeaders headers); @PUT @Path("/objects/{type}/{objectId:.+}") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) Response putObject(@PathParam("objectId") String objectId, @PathParam("type") DataCategory type,
        @Context HttpHeaders headers, InputStream input); @PUT @Path("/bulk/objects/{type}") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) Response bulkPutObjects(@PathParam("type") DataCategory type,
        @Context HttpHeaders headers, InputStream input); @DELETE @Path("/objects/{type}/{id:.+}") @Produces(MediaType.APPLICATION_JSON) Response deleteObject(@HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @HeaderParam(GlobalDataRest.X_DIGEST_ALGORITHM) String xDigestAlgorithm, @PathParam("type") DataCategory
        type,
        @PathParam("id") String idObject); @HEAD @Path("/objects/{type}/{id:.+}") Response checkObjectExistence(@PathParam("type") DataCategory type, @PathParam("id") String idObject,
        @HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId); @GET @Path("/objects/{type}/{id:.+}/metadatas") @Produces(MediaType.APPLICATION_JSON) Response getObjectMetadata(@PathParam("type") DataCategory type, @PathParam("id") String idObject,
        @HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @HeaderParam(GlobalDataRest.X_OFFER_NO_CACHE) Boolean noCache); }
DefaultOfferResource extends ApplicationStatusResource { @PUT @Path("/bulk/objects/{type}") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) public Response bulkPutObjects(@PathParam("type") DataCategory type, @Context HttpHeaders headers, InputStream input) { final String xTenantId = headers.getHeaderString(GlobalDataRest.X_TENANT_ID); if (Strings.isNullOrEmpty(xTenantId)) { LOGGER.error(MISSING_THE_TENANT_ID_X_TENANT_ID); return Response.status(Response.Status.BAD_REQUEST).build(); } final String containerName = buildContainerName(type, xTenantId); final String size = headers.getHeaderString(GlobalDataRest.VITAM_CONTENT_LENGTH); Long inputStreamSize; try { inputStreamSize = Long.valueOf(size); } catch (NumberFormatException e) { LOGGER.error("Bad or missing size '" + size + "'"); return Response.status(Response.Status.BAD_REQUEST).build(); } try { MultiplexedStreamReader multiplexedStreamReader = new MultiplexedStreamReader( new ExactSizeInputStream(input, inputStreamSize)); Optional<ExactSizeInputStream> headerEntry = multiplexedStreamReader.readNextEntry(); if (!headerEntry.isPresent()) { throw new IllegalStateException("Header entry not found"); } List<String> objectIds = JsonHandler.getFromInputStream(headerEntry.get(), List.class); String xDigestAlgorithm = headers.getHeaderString(GlobalDataRest.X_DIGEST_ALGORITHM); if (StringUtils.isEmpty(xDigestAlgorithm)) { LOGGER.error("Missing digest"); return Response.status(Response.Status.BAD_REQUEST).build(); } DigestType digestType = DigestType.fromValue(xDigestAlgorithm); StorageBulkPutResult storageBulkPutResult = defaultOfferService .bulkPutObjects(containerName, objectIds, multiplexedStreamReader, type, digestType); return Response.status(Status.CREATED).entity(storageBulkPutResult).build(); } catch (NonUpdatableContentAddressableStorageException e) { LOGGER.error("Object overriding forbidden", e); return Response.status(Status.CONFLICT).build(); } catch (Exception exc) { LOGGER.error("Cannot create object", exc); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } finally { StreamUtils.closeSilently(input); } } DefaultOfferResource(DefaultOfferService defaultOfferService); @HEAD @Path("/objects/{type}") @Produces(MediaType.APPLICATION_JSON) Response getCapacity(@HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @PathParam("type") DataCategory type); @GET @Path("/objects/{type}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response getContainerList(
        @HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @PathParam("type") DataCategory type); @GET @Path("/objects/{type}/logs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response getOfferLogs(@HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @PathParam("type") DataCategory type, OfferLogRequest offerLogRequest); @GET @Path("/objects/{type}/{id_object}") @Consumes(MediaType.APPLICATION_JSON) @Produces({MediaType.APPLICATION_OCTET_STREAM, CommonMediaType.ZIP}) Response getObject(@PathParam("type") DataCategory type, @NotNull @PathParam("id_object") String objectId,
        @Context HttpHeaders headers); @POST @Path("/readorder/{type}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response createReadOrderRequest(@PathParam("type") DataCategory type, List<String> objectsIds,
        @Context HttpHeaders headers); @GET @Path("/readorder/{readOrderRequestId}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response getReadOrderRequest(@PathParam("readOrderRequestId") String readOrderRequestId,
        @Context HttpHeaders headers); @DELETE @Path("/readorder/{readOrderRequestId}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response removeReadOrderRequest(@PathParam("readOrderRequestId") String readOrderRequestId,
        @Context HttpHeaders headers); @PUT @Path("/objects/{type}/{objectId:.+}") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) Response putObject(@PathParam("objectId") String objectId, @PathParam("type") DataCategory type,
        @Context HttpHeaders headers, InputStream input); @PUT @Path("/bulk/objects/{type}") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) Response bulkPutObjects(@PathParam("type") DataCategory type,
        @Context HttpHeaders headers, InputStream input); @DELETE @Path("/objects/{type}/{id:.+}") @Produces(MediaType.APPLICATION_JSON) Response deleteObject(@HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @HeaderParam(GlobalDataRest.X_DIGEST_ALGORITHM) String xDigestAlgorithm, @PathParam("type") DataCategory
        type,
        @PathParam("id") String idObject); @HEAD @Path("/objects/{type}/{id:.+}") Response checkObjectExistence(@PathParam("type") DataCategory type, @PathParam("id") String idObject,
        @HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId); @GET @Path("/objects/{type}/{id:.+}/metadatas") @Produces(MediaType.APPLICATION_JSON) Response getObjectMetadata(@PathParam("type") DataCategory type, @PathParam("id") String idObject,
        @HeaderParam(GlobalDataRest.X_TENANT_ID) String xTenantId,
        @HeaderParam(GlobalDataRest.X_OFFER_NO_CACHE) Boolean noCache); static final String RE_AUTHENTICATION_CALL_STREAM_ALREADY_CONSUMED_BUT_NO_FILE_CREATED; }