diff --git a/common/src/main/java/com/gentics/mesh/core/image/spi/ImageInfo.java b/common/src/main/java/com/gentics/mesh/core/image/spi/ImageInfo.java index d74fd85129..b9900c4ea5 100644 --- a/common/src/main/java/com/gentics/mesh/core/image/spi/ImageInfo.java +++ b/common/src/main/java/com/gentics/mesh/core/image/spi/ImageInfo.java @@ -1,5 +1,8 @@ package com.gentics.mesh.core.image.spi; +/** + * Container object which holds image information. + */ public class ImageInfo { private Integer width; diff --git a/common/src/main/java/com/gentics/mesh/core/image/spi/ImageManipulator.java b/common/src/main/java/com/gentics/mesh/core/image/spi/ImageManipulator.java index 3993bd8b6b..437a23ec69 100644 --- a/common/src/main/java/com/gentics/mesh/core/image/spi/ImageManipulator.java +++ b/common/src/main/java/com/gentics/mesh/core/image/spi/ImageManipulator.java @@ -20,6 +20,7 @@ public interface ImageManipulator { * Resize the given binary file and return a buffer to the resized image data. * * @param binaryFile + * Binary file in the filesystem to be used for resizing * @param sha512sum * @param imageRequestParameter * @return @@ -27,12 +28,12 @@ public interface ImageManipulator { Single handleResize(File binaryFile, String sha512sum, ImageManipulationParameters imageRequestParameter); /** - * Read the inputstream and resize the image data. + * Read the {@link InputStream} and resize the image data. * * @param ins * @param sha512sum * @param parameters - * @return + * @return Buffer which contains the resized image data */ Single handleResize(InputStream ins, String sha512sum, ImageManipulationParameters parameters); diff --git a/core/src/main/java/com/gentics/mesh/core/verticle/node/BinaryFieldHandler.java b/core/src/main/java/com/gentics/mesh/core/verticle/node/BinaryFieldHandler.java index 830c1fbc60..2e1d00c92c 100644 --- a/core/src/main/java/com/gentics/mesh/core/verticle/node/BinaryFieldHandler.java +++ b/core/src/main/java/com/gentics/mesh/core/verticle/node/BinaryFieldHandler.java @@ -91,30 +91,35 @@ public void handleReadBinaryField(RoutingContext rc, String uuid, String fieldNa InternalActionContext ac = new InternalRoutingActionContextImpl(rc); db.operateNoTx(() -> { Project project = ac.getProject(); - Node node = project.getNodeRoot().loadObjectByUuid(ac, uuid, READ_PERM); + Node node = project.getNodeRoot() + .loadObjectByUuid(ac, uuid, READ_PERM); // Language language = boot.get().languageRoot().findByLanguageTag(languageTag); // if (language == null) { // throw error(NOT_FOUND, "error_language_not_found", languageTag); // } Release release = ac.getRelease(node.getProject()); - NodeGraphFieldContainer fieldContainer = node.findNextMatchingFieldContainer(ac.getNodeParameters().getLanguageList(), release.getUuid(), - ac.getVersioningParameters().getVersion()); + NodeGraphFieldContainer fieldContainer = node.findNextMatchingFieldContainer(ac.getNodeParameters() + .getLanguageList(), release.getUuid(), + ac.getVersioningParameters() + .getVersion()); if (fieldContainer == null) { - throw error(NOT_FOUND, "object_not_found_for_version", ac.getVersioningParameters().getVersion()); + throw error(NOT_FOUND, "object_not_found_for_version", ac.getVersioningParameters() + .getVersion()); } BinaryGraphField binaryField = fieldContainer.getBinary(fieldName); if (binaryField == null) { throw error(NOT_FOUND, "error_binaryfield_not_found_with_name", fieldName); } return Single.just(binaryField); - }).subscribe(binaryField -> { - db.noTx(() -> { - BinaryFieldResponseHandler handler = new BinaryFieldResponseHandler(rc, imageManipulator); - handler.handle(binaryField); - return null; - }); - }, ac::fail); + }) + .subscribe(binaryField -> { + db.noTx(() -> { + BinaryFieldResponseHandler handler = new BinaryFieldResponseHandler(rc, imageManipulator); + handler.handle(binaryField); + return null; + }); + }, ac::fail); } /** @@ -142,7 +147,9 @@ public void handleUpdateBinaryField(InternalActionContext ac, String uuid, Strin throw error(BAD_REQUEST, "upload_error_no_version"); } - MeshUploadOptions uploadOptions = Mesh.mesh().getOptions().getUploadOptions(); + MeshUploadOptions uploadOptions = Mesh.mesh() + .getOptions() + .getUploadOptions(); Set fileUploads = ac.getFileUploads(); if (fileUploads.isEmpty()) { throw error(BAD_REQUEST, "node_error_no_binarydata_found"); @@ -152,7 +159,8 @@ public void handleUpdateBinaryField(InternalActionContext ac, String uuid, Strin if (fileUploads.size() > 1) { throw error(BAD_REQUEST, "node_error_more_than_one_binarydata_included"); } - FileUpload ul = fileUploads.iterator().next(); + FileUpload ul = fileUploads.iterator() + .next(); long byteLimit = uploadOptions.getByteLimit(); if (ul.size() > byteLimit) { @@ -170,9 +178,12 @@ public void handleUpdateBinaryField(InternalActionContext ac, String uuid, Strin db.operateNoTx(() -> { Project project = ac.getProject(); Release release = ac.getRelease(); - Node node = project.getNodeRoot().loadObjectByUuid(ac, uuid, UPDATE_PERM); + Node node = project.getNodeRoot() + .loadObjectByUuid(ac, uuid, UPDATE_PERM); - Language language = boot.get().languageRoot().findByLanguageTag(languageTag); + Language language = boot.get() + .languageRoot() + .findByLanguageTag(languageTag); if (language == null) { throw error(NOT_FOUND, "error_language_not_found", languageTag); } @@ -201,16 +212,21 @@ public void handleUpdateBinaryField(InternalActionContext ac, String uuid, Strin List requestVersionDiff = Arrays.asList(new FieldContainerChange(fieldName, FieldChangeTypes.UPDATED)); // Compare both sets of change sets - List intersect = baseVersionDiff.stream().filter(requestVersionDiff::contains).collect(Collectors.toList()); + List intersect = baseVersionDiff.stream() + .filter(requestVersionDiff::contains) + .collect(Collectors.toList()); // Check whether the update was not based on the latest draft version. In that case a conflict check needs to occur. - if (!latestDraftVersion.getVersion().equals(nodeVersion)) { + if (!latestDraftVersion.getVersion() + .equals(nodeVersion)) { // Check whether a conflict has been detected if (intersect.size() > 0) { NodeVersionConflictException conflictException = new NodeVersionConflictException("node_error_conflict_detected"); - conflictException.setOldVersion(baseVersionContainer.getVersion().toString()); - conflictException.setNewVersion(latestDraftVersion.getVersion().toString()); + conflictException.setOldVersion(baseVersionContainer.getVersion() + .toString()); + conflictException.setNewVersion(latestDraftVersion.getVersion() + .toString()); for (FieldContainerChange fcc : intersect) { conflictException.addConflict(fcc.getFieldCoordinates()); } @@ -218,7 +234,9 @@ public void handleUpdateBinaryField(InternalActionContext ac, String uuid, Strin } } - FieldSchema fieldSchema = latestDraftVersion.getSchemaContainerVersion().getSchema().getField(fieldName); + FieldSchema fieldSchema = latestDraftVersion.getSchemaContainerVersion() + .getSchema() + .getField(fieldName); if (fieldSchema == null) { throw error(BAD_REQUEST, "error_schema_definition_not_found", fieldName); } @@ -262,23 +280,33 @@ public void handleUpdateBinaryField(InternalActionContext ac, String uuid, Strin return new TransformationResult(sha512sum, 0, imageInfo); }); - TransformationResult info = resultObs.toBlocking().value(); + TransformationResult info = resultObs.toBlocking() + .value(); field.setFileName(fileName); field.setFileSize(ul.size()); field.setMimeType(contentType); field.setSHA512Sum(info.getHash()); - field.setImageDominantColor(info.getImageInfo().getDominantColor()); - field.setImageHeight(info.getImageInfo().getHeight()); - field.setImageWidth(info.getImageInfo().getWidth()); + field.setImageDominantColor(info.getImageInfo() + .getDominantColor()); + field.setImageHeight(info.getImageInfo() + .getHeight()); + field.setImageWidth(info.getImageInfo() + .getWidth()); // If the binary field is the segment field, we need to update the webroot info in the node - if (field.getFieldKey().equals(newDraftVersion.getSchemaContainerVersion().getSchema().getSegmentField())) { + if (field.getFieldKey() + .equals(newDraftVersion.getSchemaContainerVersion() + .getSchema() + .getSegmentField())) { newDraftVersion.updateWebrootPathInfo(release.getUuid(), "node_conflicting_segmentfield_upload"); } return batch.store(node, release.getUuid(), DRAFT, false); - }).processAsync().andThen(node.transformToRest(ac, 0)); - }).subscribe(model -> ac.send(model, CREATED), ac::fail); + }) + .processAsync() + .andThen(node.transformToRest(ac, 0)); + }) + .subscribe(model -> ac.send(model, CREATED), ac::fail); } /** @@ -297,21 +325,26 @@ public void handleTransformImage(RoutingContext rc, String uuid, String fieldNam } db.operateNoTx(() -> { - // 1. Load needed elements + // Load needed elements Project project = ac.getProject(); - Node node = project.getNodeRoot().loadObjectByUuid(ac, uuid, UPDATE_PERM); + Node node = project.getNodeRoot() + .loadObjectByUuid(ac, uuid, UPDATE_PERM); - Language language = boot.get().languageRoot().findByLanguageTag(transformation.getLanguage()); + Language language = boot.get() + .languageRoot() + .findByLanguageTag(transformation.getLanguage()); if (language == null) { throw error(NOT_FOUND, "error_language_not_found", transformation.getLanguage()); } - NodeGraphFieldContainer container = node.getLatestDraftFieldContainer(language); - if (container == null) { + NodeGraphFieldContainer latestDraftVersion = node.getLatestDraftFieldContainer(language); + if (latestDraftVersion == null) { throw error(NOT_FOUND, "error_language_not_found", language.getLanguageTag()); } - FieldSchema fieldSchema = container.getSchemaContainerVersion().getSchema().getField(fieldName); + FieldSchema fieldSchema = latestDraftVersion.getSchemaContainerVersion() + .getSchema() + .getField(fieldName); if (fieldSchema == null) { throw error(BAD_REQUEST, "error_schema_definition_not_found", fieldName); } @@ -319,73 +352,89 @@ public void handleTransformImage(RoutingContext rc, String uuid, String fieldNam throw error(BAD_REQUEST, "error_found_field_is_not_binary", fieldName); } - BinaryGraphField field = container.getBinary(fieldName); - if (field == null) { + BinaryGraphField initialField = latestDraftVersion.getBinary(fieldName); + if (initialField == null) { throw error(NOT_FOUND, "error_binaryfield_not_found_with_name", fieldName); } - if (!field.hasImage()) { + if (!initialField.hasImage()) { throw error(BAD_REQUEST, "error_transformation_non_image", fieldName); } try { // Prepare the imageManipulationParameter using the transformation request as source ImageManipulationParameters imageManipulationParameter = new ImageManipulationParametersImpl().setWidth(transformation.getWidth()) - .setHeight(transformation.getHeight()).setStartx(transformation.getCropx()).setStarty(transformation.getCropy()) - .setCropw(transformation.getCropw()).setCroph(transformation.getCroph()); + .setHeight(transformation.getHeight()) + .setStartx(transformation.getCropx()) + .setStarty(transformation.getCropy()) + .setCropw(transformation.getCropw()) + .setCroph(transformation.getCroph()); if (!imageManipulationParameter.isSet()) { throw error(BAD_REQUEST, "error_no_image_transformation", fieldName); } - String fieldUuid = field.getUuid(); - String fieldSegmentedPath = field.getSegmentedPath(); - - // Resize the image and store the result in the filesystem - Single obsTransformation = imageManipulator - .handleResize(field.getFile(), field.getSHA512Sum(), imageManipulationParameter).flatMap(buffer -> { - return hashAndStoreBinaryFile(buffer, fieldUuid, fieldSegmentedPath).flatMap(hash -> { - // The image was stored and hashed. Now we need to load the stored file again and check the image properties - return db.noTx(() -> { - String fieldPath = field.getFilePath(); + + // Update the binary field with the new information + SearchQueueBatch batch = searchQueue.create(); + Node updatedNodeUuid = db.tx(() -> { + Release release = ac.getRelease(); + + // Create a new node version field container to store the upload + NodeGraphFieldContainer newDraftVersion = node.createGraphFieldContainer(language, release, ac.getUser(), latestDraftVersion); + BinaryGraphField field = newDraftVersion.createBinary(fieldName); + String fieldUuid = field.getUuid(); + String fieldSegmentedPath = field.getSegmentedPath(); + String fieldPath = field.getFilePath(); + + // 1. Resize the original image and store the result in the filesystem + Single obsTransformation = imageManipulator + .handleResize(initialField.getFile(), field.getSHA512Sum(), imageManipulationParameter) + .flatMap(buffer -> { + // 2. Hash the resized image data and store it using the computed fieldUuid + hash + return hashAndStoreBinaryFile(buffer, fieldUuid, fieldSegmentedPath).flatMap(hash -> { + // 3. The image was stored and hashed. Now we need to load the stored file again and check the image properties return imageManipulator.readImageInfo(() -> { try { return new FileInputStream(fieldPath); } catch (IOException e) { throw new RuntimeException(e); } - }).map(info -> { - // Return a POJO which hold all information that is needed to update the field - return new TransformationResult(hash, buffer.length(), info); - }); + }) + .map(info -> { + // Return a POJO which hold all information that is needed to update the field + return new TransformationResult(hash, buffer.length(), info); + }); }); }); - }); - return obsTransformation.flatMap(info -> { - - // Update the binary field with the new information - SearchQueueBatch batch = searchQueue.create(); - Node updatedNodeUuid = db.tx(() -> { - - field.setSHA512Sum(info.getHash()); - field.setFileSize(info.getSize()); - // The resized image will always be a jpeg - field.setMimeType("image/jpeg"); - // TODO should we rename the image, if the extension is wrong? - field.setImageHeight(info.getImageInfo().getHeight()); - field.setImageWidth(info.getImageInfo().getWidth()); - batch.store(container, node.getProject().getReleaseRoot().getLatestRelease().getUuid(), DRAFT, false); - return node; - }); - // Finally update the search index and return the updated node - return batch.processAsync().andThen(updatedNodeUuid.transformToRest(ac, 0)); + TransformationResult result = obsTransformation.toBlocking() + .value(); + + field.setSHA512Sum(result.getHash()); + field.setFileSize(result.getSize()); + // The resized image will always be a JPEG + field.setMimeType("image/jpeg"); + // TODO should we rename the image, if the extension is wrong? + field.setImageHeight(result.getImageInfo() + .getHeight()); + field.setImageWidth(result.getImageInfo() + .getWidth()); + batch.store(newDraftVersion, node.getProject() + .getReleaseRoot() + .getLatestRelease() + .getUuid(), DRAFT, false); + return node; }); + // Finally update the search index and return the updated node + return batch.processAsync() + .andThen(updatedNodeUuid.transformToRest(ac, 0)); } catch (GenericRestException e) { throw e; } catch (Exception e) { log.error("Error while transforming image", e); throw error(INTERNAL_SERVER_ERROR, "error_internal"); } - }).subscribe(model -> ac.send(model, OK), ac::fail); + }) + .subscribe(model -> ac.send(model, OK), ac::fail); } /** @@ -398,7 +447,9 @@ public void handleTransformImage(RoutingContext rc, String uuid, String fieldNam * @return */ protected Single hashAndMoveBinaryFile(FileUpload fileUpload, String uuid, String segmentedPath) { - MeshUploadOptions uploadOptions = Mesh.mesh().getOptions().getUploadOptions(); + MeshUploadOptions uploadOptions = Mesh.mesh() + .getOptions() + .getUploadOptions(); File uploadFolder = new File(uploadOptions.getDirectory(), segmentedPath); File targetFile = new File(uploadFolder, uuid + ".bin"); String targetPath = targetFile.getAbsolutePath(); @@ -407,10 +458,11 @@ protected Single hashAndMoveBinaryFile(FileUpload fileUpload, String uui checkUploadFolderExists(uploadFolder).await(); deletePotentialUpload(targetPath).await(); return moveUploadIntoPlace(fileUpload, targetPath).toSingleDefault(sha512sum); - }).doOnError(error -> { - log.error("Failed to handle upload file from {" + fileUpload.uploadedFileName() + "} / {" + targetPath + "}", error); - throw error(INTERNAL_SERVER_ERROR, "node_error_upload_failed", error); - }); + }) + .doOnError(error -> { + log.error("Failed to handle upload file from {" + fileUpload.uploadedFileName() + "} / {" + targetPath + "}", error); + throw error(INTERNAL_SERVER_ERROR, "node_error_upload_failed", error); + }); } @@ -426,7 +478,9 @@ protected Single hashAndMoveBinaryFile(FileUpload fileUpload, String uui * @return single emitting the sha512 checksum */ public Single hashAndStoreBinaryFile(Buffer buffer, String uuid, String segmentedPath) { - MeshUploadOptions uploadOptions = Mesh.mesh().getOptions().getUploadOptions(); + MeshUploadOptions uploadOptions = Mesh.mesh() + .getOptions() + .getUploadOptions(); File uploadFolder = new File(uploadOptions.getDirectory(), segmentedPath); File targetFile = new File(uploadFolder, uuid + ".bin"); String targetPath = targetFile.getAbsolutePath(); @@ -445,9 +499,10 @@ public Single hashAndStoreBinaryFile(Buffer buffer, String uuid, String * @return */ protected Single hashFileupload(FileUpload fileUpload) { - return FileUtils.generateSha512Sum(fileUpload.uploadedFileName()).doOnError(error -> { - log.error("Error while hashing fileupload {" + fileUpload.uploadedFileName() + "}", error); - }); + return FileUtils.generateSha512Sum(fileUpload.uploadedFileName()) + .doOnError(error -> { + log.error("Error while hashing fileupload {" + fileUpload.uploadedFileName() + "}", error); + }); } /** @@ -458,10 +513,11 @@ protected Single hashFileupload(FileUpload fileUpload) { * @return single emitting the sha512 checksum */ protected Single hashBuffer(Buffer buffer) { - Single obsHash = FileUtils.generateSha512Sum(buffer).doOnError(error -> { - log.error("Error while hashing data", error); - throw error(INTERNAL_SERVER_ERROR, "node_error_upload_failed", error); - }); + Single obsHash = FileUtils.generateSha512Sum(buffer) + .doOnError(error -> { + log.error("Error while hashing data", error); + throw error(INTERNAL_SERVER_ERROR, "node_error_upload_failed", error); + }); return obsHash; } @@ -475,13 +531,16 @@ protected Completable deletePotentialUpload(String targetPath) { Vertx rxVertx = Vertx.newInstance(Mesh.vertx()); FileSystem fileSystem = rxVertx.fileSystem(); // Deleting of existing binary file - Completable obsDeleteExisting = fileSystem.rxDelete(targetPath).toCompletable().doOnError(error -> { - log.error("Error while attempting to delete target file {" + targetPath + "}", error); - }); + Completable obsDeleteExisting = fileSystem.rxDelete(targetPath) + .toCompletable() + .doOnError(error -> { + log.error("Error while attempting to delete target file {" + targetPath + "}", error); + }); - Single obsUploadExistsCheck = fileSystem.rxExists(targetPath).doOnError(error -> { - log.error("Unable to check existence of file at location {" + targetPath + "}"); - }); + Single obsUploadExistsCheck = fileSystem.rxExists(targetPath) + .doOnError(error -> { + log.error("Unable to check existence of file at location {" + targetPath + "}"); + }); return RxUtil.andThenCompletable(obsUploadExistsCheck, uploadAlreadyExists -> { if (uploadAlreadyExists) { @@ -501,13 +560,16 @@ protected Completable deletePotentialUpload(String targetPath) { protected Completable moveUploadIntoPlace(FileUpload fileUpload, String targetPath) { Vertx rxVertx = Vertx.newInstance(Mesh.vertx()); FileSystem fileSystem = rxVertx.fileSystem(); - return fileSystem.rxMove(fileUpload.uploadedFileName(), targetPath).toCompletable().doOnError(error -> { - log.error("Failed to move upload file from {" + fileUpload.uploadedFileName() + "} to {" + targetPath + "}", error); - }).doOnCompleted(() -> { - if (log.isDebugEnabled()) { - log.debug("Moved upload file from {" + fileUpload.uploadedFileName() + "} to {" + targetPath + "}"); - } - }); + return fileSystem.rxMove(fileUpload.uploadedFileName(), targetPath) + .toCompletable() + .doOnError(error -> { + log.error("Failed to move upload file from {" + fileUpload.uploadedFileName() + "} to {" + targetPath + "}", error); + }) + .doOnCompleted(() -> { + if (log.isDebugEnabled()) { + log.debug("Moved upload file from {" + fileUpload.uploadedFileName() + "} to {" + targetPath + "}"); + } + }); } /** @@ -522,10 +584,12 @@ protected Completable moveUploadIntoPlace(FileUpload fileUpload, String targetPa protected Completable storeBuffer(Buffer buffer, String targetPath) { Vertx rxVertx = Vertx.newInstance(Mesh.vertx()); FileSystem fileSystem = rxVertx.fileSystem(); - return fileSystem.rxWriteFile(targetPath, buffer).toCompletable().doOnError(error -> { - log.error("Failed to save file to {" + targetPath + "}", error); - throw error(INTERNAL_SERVER_ERROR, "node_error_upload_failed", error); - }); + return fileSystem.rxWriteFile(targetPath, buffer) + .toCompletable() + .doOnError(error -> { + log.error("Failed to save file to {" + targetPath + "}", error); + throw error(INTERNAL_SERVER_ERROR, "node_error_upload_failed", error); + }); } /** @@ -537,21 +601,25 @@ protected Completable storeBuffer(Buffer buffer, String targetPath) { protected Completable checkUploadFolderExists(File uploadFolder) { Vertx rxVertx = Vertx.newInstance(Mesh.vertx()); FileSystem fileSystem = rxVertx.fileSystem(); - Single obs = fileSystem.rxExists(uploadFolder.getAbsolutePath()).doOnError(error -> { - log.error("Could not check whether target directory {" + uploadFolder.getAbsolutePath() + "} exists.", error); - throw error(BAD_REQUEST, "node_error_upload_failed", error); - }); + Single obs = fileSystem.rxExists(uploadFolder.getAbsolutePath()) + .doOnError(error -> { + log.error("Could not check whether target directory {" + uploadFolder.getAbsolutePath() + "} exists.", error); + throw error(BAD_REQUEST, "node_error_upload_failed", error); + }); return RxUtil.andThenCompletable(obs, folderExists -> { if (!folderExists) { - return fileSystem.rxMkdirs(uploadFolder.getAbsolutePath()).toCompletable().doOnError(error -> { - log.error("Failed to create target folder {" + uploadFolder.getAbsolutePath() + "}", error); - throw error(BAD_REQUEST, "node_error_upload_failed", error); - }).doOnCompleted(() -> { - if (log.isDebugEnabled()) { - log.debug("Created folder {" + uploadFolder.getAbsolutePath() + "}"); - } - }); + return fileSystem.rxMkdirs(uploadFolder.getAbsolutePath()) + .toCompletable() + .doOnError(error -> { + log.error("Failed to create target folder {" + uploadFolder.getAbsolutePath() + "}", error); + throw error(BAD_REQUEST, "node_error_upload_failed", error); + }) + .doOnCompleted(() -> { + if (log.isDebugEnabled()) { + log.debug("Created folder {" + uploadFolder.getAbsolutePath() + "}"); + } + }); } else { return Completable.complete(); } diff --git a/core/src/main/java/com/gentics/mesh/core/verticle/node/TransformationResult.java b/core/src/main/java/com/gentics/mesh/core/verticle/node/TransformationResult.java index 57f17e8f74..f2c7963ddb 100644 --- a/core/src/main/java/com/gentics/mesh/core/verticle/node/TransformationResult.java +++ b/core/src/main/java/com/gentics/mesh/core/verticle/node/TransformationResult.java @@ -2,26 +2,54 @@ import com.gentics.mesh.core.image.spi.ImageInfo; +/** + * Image transformation result object. + */ public class TransformationResult { private String sha512sum; private long size; private ImageInfo imageInfo; + /** + * Create a new result. + * + * @param sha512sum + * New sha512 checksum of the image + * @param size + * New image binary size + * @param imageInfo + * New image properties (width, height..) + */ public TransformationResult(String sha512sum, long size, ImageInfo imageInfo) { this.sha512sum = sha512sum; this.size = size; this.imageInfo = imageInfo; } + /** + * Return the hash of the image. + * + * @return + */ public String getHash() { return sha512sum; } + /** + * Return the image properties of the file. + * + * @return + */ public ImageInfo getImageInfo() { return imageInfo; } + /** + * Return the size of the image in bytes. + * + * @return + */ public long getSize() { return size; } diff --git a/core/src/test/java/com/gentics/mesh/core/node/NodeImageResizeEndpointTest.java b/core/src/test/java/com/gentics/mesh/core/node/NodeImageResizeEndpointTest.java index 0889420b78..497edb302d 100644 --- a/core/src/test/java/com/gentics/mesh/core/node/NodeImageResizeEndpointTest.java +++ b/core/src/test/java/com/gentics/mesh/core/node/NodeImageResizeEndpointTest.java @@ -8,6 +8,7 @@ import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -112,6 +113,7 @@ public void testTransformImage() throws Exception { // 1. Upload image return uploadImage(node, "en", "image").getVersion(); }); + // 2. Transform the image ImageManipulationParameters params = new ImageManipulationParametersImpl().setWidth(100); NodeResponse transformResponse = call( @@ -121,12 +123,17 @@ public void testTransformImage() throws Exception { .getWidth() .intValue()); - // 3. Download the image + // 3. Validate that a new version was created + String newNumber = transformResponse.getVersion().getNumber(); + assertNotEquals("The version number should have changed.", version.getNumber(), newNumber); + + // 4. Download the image NodeDownloadResponse result = call(() -> client().downloadBinaryField(PROJECT_NAME, uuid, "en", "image")); - // 4. Validate the resized image + // 5. Validate the resized image validateResizeImage(result, null, params, 100, 118); + } @Test diff --git a/rest-client/src/main/java/com/gentics/mesh/rest/client/method/NodeBinaryFieldClientMethods.java b/rest-client/src/main/java/com/gentics/mesh/rest/client/method/NodeBinaryFieldClientMethods.java index e43a9815ad..96b990a395 100644 --- a/rest-client/src/main/java/com/gentics/mesh/rest/client/method/NodeBinaryFieldClientMethods.java +++ b/rest-client/src/main/java/com/gentics/mesh/rest/client/method/NodeBinaryFieldClientMethods.java @@ -54,7 +54,7 @@ MeshRequest downloadBinaryField(String projectName, String * @param projectName * project name * @param nodeUuid - * uuid of hte node + * UUID of the node * @param languageTag * language tag * @param version