PartBinaryResource { @POST @ApiOperation(value = "Upload attached file", response = Response.class) @ApiImplicitParams({ @ApiImplicitParam(name = "upload", paramType = "formData", dataType = "file", required = true) }) @ApiResponses(value = { @ApiResponse(code = 204, message = "Upload success"), @ApiResponse(code = 401, message = "Unauthorized"), @ApiResponse(code = 403, message = "Forbidden"), @ApiResponse(code = 500, message = "Internal server error") }) @Path("/{iteration}/" + PartIteration.ATTACHED_FILES_SUBTYPE) @Consumes(MediaType.MULTIPART_FORM_DATA) @RolesAllowed({UserGroupMapping.REGULAR_USER_ROLE_ID}) public Response uploadAttachedFiles( @Context HttpServletRequest request, @ApiParam(required = true, value = "Workspace id") @PathParam("workspaceId") final String workspaceId, @ApiParam(required = true, value = "Part number") @PathParam("partNumber") final String partNumber, @ApiParam(required = true, value = "Part version") @PathParam("version") final String version, @ApiParam(required = true, value = "Part iteration") @PathParam("iteration") final int iteration) throws EntityNotFoundException, EntityAlreadyExistsException, UserNotActiveException, AccessRightException, NotAllowedException, CreationException, WorkspaceNotEnabledException { try { PartIterationKey partPK = new PartIterationKey(workspaceId, partNumber, version, iteration); Collection<Part> formParts = request.getParts(); String fileName = null; for (Part formPart : formParts) { fileName = Normalizer.normalize(formPart.getSubmittedFileName(), Normalizer.Form.NFC); BinaryResource binaryResource = productService.saveFileInPartIteration(partPK, fileName, PartIteration.ATTACHED_FILES_SUBTYPE, 0); OutputStream outputStream = storageManager.getBinaryResourceOutputStream(binaryResource); long length = BinaryResourceUpload.uploadBinary(outputStream, formPart); productService.saveFileInPartIteration(partPK, fileName, PartIteration.ATTACHED_FILES_SUBTYPE, length); } if (formParts.size() == 1) { return BinaryResourceUpload.tryToRespondCreated(request.getRequestURI() + URLEncoder.encode(fileName, UTF8_ENCODING)); } return Response.noContent().build(); } catch (IOException | ServletException | StorageException e) { return BinaryResourceUpload.uploadError(e); } } PartBinaryResource(); @POST @ApiOperation(value = "Upload CAD file", response = Response.class) @ApiImplicitParams({ @ApiImplicitParam(name = "upload", paramType = "formData", dataType = "file", required = true) }) @ApiResponses(value = { @ApiResponse(code = 200, message = "Upload success"), @ApiResponse(code = 401, message = "Unauthorized"), @ApiResponse(code = 403, message = "Forbidden"), @ApiResponse(code = 500, message = "Internal server error") }) @Path("/{iteration}/" + PartIteration.NATIVE_CAD_SUBTYPE) @Consumes(MediaType.MULTIPART_FORM_DATA) @RolesAllowed({UserGroupMapping.REGULAR_USER_ROLE_ID}) Response uploadNativeCADFile(
            @Context HttpServletRequest request,
            @ApiParam(required = true, value = "Workspace id") @PathParam("workspaceId") final String workspaceId,
            @ApiParam(required = true, value = "Part number") @PathParam("partNumber") final String partNumber,
            @ApiParam(required = true, value = "Part version") @PathParam("version") final String version,
            @ApiParam(required = true, value = "Part iteration") @PathParam("iteration") final int iteration); @POST @ApiOperation(value = "Upload attached file", response = Response.class) @ApiImplicitParams({ @ApiImplicitParam(name = "upload", paramType = "formData", dataType = "file", required = true) }) @ApiResponses(value = { @ApiResponse(code = 204, message = "Upload success"), @ApiResponse(code = 401, message = "Unauthorized"), @ApiResponse(code = 403, message = "Forbidden"), @ApiResponse(code = 500, message = "Internal server error") }) @Path("/{iteration}/" + PartIteration.ATTACHED_FILES_SUBTYPE) @Consumes(MediaType.MULTIPART_FORM_DATA) @RolesAllowed({UserGroupMapping.REGULAR_USER_ROLE_ID}) Response uploadAttachedFiles(
            @Context HttpServletRequest request,
            @ApiParam(required = true, value = "Workspace id") @PathParam("workspaceId") final String workspaceId,
            @ApiParam(required = true, value = "Part number") @PathParam("partNumber") final String partNumber,
            @ApiParam(required = true, value = "Part version") @PathParam("version") final String version,
            @ApiParam(required = true, value = "Part iteration") @PathParam("iteration") final int iteration); @GET @ApiOperation(value = "Download part file without a sub type", response = File.class) @ApiResponses(value = { @ApiResponse(code = 200, message = "Download success"), @ApiResponse(code = 401, message = "Unauthorized"), @ApiResponse(code = 403, message = "Forbidden"), @ApiResponse(code = 500, message = "Internal server error") }) @Path("/{iteration}/{fileName}") @Produces(MediaType.APPLICATION_OCTET_STREAM) Response downloadDirectPartFile(
            @Context Request request,
            @ApiParam(required = true, value = "Workspace id") @PathParam("workspaceId") final String workspaceId,
            @ApiParam(required = true, value = "Part number") @PathParam("partNumber") final String partNumber,
            @ApiParam(required = true, value = "Part version") @PathParam("version") final String version,
            @ApiParam(required = true, value = "Part iteration") @PathParam("iteration") final int iteration,
            @ApiParam(required = true, value = "File name") @PathParam("fileName") final String fileName,
            @ApiParam(required = false, value = "Type") @QueryParam("type") String type,
            @ApiParam(required = false, value = "Output") @QueryParam("output") String output,
            @ApiParam(required = false, value = "Range") @HeaderParam("Range") String range,
            @ApiParam(required = false, value = "Shared entity uuid") @QueryParam("uuid") final String uuid,
            @ApiParam(required = false, value = "Password for private resource") @HeaderParam("password") String password,
            @ApiParam(required = false, value = "Shared entity token") @QueryParam("token") String accessToken); @GET @ApiOperation(value = "Download part file with a sub type", response = File.class) @ApiResponses(value = { @ApiResponse(code = 200, message = "Download success"), @ApiResponse(code = 401, message = "Unauthorized"), @ApiResponse(code = 403, message = "Forbidden"), @ApiResponse(code = 500, message = "Internal server error") }) @Path("/{iteration}/{subType}/{fileName}") @Produces(MediaType.APPLICATION_OCTET_STREAM) Response downloadPartFile(
            @Context Request request,
            @ApiParam(required = true, value = "Workspace id") @PathParam("workspaceId") final String workspaceId,
            @ApiParam(required = true, value = "Part number") @PathParam("partNumber") final String partNumber,
            @ApiParam(required = true, value = "Part version") @PathParam("version") final String version,
            @ApiParam(required = true, value = "Part iteration") @PathParam("iteration") final int iteration,
            @ApiParam(required = true, value = "File sub type") @PathParam("subType") String subType,
            @ApiParam(required = true, value = "File name") @PathParam("fileName") final String fileName,
            @ApiParam(required = false, value = "Type") @QueryParam("type") String type,
            @ApiParam(required = false, value = "Output") @QueryParam("output") String output,
            @ApiParam(required = false, value = "Range") @HeaderParam("Range") String range,
            @ApiParam(required = false, value = "Shared entity uuid") @QueryParam("uuid") final String uuid,
            @ApiParam(required = false, value = "Password for private resource") @HeaderParam("password") String password,
            @ApiParam(required = false, value = "Shared entity token") @QueryParam("token") String accessToken);  }
@Test public void uploadFileToPart() throws Exception { final File fileToUpload = new File(ResourceUtil.getFilePath(ResourceUtil.SOURCE_PART_STORAGE + ResourceUtil.TEST_PART_FILENAME1)); File uploadedFile = File.createTempFile(ResourceUtil.TARGET_PART_STORAGE + ResourceUtil.FILENAME_TARGET_PART, ResourceUtil.TEMP_SUFFIX); HttpServletRequestWrapper request = Mockito.mock(HttpServletRequestWrapper.class); Collection<Part> parts = new ArrayList<>(); parts.add(new PartImpl(fileToUpload)); Mockito.when(request.getParts()).thenReturn(parts); BinaryResource binaryResource = new BinaryResource(ResourceUtil.FILENAME1, ResourceUtil.PART_SIZE, new Date()); OutputStream outputStream = new FileOutputStream(uploadedFile); Mockito.when(request.getRequestURI()).thenReturn(ResourceUtil.WORKSPACE_ID + "/parts/" + ResourceUtil.PART_TEMPLATE_ID + "/"); Mockito.when(productService.saveFileInPartIteration(Matchers.any(PartIterationKey.class), Matchers.anyString(), Matchers.anyString(), Matchers.anyInt())).thenReturn(binaryResource); Mockito.when(storageManager.getBinaryResourceOutputStream(binaryResource)).thenReturn(outputStream); Response response = partBinaryResource.uploadAttachedFiles(request, ResourceUtil.WORKSPACE_ID, ResourceUtil.PART_NUMBER, ResourceUtil.VERSION, ResourceUtil.ITERATION); assertNotNull(response); assertEquals(response.getStatus(), 201); assertEquals(response.getStatusInfo(), Response.Status.CREATED); uploadedFile.deleteOnExit(); }
@Test public void uploadFileWithSpecialCharactersToPart() throws Exception { File fileToUpload = new File(ResourceUtil.getFilePath(ResourceUtil.SOURCE_PART_STORAGE) + ResourceUtil.FILENAME_TO_UPLOAD_PART_SPECIAL_CHARACTER); File uploadedFile = File.createTempFile(ResourceUtil.TARGET_PART_STORAGE + ResourceUtil.FILENAME_TO_UPLOAD_PART_SPECIAL_CHARACTER, ResourceUtil.TEMP_SUFFIX); HttpServletRequestWrapper request = Mockito.mock(HttpServletRequestWrapper.class); Collection<Part> parts = new ArrayList<>(); parts.add(new PartImpl(fileToUpload)); Mockito.when(request.getParts()).thenReturn(parts); BinaryResource binaryResource = new BinaryResource(ResourceUtil.FILENAME_TO_UPLOAD_PART_SPECIAL_CHARACTER, ResourceUtil.PART_SIZE, new Date()); OutputStream outputStream = new FileOutputStream(uploadedFile); Mockito.when(request.getRequestURI()).thenReturn(ResourceUtil.WORKSPACE_ID + "/parts/" + ResourceUtil.PART_TEMPLATE_ID + "/"); Mockito.when(productService.saveFileInPartIteration(Matchers.any(PartIterationKey.class), Matchers.anyString(), Matchers.anyString(), Matchers.anyInt())).thenReturn(binaryResource); Mockito.when(storageManager.getBinaryResourceOutputStream(binaryResource)).thenReturn(outputStream); Response response = partBinaryResource.uploadAttachedFiles(request, ResourceUtil.WORKSPACE_ID, ResourceUtil.PART_NUMBER, ResourceUtil.VERSION, ResourceUtil.ITERATION); assertNotNull(response); assertEquals(response.getStatus(), 201); assertEquals(response.getStatusInfo(), Response.Status.CREATED); assertEquals(response.getLocation().toString(), (ResourceUtil.WORKSPACE_ID + "/parts/" + ResourceUtil.PART_TEMPLATE_ID + "/" + URLEncoder.encode(ResourceUtil.getFilePath(ResourceUtil.SOURCE_PART_STORAGE) + ResourceUtil.FILENAME_TO_UPLOAD_PART_SPECIAL_CHARACTER, "UTF-8"))); uploadedFile.deleteOnExit(); }
@Test public void uploadSeveralFilesToPart() throws Exception { File fileToUpload1 = new File(ResourceUtil.getFilePath(ResourceUtil.SOURCE_PART_STORAGE + ResourceUtil.TEST_PART_FILENAME1)); File fileToUpload2 = new File(ResourceUtil.getFilePath(ResourceUtil.SOURCE_PART_STORAGE + ResourceUtil.TEST_PART_FILENAME2)); File uploadedFile1 = File.createTempFile(ResourceUtil.TARGET_PART_STORAGE + ResourceUtil.TEST_PART_FILENAME1, ResourceUtil.TEMP_SUFFIX); File uploadedFile2 = File.createTempFile(ResourceUtil.TARGET_PART_STORAGE + ResourceUtil.TEST_PART_FILENAME2, ResourceUtil.TEMP_SUFFIX); HttpServletRequestWrapper request = Mockito.mock(HttpServletRequestWrapper.class); Collection<Part> parts = new ArrayList<>(); parts.add(new PartImpl(fileToUpload1)); parts.add(new PartImpl(fileToUpload2)); Mockito.when(request.getParts()).thenReturn(parts); BinaryResource binaryResource1 = new BinaryResource(ResourceUtil.TEST_PART_FILENAME1, ResourceUtil.PART_SIZE, new Date()); BinaryResource binaryResource2 = new BinaryResource(ResourceUtil.TEST_PART_FILENAME2, ResourceUtil.PART_SIZE, new Date()); OutputStream outputStream1 = new FileOutputStream(uploadedFile1); OutputStream outputStream2 = new FileOutputStream(uploadedFile2); Mockito.when(productService.saveFileInPartIteration(Matchers.any(PartIterationKey.class), Matchers.anyString(), Matchers.anyString(), Matchers.anyInt())).thenReturn(binaryResource1, binaryResource1, binaryResource2, binaryResource2); Mockito.when(storageManager.getBinaryResourceOutputStream(Mockito.any(BinaryResource.class))).thenReturn(outputStream1, outputStream2); Response response = partBinaryResource.uploadAttachedFiles(request, ResourceUtil.WORKSPACE_ID, ResourceUtil.PART_NUMBER, ResourceUtil.VERSION, ResourceUtil.ITERATION); assertNotNull(response); assertEquals(204, response.getStatus()); assertEquals(Response.Status.NO_CONTENT, response.getStatusInfo()); uploadedFile1.deleteOnExit(); uploadedFile2.deleteOnExit(); }