FINERACT-2169: Refactor image api resource;

This commit is contained in:
viktorpavlenko
2025-03-19 12:27:05 +01:00
committed by Adam Saghy
parent ac8f62db51
commit ef47989656
2 changed files with 29 additions and 33 deletions
@@ -42,7 +42,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.UploadRequest; import org.apache.fineract.infrastructure.core.data.UploadRequest;
import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage; import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils; import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.ImageFileExtension; import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.ImageFileExtension;
import org.apache.fineract.infrastructure.documentmanagement.data.FileData; import org.apache.fineract.infrastructure.documentmanagement.data.FileData;
@@ -52,7 +51,6 @@ import org.apache.fineract.infrastructure.documentmanagement.exception.InvalidEn
import org.apache.fineract.infrastructure.documentmanagement.service.ImageReadPlatformService; import org.apache.fineract.infrastructure.documentmanagement.service.ImageReadPlatformService;
import org.apache.fineract.infrastructure.documentmanagement.service.ImageWritePlatformService; import org.apache.fineract.infrastructure.documentmanagement.service.ImageWritePlatformService;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.client.data.ClientData;
import org.glassfish.jersey.media.multipart.FormDataBodyPart; import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam; import org.glassfish.jersey.media.multipart.FormDataParam;
@@ -67,7 +65,6 @@ public class ImagesApiResource {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ImageReadPlatformService imageReadPlatformService; private final ImageReadPlatformService imageReadPlatformService;
private final ImageWritePlatformService imageWritePlatformService; private final ImageWritePlatformService imageWritePlatformService;
private final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer;
private final FileUploadValidator fileUploadValidator; private final FileUploadValidator fileUploadValidator;
private final ImageResizer imageResizer; private final ImageResizer imageResizer;
@@ -79,9 +76,10 @@ public class ImagesApiResource {
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@RequestBody(description = "Upload new client image", content = { @RequestBody(description = "Upload new client image", content = {
@Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) }) @Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) })
public String addNewClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId, public CommandProcessingResult addNewClientImage(@PathParam("entity") final String entityName,
@HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream, @PathParam("entityId") final Long entityId, @HeaderParam("Content-Length") final Long fileSize,
@FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart) { @FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails,
@FormDataParam("file") final FormDataBodyPart bodyPart) {
validateEntityTypeforImage(entityName); validateEntityTypeforImage(entityName);
fileUploadValidator.validate(fileSize, inputStream, fileDetails, bodyPart); fileUploadValidator.validate(fileSize, inputStream, fileDetails, bodyPart);
// TODO: vishwas might need more advances validation (like reading magic // TODO: vishwas might need more advances validation (like reading magic
@@ -90,10 +88,7 @@ public class ImagesApiResource {
ContentRepositoryUtils.validateClientImageNotEmpty(fileDetails.getFileName()); ContentRepositoryUtils.validateClientImageNotEmpty(fileDetails.getFileName());
ContentRepositoryUtils.validateImageMimeType(bodyPart.getMediaType().toString()); ContentRepositoryUtils.validateImageMimeType(bodyPart.getMediaType().toString());
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateImage(entityName, entityId, return imageWritePlatformService.saveOrUpdateImage(entityName, entityId, fileDetails.getFileName(), inputStream, fileSize);
fileDetails.getFileName(), inputStream, fileSize);
return this.toApiJsonSerializer.serialize(result);
} }
/** /**
@@ -102,15 +97,13 @@ public class ImagesApiResource {
@POST @POST
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public String addNewClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId, public CommandProcessingResult addNewClientImage(@PathParam("entity") final String entityName,
final String jsonRequestBody) { @PathParam("entityId") final Long entityId, final String jsonRequestBody) {
validateEntityTypeforImage(entityName); validateEntityTypeforImage(entityName);
final Base64EncodedImage base64EncodedImage = ContentRepositoryUtils.extractImageFromDataURL(jsonRequestBody); final Base64EncodedImage base64EncodedImage = ContentRepositoryUtils.extractImageFromDataURL(jsonRequestBody);
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateImage(entityName, entityId, base64EncodedImage); return imageWritePlatformService.saveOrUpdateImage(entityName, entityId, base64EncodedImage);
return this.toApiJsonSerializer.serialize(result);
} }
/** /**
@@ -126,17 +119,17 @@ public class ImagesApiResource {
@QueryParam("output") final String output, @HeaderParam("Accept") String acceptHeader) { @QueryParam("output") final String output, @HeaderParam("Accept") String acceptHeader) {
validateEntityTypeforImage(entityName); validateEntityTypeforImage(entityName);
if (EntityTypeForImages.CLIENTS.toString().equalsIgnoreCase(entityName)) { if (EntityTypeForImages.CLIENTS.toString().equalsIgnoreCase(entityName)) {
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE"); context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
} else if (EntityTypeForImages.STAFF.toString().equalsIgnoreCase(entityName)) { } else if (EntityTypeForImages.STAFF.toString().equalsIgnoreCase(entityName)) {
this.context.authenticatedUser().validateHasReadPermission("STAFFIMAGE"); context.authenticatedUser().validateHasReadPermission("STAFFIMAGE");
} }
final FileData imageData = this.imageReadPlatformService.retrieveImage(entityName, entityId); final FileData imageData = imageReadPlatformService.retrieveImage(entityName, entityId);
final FileData resizedImage = imageResizer.resize(imageData, maxWidth, maxHeight); final FileData resizedImage = imageResizer.resize(imageData, maxWidth, maxHeight);
// If client wants (Accept header) octet-stream, or output="octet" or "inline_octet", then send that instead of // If client wants (Accept header) octet-stream, or output="octet" or "inline_octet", then send that instead of
// text // text
if ("application/octet-stream".equalsIgnoreCase(acceptHeader) if (MediaType.APPLICATION_OCTET_STREAM.equalsIgnoreCase(acceptHeader)
|| (output != null && (output.equals("octet") || output.equals("inline_octet")))) { || (output != null && (output.equals("octet") || output.equals("inline_octet")))) {
return ContentResources.fileDataToResponse(resizedImage, resizedImage.name() + ImageFileExtension.JPEG, return ContentResources.fileDataToResponse(resizedImage, resizedImage.name() + ImageFileExtension.JPEG,
"inline_octet".equals(output) ? "inline" : "attachment"); "inline_octet".equals(output) ? "inline" : "attachment");
@@ -175,9 +168,10 @@ public class ImagesApiResource {
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@RequestBody(description = "Update client image", content = { @RequestBody(description = "Update client image", content = {
@Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) }) @Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) })
public String updateClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId, public CommandProcessingResult updateClientImage(@PathParam("entity") final String entityName,
@HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream, @PathParam("entityId") final Long entityId, @HeaderParam("Content-Length") final Long fileSize,
@FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart) { @FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails,
@FormDataParam("file") final FormDataBodyPart bodyPart) {
return addNewClientImage(entityName, entityId, fileSize, inputStream, fileDetails, bodyPart); return addNewClientImage(entityName, entityId, fileSize, inputStream, fileDetails, bodyPart);
} }
@@ -190,18 +184,19 @@ public class ImagesApiResource {
@PUT @PUT
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public String updateClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId, public CommandProcessingResult updateClientImage(@PathParam("entity") final String entityName,
final String jsonRequestBody) { @PathParam("entityId") final Long entityId, final String jsonRequestBody) {
return addNewClientImage(entityName, entityId, jsonRequestBody); return addNewClientImage(entityName, entityId, jsonRequestBody);
} }
@DELETE @DELETE
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public String deleteClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId) { public CommandProcessingResult deleteClientImage(@PathParam("entity") final String entityName,
@PathParam("entityId") final Long entityId) {
validateEntityTypeforImage(entityName); validateEntityTypeforImage(entityName);
this.imageWritePlatformService.deleteImage(entityName, entityId); imageWritePlatformService.deleteImage(entityName, entityId);
return this.toApiJsonSerializer.serialize(CommandProcessingResult.resourceResult(entityId)); return CommandProcessingResult.resourceResult(entityId);
} }
/*** Entities for document Management **/ /*** Entities for document Management **/
@@ -42,6 +42,7 @@ import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo; import jakarta.ws.rs.core.UriInfo;
import java.io.InputStream; import java.io.InputStream;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.UploadRequest; import org.apache.fineract.infrastructure.core.data.UploadRequest;
import org.apache.fineract.infrastructure.documentmanagement.api.ImagesApiResource; import org.apache.fineract.infrastructure.documentmanagement.api.ImagesApiResource;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
@@ -236,9 +237,9 @@ public class SelfClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
@RequestBody(description = "Add new client image", content = { @RequestBody(description = "Add new client image", content = {
@Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) }) @Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) })
public String addNewClientImage(@PathParam("clientId") final Long clientId, @HeaderParam("Content-Length") final Long fileSize, public CommandProcessingResult addNewClientImage(@PathParam("clientId") final Long clientId,
@FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails, @HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream,
@FormDataParam("file") final FormDataBodyPart bodyPart) { @FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart) {
validateAppuserClientsMapping(clientId); validateAppuserClientsMapping(clientId);
return this.imagesApiResource.addNewClientImage(ClientApiConstants.clientEntityName, clientId, fileSize, inputStream, fileDetails, return this.imagesApiResource.addNewClientImage(ClientApiConstants.clientEntityName, clientId, fileSize, inputStream, fileDetails,
@@ -250,8 +251,8 @@ public class SelfClientsApiResource {
@Path("{clientId}/images") @Path("{clientId}/images")
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String addNewClientImage(@PathParam("entity") final String entityName, @PathParam("clientId") final Long clientId, public CommandProcessingResult addNewClientImage(@PathParam("entity") final String entityName,
final String jsonRequestBody) { @PathParam("clientId") final Long clientId, final String jsonRequestBody) {
validateAppuserClientsMapping(clientId); validateAppuserClientsMapping(clientId);
return this.imagesApiResource.addNewClientImage(ClientApiConstants.clientEntityName, clientId, jsonRequestBody); return this.imagesApiResource.addNewClientImage(ClientApiConstants.clientEntityName, clientId, jsonRequestBody);
@@ -261,7 +262,7 @@ public class SelfClientsApiResource {
@Path("{clientId}/images") @Path("{clientId}/images")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String deleteClientImage(@PathParam("clientId") final Long clientId) { public CommandProcessingResult deleteClientImage(@PathParam("clientId") final Long clientId) {
validateAppuserClientsMapping(clientId); validateAppuserClientsMapping(clientId);
return this.imagesApiResource.deleteClientImage(ClientApiConstants.clientEntityName, clientId); return this.imagesApiResource.deleteClientImage(ClientApiConstants.clientEntityName, clientId);