Refactoring document and image management
This commit is contained in:
@@ -1,28 +0,0 @@
|
||||
INSERT INTO c_configuration (name,enabled) VALUES ('amazon-S3',0);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS m_external_services (
|
||||
name VARCHAR(150) NOT NULL,
|
||||
value VARCHAR(250),
|
||||
UNIQUE(name)
|
||||
);
|
||||
|
||||
INSERT INTO m_external_services (name) VALUES ('s3_bucket_name');
|
||||
INSERT INTO m_external_services (name) VALUES ('s3_access_key');
|
||||
INSERT INTO m_external_services (name) VALUES ('s3_secret_key');
|
||||
|
||||
ALTER TABLE m_document ADD COLUMN storage_type varchar(50);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `m_image`(
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`client_id` BIGINT NOT NULL,
|
||||
`key` varchar(500),
|
||||
`storage_type` varchar(50),
|
||||
FOREIGN KEY (`client_id`) REFERENCES m_client(`id`),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE(client_id)
|
||||
);
|
||||
|
||||
UPDATE m_document set storage_type='file_system';
|
||||
|
||||
insert into m_image (`client_id`,`key`,`storage_type`) select id,`image_key`,'file_system' from m_client where `image_key` IS NOT NULL;
|
||||
@@ -0,0 +1,70 @@
|
||||
INSERT INTO c_configuration (name,enabled) VALUES ('amazon-S3',0);
|
||||
|
||||
/*New table for storing details of external services used*/
|
||||
CREATE TABLE `c_external_service` (
|
||||
`name` VARCHAR(150) NOT NULL,
|
||||
`value` VARCHAR(250) NULL DEFAULT NULL,
|
||||
UNIQUE INDEX `name` (`name`)
|
||||
)
|
||||
COLLATE='utf8_general_ci'
|
||||
ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO c_external_service (name) VALUES ('s3_bucket_name');
|
||||
INSERT INTO c_external_service (name) VALUES ('s3_access_key');
|
||||
INSERT INTO c_external_service (name) VALUES ('s3_secret_key');
|
||||
|
||||
|
||||
|
||||
/*Image tables stores details of all images*/
|
||||
CREATE TABLE IF NOT EXISTS `m_image`(
|
||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
`location` varchar(500),
|
||||
`storage_type_enum` SMALLINT(5),
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
COLLATE='utf8_general_ci'
|
||||
ENGINE=InnoDB;
|
||||
|
||||
/*Client points to image table*/
|
||||
ALTER TABLE `m_client`
|
||||
ADD COLUMN `image_id` BIGINT(20) NULL DEFAULT NULL AFTER `display_name`,
|
||||
ADD CONSTRAINT `FK_m_client_m_image` FOREIGN KEY (`image_id`) REFERENCES `m_image` (`id`);
|
||||
|
||||
/*Move existing image locations to new table*/
|
||||
drop procedure if exists migrate_customer_image_data;
|
||||
|
||||
delimiter #
|
||||
create procedure migrate_customer_image_data()
|
||||
begin
|
||||
declare v_counter int unsigned default 0;
|
||||
declare num_of_clients INT DEFAULT 0;
|
||||
declare curr_client INT DEFAULT 0;
|
||||
declare curr_image INT DEFAULT 0;
|
||||
declare prev_image INT DEFAULT 0;
|
||||
SELECT COUNT(*) FROM m_client INTO num_of_clients;
|
||||
while v_counter < num_of_clients do
|
||||
INSERT INTO m_image(`location`,`storage_type_enum`) select image_key, 1 FROM m_client where image_key is not null LIMIT v_counter,1;
|
||||
select ifnull(max(`id`),0) from m_image INTO curr_image;
|
||||
select id FROM m_client where image_key is not null limit v_counter,1 INTO curr_client;
|
||||
IF (prev_image != curr_image) THEN UPDATE m_client set image_id = curr_image where id=curr_client;
|
||||
END IF;
|
||||
set prev_image=curr_image;
|
||||
set v_counter=v_counter+1;
|
||||
end while;
|
||||
delete from m_image where `location` is null;
|
||||
end#
|
||||
|
||||
delimiter ;
|
||||
call migrate_customer_image_data();
|
||||
|
||||
/*Now drop the procedure*/
|
||||
drop procedure if exists migrate_customer_image_data;
|
||||
|
||||
/*Delete image key from client*/
|
||||
ALTER TABLE `m_client` DROP COLUMN `image_key`;
|
||||
|
||||
|
||||
/*Add storage type for m_document table and update existing documents to file storage*/
|
||||
ALTER TABLE m_document ADD COLUMN storage_type_enum SMALLINT(5);
|
||||
UPDATE m_document set storage_type_enum=1;
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.infrastructure.configuration.data;
|
||||
|
||||
public class S3CredentialsData {
|
||||
|
||||
private final String bucketName;
|
||||
private final String accessKey;
|
||||
private final String secretKey;
|
||||
|
||||
public S3CredentialsData(String bucketName, String accessKey, String secretKey) {
|
||||
this.bucketName = bucketName;
|
||||
this.accessKey = accessKey;
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
|
||||
public String getBucketName() {
|
||||
return this.bucketName;
|
||||
}
|
||||
|
||||
public String getAccessKey() {
|
||||
return this.accessKey;
|
||||
}
|
||||
|
||||
public String getSecretKey() {
|
||||
return this.secretKey;
|
||||
}
|
||||
|
||||
}
|
||||
+8
-8
@@ -1,20 +1,21 @@
|
||||
package org.mifosplatform.infrastructure.configuration.domain;
|
||||
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_external_services", uniqueConstraints = { @UniqueConstraint(columnNames = ("name"))})
|
||||
public class ExternalServiceProperty extends AbstractPersistable<Long> {
|
||||
@Table(name = "c_external_service", uniqueConstraints = { @UniqueConstraint(columnNames = ("name")) })
|
||||
public class ExternalService extends AbstractPersistable<Long> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "name", nullable = false)
|
||||
@@ -23,15 +24,14 @@ public class ExternalServiceProperty extends AbstractPersistable<Long> {
|
||||
@Column(name = "value", nullable = false)
|
||||
private String value;
|
||||
|
||||
public ExternalServiceProperty(final String name, final String value) {
|
||||
public ExternalService(final String name, final String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ExternalServiceProperty() {
|
||||
}
|
||||
protected ExternalService() {}
|
||||
|
||||
public String getValue(){
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -3,8 +3,7 @@ package org.mifosplatform.infrastructure.configuration.domain;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface ExternalServiceRepository extends JpaRepository<ExternalServiceProperty, Long>,
|
||||
JpaSpecificationExecutor<ExternalServiceProperty> {
|
||||
public interface ExternalServiceRepository extends JpaRepository<ExternalService, Long>, JpaSpecificationExecutor<ExternalService> {
|
||||
|
||||
ExternalServiceProperty findOneByName(String name);
|
||||
ExternalService findOneByName(String name);
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package org.mifosplatform.infrastructure.configuration.domain;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ExternalServicesDomainService {
|
||||
private ExternalServiceRepository externalServiceRepository;
|
||||
|
||||
@Autowired
|
||||
public ExternalServicesDomainService(final ExternalServiceRepository externalServiceRepository) {
|
||||
this.externalServiceRepository = externalServiceRepository;
|
||||
}
|
||||
|
||||
public String getValue(String name){
|
||||
return externalServiceRepository.findOneByName(name).getValue();
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.mifosplatform.infrastructure.configuration.service;
|
||||
|
||||
public class ExternalServicesConstants {
|
||||
|
||||
public static final String S3_BUCKET_NAME = "s3_bucket_name";
|
||||
public static final String S3_ACCESS_KEY = "s3_access_key";
|
||||
public static final String S3_SECRET_KEY = "s3_secret_key";
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.mifosplatform.infrastructure.configuration.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.configuration.data.S3CredentialsData;
|
||||
|
||||
public interface ExternalServicesReadPlatformService {
|
||||
|
||||
S3CredentialsData getS3Credentials();
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package org.mifosplatform.infrastructure.configuration.service;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.mifosplatform.infrastructure.configuration.data.S3CredentialsData;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ExternalServicesReadPlatformServiceImpl implements ExternalServicesReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Autowired
|
||||
public ExternalServicesReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
private static final class S3CredentialsDataExtractor implements ResultSetExtractor<S3CredentialsData> {
|
||||
|
||||
@Override
|
||||
public S3CredentialsData extractData(ResultSet rs) throws SQLException, DataAccessException {
|
||||
String accessKey = null;
|
||||
String bucketName = null;
|
||||
String secretKey = null;
|
||||
while (rs.next()) {
|
||||
if (rs.getString("name").equalsIgnoreCase(ExternalServicesConstants.S3_ACCESS_KEY)) {
|
||||
accessKey = rs.getString("value");
|
||||
} else if (rs.getString("name").equalsIgnoreCase(ExternalServicesConstants.S3_BUCKET_NAME)) {
|
||||
bucketName = rs.getString("value");
|
||||
} else if (rs.getString("name").equalsIgnoreCase(ExternalServicesConstants.S3_SECRET_KEY)) {
|
||||
secretKey = rs.getString("value");
|
||||
}
|
||||
}
|
||||
return new S3CredentialsData(bucketName, accessKey, secretKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3CredentialsData getS3Credentials() {
|
||||
final ResultSetExtractor<S3CredentialsData> resultSetExtractor = new S3CredentialsDataExtractor();
|
||||
final String sql = "SELECT es.name, es.value FROM c_external_service es where es.name in('s3_bucket_name','s3_access_key','s3_secret_key')";
|
||||
final S3CredentialsData s3CredentialsData = this.jdbcTemplate.query(sql, resultSetExtractor, new Object[] {});
|
||||
return s3CredentialsData;
|
||||
}
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.core.api;
|
||||
|
||||
public class ApiConstants {
|
||||
|
||||
// TODO:Vishwas Need to move these settings to the Database
|
||||
public static final Integer MAX_FILE_UPLOAD_SIZE_IN_MB = 5;
|
||||
|
||||
// TODO:Vishwas Need to move these settings to the Database
|
||||
public static final Integer MAX_IMAGE_UPLOAD_SIZE_IN_MB = 1;
|
||||
}
|
||||
+2
-1
@@ -13,12 +13,13 @@ import org.springframework.security.authentication.dao.SaltSource;
|
||||
import org.springframework.security.authentication.encoding.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Service(value = "applicationPasswordEncoder")
|
||||
@Scope("singleton")
|
||||
public class DefaultPlatformPasswordEncoder implements PlatformPasswordEncoder {
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final SaltSource saltSource;
|
||||
private final SaltSource saltSource;
|
||||
|
||||
@Autowired
|
||||
public DefaultPlatformPasswordEncoder(final PasswordEncoder passwordEncoder, final SaltSource saltSource) {
|
||||
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.ApiConstants;
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||
import org.mifosplatform.portfolio.client.data.ImageData;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public abstract class DocumentStore {
|
||||
protected DocumentStoreType type;
|
||||
|
||||
protected Integer maxFileSize = ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB;
|
||||
protected Integer maxImageSize = ApiConstants.MAX_IMAGE_UPLOAD_SIZE_IN_MB;
|
||||
|
||||
public abstract String saveDocument(InputStream uploadedInputStream, DocumentCommand documentCommand) throws DocumentManagementException;
|
||||
public abstract void deleteDocument(String documentName, String documentPath) throws DocumentManagementException;
|
||||
public abstract FileData retrieveDocument(DocumentData documentData) throws DocumentNotFoundException;
|
||||
|
||||
public abstract String saveImage(InputStream uploadedInputStream, Long resourceId, String imageName, Long fileSize) throws DocumentManagementException;
|
||||
public abstract String saveImage(Base64EncodedImage base64EncodedImage, Long resourceId, String imageName) throws DocumentManagementException;
|
||||
public abstract void deleteImage(final Long resourceId, final String location);
|
||||
public abstract ImageData retrieveImage(ImageData imageData);
|
||||
|
||||
public abstract DocumentStoreType getType();
|
||||
|
||||
protected void validateFileSizeWithinPermissibleRange(Long fileSize, String name, int maxFileSize) {
|
||||
/**
|
||||
* Using Content-Length gives me size of the entire request, which is
|
||||
* good enough for now for a fast fail as the length of the rest of the
|
||||
* content i.e name and description while compared to the uploaded file
|
||||
* size is negligible
|
||||
**/
|
||||
if (fileSize != null && ((fileSize / (1024 * 1024)) > maxFileSize)) {
|
||||
throw new DocumentManagementException(name, fileSize,
|
||||
maxFileSize);
|
||||
}
|
||||
}
|
||||
|
||||
public static DocumentStoreType getDocumentStoreType(String documentStoreType){
|
||||
if (documentStoreType.equals(DocumentStoreType.FILE_SYSTEM.getValue())) {
|
||||
return DocumentStoreType.FILE_SYSTEM;
|
||||
} else {
|
||||
return DocumentStoreType.S3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
|
||||
import com.amazonaws.services.s3.AmazonS3Client;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ExternalServicesDomainService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class DocumentStoreFactory {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
public DocumentStoreFactory(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public DocumentStore getInstanceFromConfiguration(){
|
||||
ConfigurationDomainService configurationDomainServiceJpa = applicationContext.getBean("configurationDomainServiceJpa", ConfigurationDomainService.class);
|
||||
if(configurationDomainServiceJpa.isAmazonS3Enabled()){
|
||||
return createS3DocumentStore();
|
||||
}
|
||||
else {
|
||||
return new FileSystemDocumentStore();
|
||||
}
|
||||
}
|
||||
|
||||
public DocumentStore getInstanceFromStorageType(DocumentStoreType documentStoreType){
|
||||
if(documentStoreType == DocumentStoreType.FILE_SYSTEM){
|
||||
return new FileSystemDocumentStore();
|
||||
}
|
||||
else {
|
||||
return createS3DocumentStore();
|
||||
}
|
||||
}
|
||||
private DocumentStore createS3DocumentStore() {
|
||||
AmazonS3Client s3Client = applicationContext.getBean("s3ClientFactory", S3ClientFactory.class).getS3Client();
|
||||
ExternalServicesDomainService externalServicesDomainService = applicationContext.getBean("externalServicesDomainService", ExternalServicesDomainService.class);
|
||||
return new S3DocumentStore(externalServicesDomainService.getValue("s3_bucket_name"), s3Client);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
|
||||
public enum DocumentStoreType {
|
||||
FILE_SYSTEM("file_system"), S3("s3");
|
||||
|
||||
private String value;
|
||||
|
||||
DocumentStoreType(String value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class RandomStringGenerator {
|
||||
public static Random random = new Random();
|
||||
|
||||
/**
|
||||
* Generate a random String
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String generateRandomString() {
|
||||
String characters = "abcdefghijklmnopqrstuvwxyz123456789";
|
||||
int length = generateRandomNumber();
|
||||
char[] text = new char[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
text[i] = characters.charAt(random.nextInt(characters.length()));
|
||||
}
|
||||
return new String(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random number between 5 to 16
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int generateRandomNumber() {
|
||||
Random randomGenerator = new Random();
|
||||
return randomGenerator.nextInt(11) + 5;
|
||||
}
|
||||
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.services.s3.AmazonS3Client;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ExternalServicesDomainService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class S3ClientFactory {
|
||||
|
||||
private ExternalServicesDomainService ExternalServicesDomainService;
|
||||
|
||||
@Autowired
|
||||
public S3ClientFactory(final ExternalServicesDomainService ExternalServicesDomainService) {
|
||||
this.ExternalServicesDomainService = ExternalServicesDomainService;
|
||||
}
|
||||
|
||||
public AmazonS3Client getS3Client() {
|
||||
String s3_access_key = ExternalServicesDomainService.getValue("s3_access_key");
|
||||
String s3_secret_key = ExternalServicesDomainService.getValue("s3_secret_key");
|
||||
return new AmazonS3Client(new BasicAWSCredentials(s3_access_key,s3_secret_key));
|
||||
}
|
||||
}
|
||||
-201
@@ -1,201 +0,0 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
|
||||
|
||||
import com.amazonaws.AmazonClientException;
|
||||
import com.amazonaws.AmazonServiceException;
|
||||
import com.amazonaws.services.s3.AmazonS3;
|
||||
import com.amazonaws.services.s3.model.*;
|
||||
import com.lowagie.text.pdf.codec.Base64;
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||
import org.mifosplatform.portfolio.client.data.ImageData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class S3DocumentStore extends DocumentStore {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(S3DocumentStore.class);
|
||||
|
||||
private final String s3BucketName;
|
||||
private AmazonS3 s3Client;
|
||||
|
||||
public S3DocumentStore(String s3BucketName, AmazonS3 s3Client) {
|
||||
this.s3BucketName = s3BucketName;
|
||||
this.s3Client = s3Client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveDocument(InputStream toUpload, DocumentCommand documentCommand) throws DocumentManagementException {
|
||||
String documentName = documentCommand.getFileName();
|
||||
validateFileSizeWithinPermissibleRange(documentCommand.getSize(), documentName, maxFileSize);
|
||||
|
||||
String uploadDocFolder = generateFileParentDirectory(documentCommand.getParentEntityType(), documentCommand.getParentEntityId());
|
||||
String uploadDocFullPath = uploadDocFolder + File.separator + documentName;
|
||||
|
||||
uploadDocument(toUpload, uploadDocFullPath);
|
||||
return uploadDocFullPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDocument(String documentName, String documentPath) throws DocumentManagementException {
|
||||
try{
|
||||
deleteObjectFromS3(documentPath);
|
||||
}catch (AmazonServiceException ase){
|
||||
deleteObjectAmazonServiceExceptionMessage(ase);
|
||||
throw new DocumentManagementException(documentName);
|
||||
}catch (AmazonClientException ace){
|
||||
deleteObjectAmazonClientExceptionMessage(ace);
|
||||
throw new DocumentManagementException(documentName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveImage(InputStream toUploadInputStream, Long resourceId, String imageName, Long fileSize) throws DocumentManagementException {
|
||||
validateFileSizeWithinPermissibleRange(fileSize, imageName, maxImageSize);
|
||||
|
||||
String uploadImageLocation = generateClientImageParentDirectory(resourceId);
|
||||
String fileLocation = uploadImageLocation + File.separator + imageName;
|
||||
|
||||
uploadDocument(toUploadInputStream, fileLocation);
|
||||
return fileLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveImage(Base64EncodedImage base64EncodedImage, Long resourceId, String imageName) throws DocumentManagementException {
|
||||
String uploadImageLocation = generateClientImageParentDirectory(resourceId);
|
||||
String fileLocation = uploadImageLocation + File.separator + imageName + base64EncodedImage.getFileExtension();
|
||||
InputStream toUploadInputStream = new ByteArrayInputStream(Base64.decode(base64EncodedImage.getBase64EncodedString()));
|
||||
|
||||
uploadDocument(toUploadInputStream, fileLocation);
|
||||
return fileLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteImage(Long resourceId, String location) {
|
||||
try {
|
||||
deleteObjectFromS3(location);
|
||||
} catch (AmazonServiceException ase) {
|
||||
deleteObjectAmazonServiceExceptionMessage(ase);
|
||||
logger.warn("Unable to delete image associated with clients with Id " + resourceId);
|
||||
} catch (AmazonClientException ace) {
|
||||
deleteObjectAmazonClientExceptionMessage(ace);
|
||||
logger.warn("Unable to delete image associated with clients with Id " + resourceId);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteObjectAmazonClientExceptionMessage(AmazonClientException ace) {
|
||||
String message = "Caught an AmazonClientException." +
|
||||
"Error Message: " + ace.getMessage();
|
||||
logger.error(message);
|
||||
}
|
||||
|
||||
private void deleteObjectAmazonServiceExceptionMessage(AmazonServiceException ase) {
|
||||
String message = "Caught an AmazonServiceException." +
|
||||
"Error Message: " + ase.getMessage() +
|
||||
"HTTP Status Code: " + ase.getStatusCode() +
|
||||
"AWS Error Code: " + ase.getErrorCode() +
|
||||
"Error Type: " + ase.getErrorType() +
|
||||
"Request ID: " + ase.getRequestId();
|
||||
logger.error(message);
|
||||
}
|
||||
|
||||
private void deleteObjectFromS3(String location) {
|
||||
s3Client.deleteObject(new DeleteObjectRequest(s3BucketName, location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocumentStoreType getType() {
|
||||
return DocumentStoreType.S3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileData retrieveDocument(DocumentData documentData) throws DocumentNotFoundException {
|
||||
FileData fileData = null;
|
||||
String fileName = documentData.fileName();
|
||||
try {
|
||||
logger.info("Downloading an object");
|
||||
S3Object s3object = s3Client.getObject(new GetObjectRequest(s3BucketName, documentData.fileLocation()));
|
||||
fileData = new FileData(s3object.getObjectContent(), fileName, documentData.contentType());
|
||||
} catch (AmazonServiceException ase) {
|
||||
getObjectAmazonServiceExceptionMessage(ase,fileName);
|
||||
throw new DocumentNotFoundException(documentData.getParentEntityType(), documentData.getParentEntityId(), documentData.getId());
|
||||
} catch (AmazonClientException ace) {
|
||||
getObjectAmazonClientExceptionMessage(ace,fileName);
|
||||
throw new DocumentNotFoundException(documentData.getParentEntityType(), documentData.getParentEntityId(), documentData.getId());
|
||||
}
|
||||
return fileData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageData retrieveImage(ImageData imageData) {
|
||||
S3Object s3object = s3Client.getObject(new GetObjectRequest(s3BucketName, imageData.imageKey()));
|
||||
imageData.setContent(s3object.getObjectContent());
|
||||
return imageData;
|
||||
}
|
||||
|
||||
String generateFileParentDirectory(String entityType, Long entityId) {
|
||||
return "documents" + File.separator + entityType + File.separator + entityId + File.separator + RandomStringGenerator.generateRandomString();
|
||||
}
|
||||
|
||||
String generateClientImageParentDirectory(Long resourceId) {
|
||||
return "images" + File.separator + "clients" + File.separator + resourceId;
|
||||
}
|
||||
|
||||
private void uploadDocument(InputStream inputStream, String s3UploadLocation) throws DocumentManagementException {
|
||||
try {
|
||||
logger.info("Uploading a new object to S3 from a file to " + s3UploadLocation);
|
||||
s3Client.putObject(new PutObjectRequest(this.s3BucketName, s3UploadLocation, inputStream, new ObjectMetadata()));
|
||||
|
||||
} catch (AmazonServiceException ase) {
|
||||
String message = "Caught an AmazonServiceException, which " + "means your request made it " + "to Amazon S3, but was rejected with an error response" +
|
||||
" for some reason. \n Error Message: " + ase.getMessage() +
|
||||
"HTTP Status Code: " + ase.getStatusCode() +
|
||||
"AWS Error Code: " + ase.getErrorCode() +
|
||||
"Error Type: " + ase.getErrorType() +
|
||||
"Request ID: " + ase.getRequestId();
|
||||
|
||||
logger.error(message);
|
||||
throw new DocumentManagementException(message);
|
||||
} catch (AmazonClientException ace) {
|
||||
String message = "Caught an AmazonClientException, which " +
|
||||
"means the client encountered " +
|
||||
"an internal error while trying to " +
|
||||
"communicate with S3, " +
|
||||
"such as not being able to access the network." +
|
||||
"Error Message: " + ace.getMessage();
|
||||
logger.error(message);
|
||||
throw new DocumentManagementException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void getObjectAmazonClientExceptionMessage(AmazonClientException ace, String filename) {
|
||||
String message = "Caught an AmazonClientException, which means the client encountered " +
|
||||
"an internal error while trying to communicate with S3, " +
|
||||
"such as not being able to access the network." +
|
||||
"Error Message: " + ace.getMessage() +
|
||||
"FileName: " + filename;
|
||||
|
||||
logger.error(message);
|
||||
}
|
||||
|
||||
private void getObjectAmazonServiceExceptionMessage(AmazonServiceException ase, String filename) {
|
||||
String message = "Caught an AmazonServiceException, which means your request made it " +
|
||||
"to Amazon S3, but was rejected with an error response" +
|
||||
" for some reason." +
|
||||
"Error Message: " + ase.getMessage() +
|
||||
"HTTP Status Code: " + ase.getStatusCode() +
|
||||
"AWS Error Code: " + ase.getErrorCode() +
|
||||
"Error Type: " + ase.getErrorType() +
|
||||
"Request ID: " + ase.getRequestId() +
|
||||
"FileName: " + filename;
|
||||
logger.error(message);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -29,7 +29,6 @@ import javax.ws.rs.core.StreamingOutput;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.core.service.FileSystemDocumentStore;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.ReportData;
|
||||
@@ -38,6 +37,7 @@ import org.mifosplatform.infrastructure.dataqueries.data.ReportParameterJoinData
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.exception.ReportNotFoundException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.FileSystemContentRepository;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot;
|
||||
@@ -243,7 +243,7 @@ public class ReadReportingServiceImpl implements ReadReportingService {
|
||||
if (noPentaho) { throw new PlatformDataIntegrityException("error.msg.no.pentaho", "Pentaho is not enabled",
|
||||
"Pentaho is not enabled"); }
|
||||
|
||||
final String reportPath = FileSystemDocumentStore.MIFOSX_BASE_DIR + File.separator + "pentahoReports" + File.separator + reportName + ".prpt";
|
||||
final String reportPath = FileSystemContentRepository.MIFOSX_BASE_DIR + File.separator + "pentahoReports" + File.separator + reportName + ".prpt";
|
||||
logger.info("Report path: " + reportPath);
|
||||
|
||||
// load report definition
|
||||
@@ -357,7 +357,7 @@ public class ReadReportingServiceImpl implements ReadReportingService {
|
||||
@Override
|
||||
public String retrieveReportPDF(final String reportName, final String type, final Map<String, String> queryParams) {
|
||||
|
||||
String fileLocation = FileSystemDocumentStore.MIFOSX_BASE_DIR + File.separator + "";
|
||||
String fileLocation = FileSystemContentRepository.MIFOSX_BASE_DIR + File.separator + "";
|
||||
if (!new File(fileLocation).isDirectory()) {
|
||||
new File(fileLocation).mkdirs();
|
||||
}
|
||||
|
||||
+3
-6
@@ -52,8 +52,8 @@ public class DocumentManagementApiResource {
|
||||
|
||||
@Autowired
|
||||
public DocumentManagementApiResource(final PlatformSecurityContext context,
|
||||
final DocumentReadPlatformService documentReadPlatformService, final DocumentWritePlatformService documentWritePlatformService,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper, final ToApiJsonSerializer<DocumentData> toApiJsonSerializer) {
|
||||
final DocumentReadPlatformService documentReadPlatformService, final DocumentWritePlatformService documentWritePlatformService,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper, final ToApiJsonSerializer<DocumentData> toApiJsonSerializer) {
|
||||
this.context = context;
|
||||
this.documentReadPlatformService = documentReadPlatformService;
|
||||
this.documentWritePlatformService = documentWritePlatformService;
|
||||
@@ -150,9 +150,6 @@ public class DocumentManagementApiResource {
|
||||
|
||||
final DocumentData documentData = this.documentReadPlatformService.retrieveDocument(entityType, entityId, documentId);
|
||||
|
||||
// we do not want to send document location as a part of the response
|
||||
documentData.setLocation(null);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, documentData, this.RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
@@ -166,7 +163,7 @@ public class DocumentManagementApiResource {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.SystemEntityType);
|
||||
|
||||
final FileData fileData = this.documentReadPlatformService.retrieveDocumentAsFile(entityType, entityId, documentId);
|
||||
final FileData fileData = this.documentReadPlatformService.retrieveFileData(entityType, entityId, documentId);
|
||||
final ResponseBuilder response = Response.ok(fileData.file());
|
||||
response.header("Content-Disposition", "attachment; filename=\"" + fileData.name() + "\"");
|
||||
response.header("Content-Type", fileData.contentType());
|
||||
|
||||
+61
-52
@@ -3,51 +3,63 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.api;
|
||||
package org.mifosplatform.infrastructure.documentmanagement.api;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
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 org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.IMAGE_FILE_EXTENSION;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.service.ImageReadPlatformService;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.service.ImageWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.lowagie.text.pdf.codec.Base64;
|
||||
import com.sun.jersey.core.header.FormDataContentDisposition;
|
||||
import com.sun.jersey.multipart.FormDataBodyPart;
|
||||
import com.sun.jersey.multipart.FormDataParam;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.core.service.ImageUtils;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.client.exception.ImageNotFoundException;
|
||||
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||
import java.io.InputStream;
|
||||
|
||||
@Path("/clients/{clientId}/images")
|
||||
/**
|
||||
* TODO Vishwas need to change the url to entity/entityId/images to make the
|
||||
* image management API's generic for other entities like staff etc
|
||||
**/
|
||||
@Path("{clients}/{clientId}/images")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class ClientImagesApiResource {
|
||||
public class ImagesApiResource {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final ClientReadPlatformService clientReadPlatformService;
|
||||
private final ClientWritePlatformService clientWritePlatformService;
|
||||
private final ImageReadPlatformService imageReadPlatformService;
|
||||
private final ImageWritePlatformService imageWritePlatformService;
|
||||
private final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer;
|
||||
private final static Logger logger = LoggerFactory.getLogger(ClientImagesApiResource.class);
|
||||
|
||||
@Autowired
|
||||
public ClientImagesApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
|
||||
final ClientWritePlatformService clientWritePlatformService, final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer) {
|
||||
public ImagesApiResource(final PlatformSecurityContext context, final ImageReadPlatformService readPlatformService,
|
||||
final ImageWritePlatformService imageWritePlatformService, final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer) {
|
||||
this.context = context;
|
||||
this.clientReadPlatformService = readPlatformService;
|
||||
this.clientWritePlatformService = clientWritePlatformService;
|
||||
this.imageReadPlatformService = readPlatformService;
|
||||
this.imageWritePlatformService = imageWritePlatformService;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
}
|
||||
|
||||
@@ -64,10 +76,10 @@ public class ClientImagesApiResource {
|
||||
// TODO: vishwas might need more advances validation (like reading magic
|
||||
// number) for handling malicious clients
|
||||
// and clients not setting mime type
|
||||
ImageUtils.validateClientImageNotEmpty(fileDetails.getFileName());
|
||||
ImageUtils.validateImageMimeType(bodyPart.getMediaType().toString());
|
||||
ContentRepositoryUtils.validateClientImageNotEmpty(fileDetails.getFileName());
|
||||
ContentRepositoryUtils.validateImageMimeType(bodyPart.getMediaType().toString());
|
||||
|
||||
final CommandProcessingResult result = this.clientWritePlatformService.saveOrUpdateClientImage(clientId, fileDetails.getFileName(),
|
||||
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateClientImage(clientId, fileDetails.getFileName(),
|
||||
inputStream, fileSize);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
@@ -81,9 +93,9 @@ public class ClientImagesApiResource {
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String addNewClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) {
|
||||
|
||||
final Base64EncodedImage base64EncodedImage = ImageUtils.extractImageFromDataURL(jsonRequestBody);
|
||||
final Base64EncodedImage base64EncodedImage = ContentRepositoryUtils.extractImageFromDataURL(jsonRequestBody);
|
||||
|
||||
final CommandProcessingResult result = this.clientWritePlatformService.saveOrUpdateClientImage(clientId, base64EncodedImage);
|
||||
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateClientImage(clientId, base64EncodedImage);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
@@ -98,19 +110,17 @@ public class ClientImagesApiResource {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||
|
||||
final ClientData clientData = this.clientReadPlatformService.retrieveOne(clientId);
|
||||
|
||||
if (clientData.imageKeyDoesNotExist()) { throw new ImageNotFoundException("clients", clientId); }
|
||||
final ImageData imageData = this.imageReadPlatformService.retrieveClientImage(clientId);
|
||||
|
||||
// TODO: Need a better way of determining image type
|
||||
String imageDataURISuffix = ImageUtils.IMAGE_DATA_URI_SUFFIX.JPEG.getValue();
|
||||
if (StringUtils.endsWith(clientData.imageKey(), ImageUtils.IMAGE_FILE_EXTENSION.GIF.getValue())) {
|
||||
imageDataURISuffix = ImageUtils.IMAGE_DATA_URI_SUFFIX.GIF.getValue();
|
||||
} else if (StringUtils.endsWith(clientData.imageKey(), ImageUtils.IMAGE_FILE_EXTENSION.PNG.getValue())) {
|
||||
imageDataURISuffix = ImageUtils.IMAGE_DATA_URI_SUFFIX.PNG.getValue();
|
||||
String imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.JPEG.getValue();
|
||||
if (StringUtils.endsWith(imageData.location(), ContentRepositoryUtils.IMAGE_FILE_EXTENSION.GIF.getValue())) {
|
||||
imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.GIF.getValue();
|
||||
} else if (StringUtils.endsWith(imageData.location(), ContentRepositoryUtils.IMAGE_FILE_EXTENSION.PNG.getValue())) {
|
||||
imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.PNG.getValue();
|
||||
}
|
||||
|
||||
String clientImageAsBase64Text = imageDataURISuffix + Base64.encodeBytes(clientData.image());
|
||||
String clientImageAsBase64Text = imageDataURISuffix + Base64.encodeBytes(imageData.getContent());
|
||||
return clientImageAsBase64Text;
|
||||
}
|
||||
|
||||
@@ -120,16 +130,15 @@ public class ClientImagesApiResource {
|
||||
public Response downloadClientImage(@PathParam("clientId") final Long clientId) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||
final ClientData clientData = this.clientReadPlatformService.retrieveOne(clientId);
|
||||
final ImageData imageData = this.imageReadPlatformService.retrieveClientImage(clientId);
|
||||
|
||||
if (clientData.imageKeyDoesNotExist()) { throw new ImageNotFoundException("clients", clientId); }
|
||||
|
||||
ResponseBuilder response = Response.ok(clientData.image());
|
||||
response.header("Content-Disposition", "attachment; filename=\"" + clientData.imageName() + "\"");
|
||||
ResponseBuilder response = Response.ok(imageData.getContent());
|
||||
response.header("Content-Disposition", "attachment; filename=\"" + imageData.getEntityDisplayName() + IMAGE_FILE_EXTENSION.JPEG
|
||||
+ "\"");
|
||||
|
||||
// TODO: Need a better way of determining image type
|
||||
|
||||
response.header("Content-Type", clientData.imageContentType());
|
||||
response.header("Content-Type", imageData.contentType());
|
||||
return response.build();
|
||||
}
|
||||
|
||||
@@ -163,7 +172,7 @@ public class ClientImagesApiResource {
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteClientImage(@PathParam("clientId") final Long clientId) {
|
||||
this.clientWritePlatformService.deleteClientImage(clientId);
|
||||
this.imageWritePlatformService.deleteClientImage(clientId);
|
||||
return this.toApiJsonSerializer.serialize(new CommandProcessingResult(clientId));
|
||||
}
|
||||
|
||||
+9
-10
@@ -5,8 +5,6 @@
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.documentmanagement.command;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreType;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -24,9 +22,9 @@ public class DocumentCommand {
|
||||
private Long size;
|
||||
private String type;
|
||||
private String location;
|
||||
private Integer storageType;
|
||||
|
||||
private final Set<String> modifiedParameters;
|
||||
private DocumentStoreType storageType;
|
||||
|
||||
public DocumentCommand(final Set<String> modifiedParameters, final Long id, final String parentEntityType, final Long parentEntityId,
|
||||
final String name, final String fileName, final Long size, final String type, final String description, final String location) {
|
||||
@@ -98,6 +96,14 @@ public class DocumentCommand {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Integer getStorageType() {
|
||||
return this.storageType;
|
||||
}
|
||||
|
||||
public void setStorageType(Integer storageType) {
|
||||
this.storageType = storageType;
|
||||
}
|
||||
|
||||
public boolean isNameChanged() {
|
||||
return this.modifiedParameters.contains("name");
|
||||
}
|
||||
@@ -122,11 +128,4 @@ public class DocumentCommand {
|
||||
return this.modifiedParameters.contains("location");
|
||||
}
|
||||
|
||||
public void setStorageType(DocumentStoreType storageType) {
|
||||
this.storageType = storageType;
|
||||
}
|
||||
|
||||
public String getStorageType(){
|
||||
return storageType.getValue();
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package org.mifosplatform.infrastructure.documentmanagement.contentrepository;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||
|
||||
public interface ContentRepository {
|
||||
|
||||
public StorageType type = null;
|
||||
|
||||
// TODO:Vishwas Need to move these settings to the Database
|
||||
public static final Integer MAX_FILE_UPLOAD_SIZE_IN_MB = 5;
|
||||
|
||||
// TODO:Vishwas Need to move these settings to the Database
|
||||
public static final Integer MAX_IMAGE_UPLOAD_SIZE_IN_MB = 1;
|
||||
|
||||
public abstract String saveFile(InputStream uploadedInputStream, DocumentCommand documentCommand);
|
||||
|
||||
public abstract void deleteFile(String fileName, String documentPath);
|
||||
|
||||
public abstract FileData fetchFile(DocumentData documentData);
|
||||
|
||||
public abstract String saveImage(InputStream uploadedInputStream, Long resourceId, String imageName, Long fileSize);
|
||||
|
||||
public abstract String saveImage(Base64EncodedImage base64EncodedImage, Long resourceId, String imageName);
|
||||
|
||||
public abstract void deleteImage(final Long resourceId, final String location);
|
||||
|
||||
public abstract ImageData fetchImage(ImageData imageData);
|
||||
|
||||
public abstract StorageType getStorageType();
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package org.mifosplatform.infrastructure.documentmanagement.contentrepository;
|
||||
|
||||
import org.mifosplatform.infrastructure.configuration.data.S3CredentialsData;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesReadPlatformService;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ContentRepositoryFactory {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
private ExternalServicesReadPlatformService externalServicesReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public ContentRepositoryFactory(final ApplicationContext applicationContext,
|
||||
final ExternalServicesReadPlatformService externalServicesReadPlatformService) {
|
||||
this.applicationContext = applicationContext;
|
||||
this.externalServicesReadPlatformService = externalServicesReadPlatformService;
|
||||
}
|
||||
|
||||
public ContentRepository getRepository() {
|
||||
ConfigurationDomainService configurationDomainServiceJpa = applicationContext.getBean("configurationDomainServiceJpa",
|
||||
ConfigurationDomainService.class);
|
||||
if (configurationDomainServiceJpa.isAmazonS3Enabled()) { return createS3DocumentStore(); }
|
||||
return new FileSystemContentRepository();
|
||||
}
|
||||
|
||||
public ContentRepository getRepository(StorageType documentStoreType) {
|
||||
if (documentStoreType == StorageType.FILE_SYSTEM) { return new FileSystemContentRepository(); }
|
||||
return createS3DocumentStore();
|
||||
}
|
||||
|
||||
private ContentRepository createS3DocumentStore() {
|
||||
S3CredentialsData s3CredentialsData = externalServicesReadPlatformService.getS3Credentials();
|
||||
return new S3ContentRepository(s3CredentialsData.getBucketName(), s3CredentialsData.getSecretKey(),
|
||||
s3CredentialsData.getAccessKey());
|
||||
}
|
||||
}
|
||||
+48
-9
@@ -1,4 +1,8 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
package org.mifosplatform.infrastructure.documentmanagement.contentrepository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
@@ -6,11 +10,11 @@ import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.core.exception.ImageDataURLNotValidException;
|
||||
import org.mifosplatform.infrastructure.core.exception.ImageUploadException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.ContentManagementException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
public class ContentRepositoryUtils {
|
||||
|
||||
public class ImageUtils {
|
||||
public static Random random = new Random();
|
||||
|
||||
public static enum IMAGE_MIME_TYPE {
|
||||
GIF("image/gif"), JPEG("image/jpeg"), PNG("image/png");
|
||||
@@ -54,21 +58,20 @@ public class ImageUtils {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that passed in Mime type maps to known image mime types
|
||||
*
|
||||
*
|
||||
* @param mimeType
|
||||
*/
|
||||
public static void validateImageMimeType(String mimeType) {
|
||||
if (!(mimeType.equalsIgnoreCase(IMAGE_MIME_TYPE.GIF.getValue()) || mimeType.equalsIgnoreCase(IMAGE_MIME_TYPE.JPEG.getValue()) || mimeType
|
||||
.equalsIgnoreCase(IMAGE_MIME_TYPE.PNG.getValue()))) {
|
||||
throw new ImageUploadException();
|
||||
}
|
||||
.equalsIgnoreCase(IMAGE_MIME_TYPE.PNG.getValue()))) { throw new ImageUploadException(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts Image from a Data URL
|
||||
*
|
||||
*
|
||||
* @param mimeType
|
||||
*/
|
||||
public static Base64EncodedImage extractImageFromDataURL(String dataURL) {
|
||||
@@ -90,6 +93,17 @@ public class ImageUtils {
|
||||
return new Base64EncodedImage(base64EncodedString, fileExtension);
|
||||
}
|
||||
|
||||
public static void validateFileSizeWithinPermissibleRange(Long fileSize, String name) {
|
||||
/**
|
||||
* Using Content-Length gives me size of the entire request, which is
|
||||
* good enough for now for a fast fail as the length of the rest of the
|
||||
* content i.e name and description while compared to the uploaded file
|
||||
* size is negligible
|
||||
**/
|
||||
if (fileSize != null && ((fileSize / (1024 * 1024)) > ContentRepository.MAX_FILE_UPLOAD_SIZE_IN_MB)) { throw new ContentManagementException(
|
||||
name, fileSize, ContentRepository.MAX_FILE_UPLOAD_SIZE_IN_MB); }
|
||||
}
|
||||
|
||||
public static void validateClientImageNotEmpty(String imageFileName) {
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
if (imageFileName == null) {
|
||||
@@ -102,4 +116,29 @@ public class ImageUtils {
|
||||
dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random String
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String generateRandomString() {
|
||||
String characters = "abcdefghijklmnopqrstuvwxyz123456789";
|
||||
int length = generateRandomNumber();
|
||||
char[] text = new char[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
text[i] = characters.charAt(random.nextInt(characters.length()));
|
||||
}
|
||||
return new String(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random number between 5 to 16
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int generateRandomNumber() {
|
||||
Random randomGenerator = new Random();
|
||||
return randomGenerator.nextInt(11) + 5;
|
||||
}
|
||||
}
|
||||
+44
-40
@@ -3,57 +3,63 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
package org.mifosplatform.infrastructure.documentmanagement.contentrepository;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.lowagie.text.pdf.codec.Base64;
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
||||
import org.mifosplatform.portfolio.client.data.ImageData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.ContentManagementException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import com.lowagie.text.pdf.codec.Base64;
|
||||
|
||||
public class FileSystemDocumentStore extends DocumentStore {
|
||||
public class FileSystemContentRepository implements ContentRepository {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(FileSystemDocumentStore.class);
|
||||
private final static Logger logger = LoggerFactory.getLogger(FileSystemContentRepository.class);
|
||||
|
||||
public static final String MIFOSX_BASE_DIR = System.getProperty("user.home") + File.separator + ".mifosx";
|
||||
|
||||
|
||||
@Override
|
||||
public String saveDocument(InputStream uploadedInputStream, DocumentCommand documentCommand) throws DocumentManagementException {
|
||||
String documentName = documentCommand.getFileName();
|
||||
String uploadDocumentLocation = generateFileParentDirectory(documentCommand.getParentEntityType(), documentCommand.getParentEntityId());
|
||||
public String saveFile(InputStream uploadedInputStream, DocumentCommand documentCommand) {
|
||||
String fileName = documentCommand.getFileName();
|
||||
String uploadDocumentLocation = generateFileParentDirectory(documentCommand.getParentEntityType(),
|
||||
documentCommand.getParentEntityId());
|
||||
|
||||
validateFileSizeWithinPermissibleRange(documentCommand.getSize(), documentName, maxFileSize);
|
||||
ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(documentCommand.getSize(), fileName);
|
||||
makeDirectories(uploadDocumentLocation);
|
||||
|
||||
String fileLocation = uploadDocumentLocation + File.separator + documentName;
|
||||
String fileLocation = uploadDocumentLocation + File.separator + fileName;
|
||||
|
||||
writeFileToFileSystem(uploadedInputStream, fileLocation);
|
||||
writeFileToFileSystem(fileName, uploadedInputStream, fileLocation);
|
||||
return fileLocation;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String saveImage(InputStream uploadedInputStream, Long resourceId, String imageName, Long fileSize) throws DocumentManagementException {
|
||||
public String saveImage(InputStream uploadedInputStream, Long resourceId, String imageName, Long fileSize) {
|
||||
String uploadImageLocation = generateClientImageParentDirectory(resourceId);
|
||||
|
||||
validateFileSizeWithinPermissibleRange(fileSize, imageName, maxImageSize);
|
||||
ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(fileSize, imageName);
|
||||
makeDirectories(uploadImageLocation);
|
||||
|
||||
String fileLocation = uploadImageLocation + File.separator + imageName;
|
||||
|
||||
writeFileToFileSystem(uploadedInputStream, fileLocation);
|
||||
writeFileToFileSystem(imageName, uploadedInputStream, fileLocation);
|
||||
return fileLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveImage(Base64EncodedImage base64EncodedImage, Long resourceId, String imageName) throws DocumentManagementException {
|
||||
public String saveImage(Base64EncodedImage base64EncodedImage, Long resourceId, String imageName) {
|
||||
String uploadImageLocation = generateClientImageParentDirectory(resourceId);
|
||||
|
||||
makeDirectories(uploadImageLocation);
|
||||
@@ -65,8 +71,8 @@ public class FileSystemDocumentStore extends DocumentStore {
|
||||
out.write(imgBytes);
|
||||
out.flush();
|
||||
out.close();
|
||||
}catch (IOException ioe){
|
||||
throw new DocumentManagementException(ioe.getMessage());
|
||||
} catch (IOException ioe) {
|
||||
throw new ContentManagementException(imageName, ioe.getMessage());
|
||||
}
|
||||
return fileLocation;
|
||||
}
|
||||
@@ -81,9 +87,9 @@ public class FileSystemDocumentStore extends DocumentStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDocument(String documentName, String documentPath) throws DocumentManagementException{
|
||||
public void deleteFile(String fileName, String documentPath) {
|
||||
final boolean fileDeleted = deleteFile(documentPath);
|
||||
if (!fileDeleted) { throw new DocumentManagementException(documentName); }
|
||||
if (!fileDeleted) { throw new ContentManagementException(fileName, null); }
|
||||
}
|
||||
|
||||
private boolean deleteFile(String documentPath) {
|
||||
@@ -92,42 +98,43 @@ public class FileSystemDocumentStore extends DocumentStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocumentStoreType getType() {
|
||||
return DocumentStoreType.FILE_SYSTEM;
|
||||
public StorageType getStorageType() {
|
||||
return StorageType.FILE_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileData retrieveDocument(DocumentData documentData){
|
||||
public FileData fetchFile(DocumentData documentData) {
|
||||
File file = new File(documentData.fileLocation());
|
||||
return new FileData(file, documentData.fileName(), documentData.contentType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageData retrieveImage(ImageData imageData) {
|
||||
File file = new File(imageData.imageKey());
|
||||
imageData.setContent(file);
|
||||
public ImageData fetchImage(ImageData imageData) {
|
||||
File file = new File(imageData.location());
|
||||
imageData.updateContent(file);
|
||||
return imageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the directory path for storing the new document
|
||||
*
|
||||
*
|
||||
* @param entityType
|
||||
* @param entityId
|
||||
* @return
|
||||
*/
|
||||
private String generateFileParentDirectory(String entityType, Long entityId) {
|
||||
return FileSystemDocumentStore.MIFOSX_BASE_DIR + File.separator + ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim()
|
||||
+ File.separator + "documents" + File.separator + entityType + File.separator + entityId + File.separator
|
||||
+ RandomStringGenerator.generateRandomString();
|
||||
return FileSystemContentRepository.MIFOSX_BASE_DIR + File.separator
|
||||
+ ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim() + File.separator + "documents" + File.separator
|
||||
+ entityType + File.separator + entityId + File.separator + ContentRepositoryUtils.generateRandomString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate directory path for storing new Image
|
||||
*/
|
||||
private String generateClientImageParentDirectory(final Long resourceId) {
|
||||
return FileSystemDocumentStore.MIFOSX_BASE_DIR + File.separator + ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim()
|
||||
+ File.separator + "images" + File.separator + "clients" + File.separator + resourceId;
|
||||
return FileSystemContentRepository.MIFOSX_BASE_DIR + File.separator
|
||||
+ ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim() + File.separator + "images" + File.separator
|
||||
+ "clients" + File.separator + resourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,9 +146,7 @@ public class FileSystemDocumentStore extends DocumentStore {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void writeFileToFileSystem(InputStream uploadedInputStream, String fileLocation) throws DocumentManagementException {
|
||||
|
||||
private void writeFileToFileSystem(String fileName, InputStream uploadedInputStream, String fileLocation) {
|
||||
try {
|
||||
OutputStream out = new FileOutputStream(new File(fileLocation));
|
||||
int read = 0;
|
||||
@@ -153,8 +158,7 @@ public class FileSystemDocumentStore extends DocumentStore {
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException ioException) {
|
||||
throw new DocumentManagementException("IO Exception caught while writing to FileSystem" + ioException.getMessage());
|
||||
throw new ContentManagementException(fileName, ioException.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
package org.mifosplatform.infrastructure.documentmanagement.contentrepository;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.ContentManagementException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.amazonaws.AmazonClientException;
|
||||
import com.amazonaws.AmazonServiceException;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.services.s3.AmazonS3;
|
||||
import com.amazonaws.services.s3.AmazonS3Client;
|
||||
import com.amazonaws.services.s3.model.DeleteObjectRequest;
|
||||
import com.amazonaws.services.s3.model.GetObjectRequest;
|
||||
import com.amazonaws.services.s3.model.ObjectMetadata;
|
||||
import com.amazonaws.services.s3.model.PutObjectRequest;
|
||||
import com.amazonaws.services.s3.model.S3Object;
|
||||
import com.lowagie.text.pdf.codec.Base64;
|
||||
|
||||
public class S3ContentRepository implements ContentRepository {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(S3ContentRepository.class);
|
||||
|
||||
private final String s3BucketName;
|
||||
private AmazonS3 s3Client;
|
||||
|
||||
public S3ContentRepository(String bucketName, String secretKey, String accessKey) {
|
||||
this.s3BucketName = bucketName;
|
||||
this.s3Client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveFile(InputStream toUpload, DocumentCommand documentCommand) {
|
||||
String fileName = documentCommand.getFileName();
|
||||
ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(documentCommand.getSize(), fileName);
|
||||
|
||||
String uploadDocFolder = generateFileParentDirectory(documentCommand.getParentEntityType(), documentCommand.getParentEntityId());
|
||||
String uploadDocFullPath = uploadDocFolder + File.separator + fileName;
|
||||
|
||||
uploadDocument(fileName, toUpload, uploadDocFullPath);
|
||||
return uploadDocFullPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFile(String documentName, String documentPath) {
|
||||
try {
|
||||
deleteObjectFromS3(documentPath);
|
||||
} catch (AmazonClientException ace) {
|
||||
throw new ContentManagementException(documentName, ace.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveImage(InputStream toUploadInputStream, Long resourceId, String imageName, Long fileSize) {
|
||||
ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(fileSize, imageName);
|
||||
String uploadImageLocation = generateClientImageParentDirectory(resourceId);
|
||||
String fileLocation = uploadImageLocation + File.separator + imageName;
|
||||
|
||||
uploadDocument(imageName, toUploadInputStream, fileLocation);
|
||||
return fileLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveImage(Base64EncodedImage base64EncodedImage, Long resourceId, String imageName) {
|
||||
String uploadImageLocation = generateClientImageParentDirectory(resourceId);
|
||||
String fileLocation = uploadImageLocation + File.separator + imageName + base64EncodedImage.getFileExtension();
|
||||
InputStream toUploadInputStream = new ByteArrayInputStream(Base64.decode(base64EncodedImage.getBase64EncodedString()));
|
||||
|
||||
uploadDocument(imageName, toUploadInputStream, fileLocation);
|
||||
return fileLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteImage(Long resourceId, String location) {
|
||||
try {
|
||||
deleteObjectFromS3(location);
|
||||
} catch (AmazonServiceException ase) {
|
||||
deleteObjectAmazonServiceExceptionMessage(ase);
|
||||
logger.warn("Unable to delete image associated with clients with Id " + resourceId);
|
||||
} catch (AmazonClientException ace) {
|
||||
deleteObjectAmazonClientExceptionMessage(ace);
|
||||
logger.warn("Unable to delete image associated with clients with Id " + resourceId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageType getStorageType() {
|
||||
return StorageType.S3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileData fetchFile(DocumentData documentData) throws DocumentNotFoundException {
|
||||
FileData fileData = null;
|
||||
String fileName = documentData.fileName();
|
||||
try {
|
||||
logger.info("Downloading an object");
|
||||
S3Object s3object = s3Client.getObject(new GetObjectRequest(s3BucketName, documentData.fileLocation()));
|
||||
fileData = new FileData(s3object.getObjectContent(), fileName, documentData.contentType());
|
||||
} catch (AmazonClientException ace) {
|
||||
logger.error(ace.getMessage());
|
||||
throw new DocumentNotFoundException(documentData.getParentEntityType(), documentData.getParentEntityId(), documentData.getId());
|
||||
}
|
||||
return fileData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageData fetchImage(ImageData imageData) {
|
||||
S3Object s3object = s3Client.getObject(new GetObjectRequest(s3BucketName, imageData.location()));
|
||||
imageData.updateContent(s3object.getObjectContent());
|
||||
return imageData;
|
||||
}
|
||||
|
||||
private void deleteObjectAmazonClientExceptionMessage(AmazonClientException ace) {
|
||||
String message = "Caught an AmazonClientException." + "Error Message: " + ace.getMessage();
|
||||
logger.error(message);
|
||||
}
|
||||
|
||||
private void deleteObjectAmazonServiceExceptionMessage(AmazonServiceException ase) {
|
||||
String message = "Caught an AmazonServiceException." + "Error Message: " + ase.getMessage() + "HTTP Status Code: "
|
||||
+ ase.getStatusCode() + "AWS Error Code: " + ase.getErrorCode() + "Error Type: " + ase.getErrorType()
|
||||
+ "Request ID: " + ase.getRequestId();
|
||||
logger.error(message);
|
||||
}
|
||||
|
||||
private String generateFileParentDirectory(String entityType, Long entityId) {
|
||||
return "documents" + File.separator + entityType + File.separator + entityId + File.separator
|
||||
+ ContentRepositoryUtils.generateRandomString();
|
||||
}
|
||||
|
||||
private String generateClientImageParentDirectory(Long resourceId) {
|
||||
return "images" + File.separator + "clients" + File.separator + resourceId;
|
||||
}
|
||||
|
||||
private void deleteObjectFromS3(String location) {
|
||||
s3Client.deleteObject(new DeleteObjectRequest(s3BucketName, location));
|
||||
}
|
||||
|
||||
private void uploadDocument(String filename, InputStream inputStream, String s3UploadLocation) throws ContentManagementException {
|
||||
try {
|
||||
logger.info("Uploading a new object to S3 from a file to " + s3UploadLocation);
|
||||
s3Client.putObject(new PutObjectRequest(this.s3BucketName, s3UploadLocation, inputStream, new ObjectMetadata()));
|
||||
} catch (AmazonClientException ace) {
|
||||
String message = ace.getMessage();
|
||||
throw new ContentManagementException(filename, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-18
@@ -5,19 +5,15 @@
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.documentmanagement.data;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStore;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreType;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||
|
||||
/**
|
||||
* Immutable data object represent document being managed on platform.
|
||||
*/
|
||||
public class DocumentData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long id;
|
||||
@SuppressWarnings("unused")
|
||||
private final String parentEntityType;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long parentEntityId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String name;
|
||||
@@ -27,12 +23,11 @@ public class DocumentData {
|
||||
private final String type;
|
||||
@SuppressWarnings("unused")
|
||||
private final String description;
|
||||
private String location;
|
||||
|
||||
private String storageType;
|
||||
private final String location;
|
||||
private final Integer storageType;
|
||||
|
||||
public DocumentData(final Long id, final String parentEntityType, final Long parentEntityId, final String name, final String fileName,
|
||||
final Long size, final String type, final String description, final String location, String storageType) {
|
||||
final Long size, final String type, final String description, final String location, Integer storageType) {
|
||||
this.id = id;
|
||||
this.parentEntityType = parentEntityType;
|
||||
this.parentEntityId = parentEntityId;
|
||||
@@ -57,23 +52,19 @@ public class DocumentData {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public void setLocation(final String location) {
|
||||
this.location = location;
|
||||
public StorageType storageType() {
|
||||
return StorageType.fromInt(storageType);
|
||||
}
|
||||
|
||||
public DocumentStoreType storeType(){
|
||||
return DocumentStore.getDocumentStoreType(storageType);
|
||||
}
|
||||
|
||||
public String getParentEntityType(){
|
||||
public String getParentEntityType() {
|
||||
return this.parentEntityType;
|
||||
}
|
||||
|
||||
public Long getParentEntityId(){
|
||||
public Long getParentEntityId() {
|
||||
return this.parentEntityId;
|
||||
}
|
||||
|
||||
public Long getId(){
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
|
||||
+6
-11
@@ -9,6 +9,7 @@ import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class FileData {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FileData.class);
|
||||
|
||||
private final File file;
|
||||
@@ -38,19 +39,13 @@ public class FileData {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public InputStream file(){
|
||||
try{
|
||||
if(inputStream == null){
|
||||
return new FileInputStream(file);
|
||||
}
|
||||
else {
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException e){
|
||||
public InputStream file() {
|
||||
try {
|
||||
if (inputStream == null) { return new FileInputStream(file); }
|
||||
return inputStream;
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.error(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package org.mifosplatform.infrastructure.documentmanagement.data;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||
|
||||
public class ImageData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long imageId;
|
||||
private final String location;
|
||||
private final Integer storageType;
|
||||
private final String entityDisplayName;
|
||||
|
||||
private File file;
|
||||
private String contentType;
|
||||
private InputStream inputStream;
|
||||
|
||||
public ImageData(Long imageId, String location, Integer storageType, String entityDisplayName) {
|
||||
this.imageId = imageId;
|
||||
this.location = location;
|
||||
this.storageType = storageType;
|
||||
this.entityDisplayName = entityDisplayName;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
// TODO Vishwas Fix error handling
|
||||
try {
|
||||
if (inputStream == null) {
|
||||
FileInputStream fileInputStream = new FileInputStream(file);
|
||||
return IOUtils.toByteArray(fileInputStream);
|
||||
}
|
||||
|
||||
return IOUtils.toByteArray(inputStream);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String setImageContentType() {
|
||||
String contentType = ContentRepositoryUtils.IMAGE_MIME_TYPE.JPEG.getValue();
|
||||
|
||||
if (file != null) {
|
||||
String fileName = file.getName();
|
||||
|
||||
if (StringUtils.endsWith(fileName, ContentRepositoryUtils.IMAGE_FILE_EXTENSION.GIF.getValue())) {
|
||||
contentType = ContentRepositoryUtils.IMAGE_MIME_TYPE.GIF.getValue();
|
||||
} else if (StringUtils.endsWith(fileName, ContentRepositoryUtils.IMAGE_FILE_EXTENSION.PNG.getValue())) {
|
||||
contentType = ContentRepositoryUtils.IMAGE_MIME_TYPE.PNG.getValue();
|
||||
}
|
||||
}
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public String contentType() {
|
||||
return this.contentType;
|
||||
}
|
||||
|
||||
public StorageType storageType() {
|
||||
return StorageType.fromInt(storageType);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.file.getName();
|
||||
}
|
||||
|
||||
public String location() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public void updateContent(InputStream objectContent) {
|
||||
this.inputStream = objectContent;
|
||||
}
|
||||
|
||||
public void updateContent(File file) {
|
||||
this.file = file;
|
||||
setImageContentType();
|
||||
}
|
||||
|
||||
public String getEntityDisplayName() {
|
||||
return this.entityDisplayName;
|
||||
}
|
||||
|
||||
}
|
||||
+11
-15
@@ -5,16 +5,14 @@
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.documentmanagement.domain;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStore;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreType;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_document")
|
||||
public class Document extends AbstractPersistable<Long> {
|
||||
@@ -43,19 +41,18 @@ public class Document extends AbstractPersistable<Long> {
|
||||
@Column(name = "location", length = 500)
|
||||
private String location;
|
||||
|
||||
@Column(name = "storage_type", length = 50)
|
||||
private String storageType;
|
||||
@Column(name = "storage_type_enum")
|
||||
private Integer storageType;
|
||||
|
||||
public Document() {
|
||||
}
|
||||
public Document() {}
|
||||
|
||||
public static Document createNew(final String parentEntityType, final Long parentEntityId, final String name, final String fileName,
|
||||
final Long size, final String type, final String description, final String location, final DocumentStoreType storageType) {
|
||||
final Long size, final String type, final String description, final String location, final StorageType storageType) {
|
||||
return new Document(parentEntityType, parentEntityId, name, fileName, size, type, description, location, storageType);
|
||||
}
|
||||
|
||||
private Document(final String parentEntityType, final Long parentEntityId, final String name, final String fileName, final Long size,
|
||||
final String type, final String description, final String location, final DocumentStoreType storageType) {
|
||||
final String type, final String description, final String location, final StorageType storageType) {
|
||||
this.parentEntityType = StringUtils.defaultIfEmpty(parentEntityType, null);
|
||||
this.parentEntityId = parentEntityId;
|
||||
this.name = StringUtils.defaultIfEmpty(name, null);
|
||||
@@ -86,7 +83,6 @@ public class Document extends AbstractPersistable<Long> {
|
||||
if (command.isSizeChanged()) {
|
||||
this.size = command.getSize();
|
||||
}
|
||||
this.storageType = command.getStorageType();
|
||||
}
|
||||
|
||||
public String getParentEntityType() {
|
||||
@@ -153,7 +149,7 @@ public class Document extends AbstractPersistable<Long> {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public DocumentStoreType storageType(){
|
||||
return DocumentStore.getDocumentStoreType(this.storageType);
|
||||
public StorageType storageType() {
|
||||
return StorageType.fromInt(this.storageType);
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.documentmanagement.domain;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_image")
|
||||
public final class Image extends AbstractPersistable<Long> {
|
||||
|
||||
@Column(name = "location", length = 500)
|
||||
private String location;
|
||||
|
||||
@Column(name = "storage_type_enum")
|
||||
private Integer storageType;
|
||||
|
||||
public Image(String location, StorageType storageType) {
|
||||
this.location = location;
|
||||
this.storageType = storageType.getValue();
|
||||
}
|
||||
|
||||
protected Image() {
|
||||
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public Integer getStorageType() {
|
||||
return this.storageType;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public void setStorageType(Integer storageType) {
|
||||
this.storageType = storageType;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-4
@@ -3,11 +3,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
package org.mifosplatform.infrastructure.documentmanagement.domain;
|
||||
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface ImageRepository extends JpaRepository<Image, Long>, JpaSpecificationExecutor<Client> {
|
||||
Image findOneByClient(Client client);
|
||||
}
|
||||
public interface ImageRepository extends JpaRepository<Image, Long>, JpaSpecificationExecutor<Client> {}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package org.mifosplatform.infrastructure.documentmanagement.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum StorageType {
|
||||
FILE_SYSTEM(1), S3(2);
|
||||
|
||||
private Integer value;
|
||||
|
||||
StorageType(Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private static final Map<Integer, StorageType> intToEnumMap = new HashMap<Integer, StorageType>();
|
||||
static {
|
||||
for (final StorageType type : StorageType.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static StorageType fromInt(final int i) {
|
||||
final StorageType type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -7,13 +7,14 @@ package org.mifosplatform.infrastructure.documentmanagement.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
public class DocumentManagementException extends AbstractPlatformDomainRuleException {
|
||||
public class ContentManagementException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public DocumentManagementException(final String name) {
|
||||
super("error.msg.document.save", "Error while manipulating file " + name + " due to a File system / Amazon S3 issue", name);
|
||||
public ContentManagementException(final String filename, final String message) {
|
||||
super("error.msg.document.save",
|
||||
"Error while manipulating file " + filename + " due to a File system / Amazon S3 issue " + message, filename, message);
|
||||
}
|
||||
|
||||
public DocumentManagementException(final String name, final Long fileSize, final int maxFileSize) {
|
||||
public ContentManagementException(final String name, final Long fileSize, final int maxFileSize) {
|
||||
super("error.msg.document.file.too.big", "Unable to save the document with name" + name + " since its file Size of " + fileSize
|
||||
/ (1024 * 1024) + " MB exceeds the max permissable file size of " + maxFileSize + " MB", name, fileSize);
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@ public interface DocumentReadPlatformService {
|
||||
|
||||
Collection<DocumentData> retrieveAllDocuments(String entityType, Long entityId);
|
||||
|
||||
FileData retrieveDocumentAsFile(String entityType, Long entityId, Long documentId);
|
||||
FileData retrieveFileData(String entityType, Long entityId, Long documentId);
|
||||
|
||||
DocumentData retrieveDocument(String entityType, Long entityId, Long documentId);
|
||||
|
||||
|
||||
+36
-30
@@ -6,9 +6,9 @@
|
||||
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStore;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreFactory;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||
@@ -28,14 +28,14 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final PlatformSecurityContext context;
|
||||
private final DocumentStoreFactory documentStoreFactory;
|
||||
private final ContentRepositoryFactory contentRepositoryFactory;
|
||||
|
||||
@Autowired
|
||||
public DocumentReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
||||
final DocumentStoreFactory documentStoreFactory) {
|
||||
final ContentRepositoryFactory documentStoreFactory) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.documentStoreFactory = documentStoreFactory;
|
||||
this.contentRepositoryFactory = documentStoreFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,46 +46,60 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
|
||||
// TODO verify if the entities are valid and a user
|
||||
// has data
|
||||
// scope for the particular entities
|
||||
final DocumentMapper mapper = new DocumentMapper(true);
|
||||
final DocumentMapper mapper = new DocumentMapper(true, true);
|
||||
final String sql = "select " + mapper.schema() + " order by d.id";
|
||||
return this.jdbcTemplate.query(sql, mapper, new Object[] { entityType, entityId });
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileData retrieveDocumentAsFile(final String entityType, final Long entityId, final Long documentId) {
|
||||
public FileData retrieveFileData(final String entityType, final Long entityId, final Long documentId) {
|
||||
try {
|
||||
DocumentData documentData = getDocumentData(entityType, entityId, documentId);
|
||||
DocumentStore instanceForRead = documentStoreFactory.getInstanceFromStorageType(documentData.storeType());
|
||||
return instanceForRead.retrieveDocument(documentData);
|
||||
final DocumentMapper mapper = new DocumentMapper(false, false);
|
||||
DocumentData documentData = fetchDocumentDetails(entityType, entityId, documentId, mapper);
|
||||
ContentRepository contentRepository = contentRepositoryFactory.getRepository(documentData.storageType());
|
||||
return contentRepository.fetchFile(documentData);
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
throw new DocumentNotFoundException(entityType, entityId, documentId);
|
||||
} catch (final DocumentNotFoundException d) {
|
||||
throw d;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocumentData retrieveDocument(String entityType, Long entityId, Long documentId) {
|
||||
try {
|
||||
return getDocumentData(entityType, entityId, documentId);
|
||||
final DocumentMapper mapper = new DocumentMapper(true, true);
|
||||
return fetchDocumentDetails(entityType, entityId, documentId, mapper);
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
throw new DocumentNotFoundException(entityType, entityId, documentId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityType
|
||||
* @param entityId
|
||||
* @param documentId
|
||||
* @param mapper
|
||||
* @return
|
||||
*/
|
||||
private DocumentData fetchDocumentDetails(final String entityType, final Long entityId, final Long documentId,
|
||||
final DocumentMapper mapper) {
|
||||
final String sql = "select " + mapper.schema() + " and d.id=? ";
|
||||
return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { entityType, entityId, documentId });
|
||||
}
|
||||
|
||||
private static final class DocumentMapper implements RowMapper<DocumentData> {
|
||||
|
||||
private final boolean hideLocation;
|
||||
private final boolean hideStorageType;
|
||||
|
||||
public DocumentMapper(final boolean hideLocation) {
|
||||
public DocumentMapper(final boolean hideLocation, final boolean hideStorageType) {
|
||||
this.hideLocation = hideLocation;
|
||||
this.hideStorageType = hideStorageType;
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return "d.id as id, d.parent_entity_type as parentEntityType, d.parent_entity_id as parentEntityId, d.name as name, "
|
||||
+ " d.file_name as fileName, d.size as fileSize, d.type as fileType, "
|
||||
+ " d.description as description, d.location as location,"
|
||||
+ " d.storage_type as storageType"
|
||||
+ " d.description as description, d.location as location," + " d.storage_type_enum as storageType"
|
||||
+ " from m_document d where d.parent_entity_type=? and d.parent_entity_id=?";
|
||||
}
|
||||
|
||||
@@ -101,24 +115,16 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
|
||||
final String fileType = rs.getString("fileType");
|
||||
final String description = rs.getString("description");
|
||||
String location = null;
|
||||
Integer storageType = null;
|
||||
if (!this.hideLocation) {
|
||||
location = rs.getString("location");
|
||||
}
|
||||
final String storageType = rs.getString("storageType");
|
||||
|
||||
return new DocumentData(id, parentEntityType, parentEntityId, name, fileName, fileSize, fileType, description, location, storageType);
|
||||
if (!this.hideStorageType) {
|
||||
storageType = rs.getInt("storageType");
|
||||
}
|
||||
return new DocumentData(id, parentEntityType, parentEntityId, name, fileName, fileSize, fileType, description, location,
|
||||
storageType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private DocumentData getDocumentData(String entityType, Long entityId, Long documentId) {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
// TODO verify if the entities are valid and a
|
||||
// user has data
|
||||
// scope for the particular entities
|
||||
final DocumentMapper mapper = new DocumentMapper(false);
|
||||
final String sql = "select " + mapper.schema() + " and d.id=? ";
|
||||
return this.jdbcTemplate.queryForObject(sql, mapper, new Object[]{entityType, entityId, documentId});
|
||||
}
|
||||
}
|
||||
+26
-29
@@ -5,16 +5,18 @@
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStore;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreFactory;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreType;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommandValidator;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.Document;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.DocumentRepository;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.ContentManagementException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.InvalidEntityTypeForDocumentManagementException;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
@@ -25,8 +27,6 @@ import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
@Service
|
||||
public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWritePlatformService {
|
||||
|
||||
@@ -34,14 +34,14 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final DocumentRepository documentRepository;
|
||||
private final DocumentStoreFactory documentStoreFactory;
|
||||
private final ContentRepositoryFactory contentRepositoryFactory;
|
||||
|
||||
@Autowired
|
||||
public DocumentWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final DocumentRepository documentRepository,
|
||||
final DocumentStoreFactory documentStoreFactory) {
|
||||
public DocumentWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final DocumentRepository documentRepository, final ContentRepositoryFactory documentStoreFactory) {
|
||||
this.context = context;
|
||||
this.documentRepository = documentRepository;
|
||||
this.documentStoreFactory = documentStoreFactory;
|
||||
this.contentRepositoryFactory = documentStoreFactory;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -56,13 +56,13 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
||||
|
||||
validator.validateForCreate();
|
||||
|
||||
DocumentStore documentStore = this.documentStoreFactory.getInstanceFromConfiguration();
|
||||
ContentRepository contentRepository = this.contentRepositoryFactory.getRepository();
|
||||
|
||||
final String fileLocation = documentStore.saveDocument(inputStream, documentCommand);
|
||||
final String fileLocation = contentRepository.saveFile(inputStream, documentCommand);
|
||||
|
||||
final Document document = Document.createNew(documentCommand.getParentEntityType(), documentCommand.getParentEntityId(),
|
||||
documentCommand.getName(), documentCommand.getFileName(), documentCommand.getSize(), documentCommand.getType(),
|
||||
documentCommand.getDescription(), fileLocation, documentStore.getType());
|
||||
documentCommand.getDescription(), fileLocation, contentRepository.getStorageType());
|
||||
|
||||
this.documentRepository.save(document);
|
||||
|
||||
@@ -71,9 +71,6 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
} catch (final DocumentManagementException dme) {
|
||||
logger.error(dme.getMessage(), dme);
|
||||
throw new DocumentManagementException(documentCommand.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,21 +86,22 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
||||
// TODO check if entity id is valid and within data scope for the
|
||||
// user
|
||||
final Document documentForUpdate = this.documentRepository.findOne(documentCommand.getId());
|
||||
DocumentStoreType documentStoreType = documentForUpdate.storageType();
|
||||
if (documentForUpdate == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
|
||||
documentCommand.getParentEntityId(), documentCommand.getId()); }
|
||||
|
||||
StorageType documentStoreType = documentForUpdate.storageType();
|
||||
oldLocation = documentForUpdate.getLocation();
|
||||
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
||||
DocumentStore instanceFromConfiguration = this.documentStoreFactory.getInstanceFromConfiguration();
|
||||
documentCommand.setLocation(instanceFromConfiguration.saveDocument(inputStream, documentCommand));
|
||||
documentCommand.setStorageType(instanceFromConfiguration.getType());
|
||||
ContentRepository contentRepository = this.contentRepositoryFactory.getRepository();
|
||||
documentCommand.setLocation(contentRepository.saveFile(inputStream, documentCommand));
|
||||
documentCommand.setStorageType(contentRepository.getStorageType().getValue());
|
||||
}
|
||||
|
||||
documentForUpdate.update(documentCommand);
|
||||
|
||||
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
||||
DocumentStore documentStore = this.documentStoreFactory.getInstanceFromStorageType(documentStoreType);
|
||||
documentStore.deleteDocument(documentCommand.getName(), oldLocation);
|
||||
ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(documentStoreType);
|
||||
contentRepository.deleteFile(documentCommand.getName(), oldLocation);
|
||||
}
|
||||
|
||||
this.documentRepository.saveAndFlush(documentForUpdate);
|
||||
@@ -113,9 +111,9 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
} catch (final DocumentManagementException dme) {
|
||||
logger.error(dme.getMessage(), dme);
|
||||
throw new DocumentManagementException(documentCommand.getName());
|
||||
} catch (final ContentManagementException cme) {
|
||||
logger.error(cme.getMessage(), cme);
|
||||
throw new ContentManagementException(documentCommand.getName(), cme.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,12 +125,12 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
||||
validateParentEntityType(documentCommand);
|
||||
// TODO: Check document is present under this entity Id
|
||||
final Document document = this.documentRepository.findOne(documentCommand.getId());
|
||||
DocumentStore documentStore = this.documentStoreFactory.getInstanceFromStorageType(document.storageType());
|
||||
if (document == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
|
||||
documentCommand.getParentEntityId(), documentCommand.getId()); }
|
||||
|
||||
this.documentRepository.delete(document);
|
||||
documentStore.deleteDocument(document.getName(), document.getLocation());
|
||||
|
||||
ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(document.storageType());
|
||||
contentRepository.deleteFile(document.getName(), document.getLocation());
|
||||
return new CommandProcessingResult(document.getId());
|
||||
}
|
||||
|
||||
@@ -142,7 +140,6 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
||||
}
|
||||
|
||||
private static boolean checkValidEntityType(final String entityType) {
|
||||
|
||||
for (final DOCUMENT_MANAGEMENT_ENTITY entities : DOCUMENT_MANAGEMENT_ENTITY.values()) {
|
||||
if (entities.name().equalsIgnoreCase(entityType)) { return true; }
|
||||
}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
||||
|
||||
public interface ImageReadPlatformService {
|
||||
|
||||
ImageData retrieveClientImage(Long clientId);
|
||||
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.client.exception.ImageNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ImageReadPlatformServiceImpl implements ImageReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final ContentRepositoryFactory contentRepositoryFactory;
|
||||
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
||||
|
||||
@Autowired
|
||||
public ImageReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource, final ContentRepositoryFactory documentStoreFactory,
|
||||
final ClientRepositoryWrapper clientRepositoryWrapper) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.contentRepositoryFactory = documentStoreFactory;
|
||||
this.clientRepositoryWrapper = clientRepositoryWrapper;
|
||||
}
|
||||
|
||||
private static final class ImageMapper implements RowMapper<ImageData> {
|
||||
|
||||
private final String entityDisplayName;
|
||||
|
||||
public ImageMapper(final String entityDisplayName) {
|
||||
this.entityDisplayName = entityDisplayName;
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return " image.id as id, image.location as location, image.storage_type_enum as storageType "
|
||||
+ " from m_image image , m_client client " + " where client.image_id = image.id and client.id=?";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = JdbcSupport.getLong(rs, "id");
|
||||
final String location = rs.getString("location");
|
||||
final Integer storageType = JdbcSupport.getInteger(rs, "storageType");
|
||||
return new ImageData(id, location, storageType, entityDisplayName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageData retrieveClientImage(Long clientId) {
|
||||
try {
|
||||
Client client = clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||
|
||||
final ImageMapper imageMapper = new ImageMapper(client.getDisplayName());
|
||||
|
||||
final String sql = "select " + imageMapper.schema();
|
||||
|
||||
ImageData imageData = this.jdbcTemplate.queryForObject(sql, imageMapper, new Object[] { clientId });
|
||||
ContentRepository contentRepository = contentRepositoryFactory.getRepository(imageData.storageType());
|
||||
return contentRepository.fetchImage(imageData);
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
throw new ImageNotFoundException("clients", clientId);
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
public interface ImageWritePlatformService {
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')")
|
||||
CommandProcessingResult saveOrUpdateClientImage(Long clientId, String imageName, InputStream inputStream, Long fileSize);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')")
|
||||
CommandProcessingResult saveOrUpdateClientImage(Long clientId, Base64EncodedImage encodedImage);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE')")
|
||||
CommandProcessingResult deleteClientImage(Long clientId);
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.Image;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.ImageRepository;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePlatformService {
|
||||
|
||||
private final ContentRepositoryFactory contentRepositoryFactory;
|
||||
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
||||
private final ImageRepository imageRepository;
|
||||
|
||||
@Autowired
|
||||
public ImageWritePlatformServiceJpaRepositoryImpl(final ContentRepositoryFactory documentStoreFactory,
|
||||
final ClientRepositoryWrapper clientRepositoryWrapper, final ImageRepository imageRepository) {
|
||||
this.contentRepositoryFactory = documentStoreFactory;
|
||||
this.clientRepositoryWrapper = clientRepositoryWrapper;
|
||||
this.imageRepository = imageRepository;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult saveOrUpdateClientImage(final Long clientId, final String imageName, final InputStream inputStream,
|
||||
Long fileSize) {
|
||||
final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||
deletePreviousClientImage(client);
|
||||
|
||||
ContentRepository contentRepository = this.contentRepositoryFactory.getRepository();
|
||||
String imageLocation = contentRepository.saveImage(inputStream, clientId, imageName, fileSize);
|
||||
return updateClientImage(client, imageLocation, contentRepository.getStorageType());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult saveOrUpdateClientImage(final Long clientId, final Base64EncodedImage encodedImage) {
|
||||
final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||
deletePreviousClientImage(client);
|
||||
|
||||
ContentRepository contenRepository = this.contentRepositoryFactory.getRepository();
|
||||
final String imageLocation = contenRepository.saveImage(encodedImage, clientId, "image");
|
||||
|
||||
return updateClientImage(client, imageLocation, contenRepository.getStorageType());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult deleteClientImage(final Long clientId) {
|
||||
|
||||
final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||
|
||||
Image image = client.getImage();
|
||||
// delete image from the file system
|
||||
if (image != null) {
|
||||
ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(StorageType.fromInt(image.getStorageType()));
|
||||
contentRepository.deleteImage(clientId, image.getLocation());
|
||||
client.setImage(null);
|
||||
this.imageRepository.delete(image);
|
||||
this.clientRepositoryWrapper.save(client);
|
||||
}
|
||||
|
||||
return new CommandProcessingResult(clientId);
|
||||
}
|
||||
|
||||
private void deletePreviousClientImage(final Client client) {
|
||||
Image image = client.getImage();
|
||||
if (image != null) {
|
||||
ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(StorageType.fromInt(image.getStorageType()));
|
||||
contentRepository.deleteImage(client.getId(), image.getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
private CommandProcessingResult updateClientImage(final Client client, final String imageLocation, final StorageType storageType) {
|
||||
Image image = client.getImage();
|
||||
if (image == null) {
|
||||
image = new Image(imageLocation, storageType);
|
||||
} else {
|
||||
image.setLocation(imageLocation);
|
||||
image.setStorageType(storageType.getValue());
|
||||
}
|
||||
this.imageRepository.save(image);
|
||||
client.setImage(image);
|
||||
this.clientRepositoryWrapper.save(client);
|
||||
return new CommandProcessingResult(client.getId());
|
||||
}
|
||||
|
||||
}
|
||||
+16
-46
@@ -5,6 +5,9 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.data;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.builder.CompareToBuilder;
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
@@ -13,20 +16,12 @@ import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Immutable data object representing client data.
|
||||
*/
|
||||
final public class ClientData implements Comparable<ClientData> {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ClientData.class);
|
||||
|
||||
|
||||
private final Long id;
|
||||
private final String accountNo;
|
||||
@@ -46,9 +41,7 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
private final Long officeId;
|
||||
private final String officeName;
|
||||
|
||||
// private String imageData;
|
||||
private ImageData imageData;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long imageId;
|
||||
private final Boolean imagePresent;
|
||||
|
||||
// associations
|
||||
@@ -65,13 +58,13 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
|
||||
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
|
||||
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
|
||||
clientData.externalId, clientData.activationDate, clientData.imageData, allowedOffices, clientData.groups);
|
||||
clientData.externalId, clientData.activationDate, clientData.imageId, allowedOffices, clientData.groups);
|
||||
}
|
||||
|
||||
public static ClientData setParentGroups(final ClientData clientData, final Collection<GroupGeneralData> parentGroups) {
|
||||
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
|
||||
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
|
||||
clientData.externalId, clientData.activationDate, clientData.imageData, clientData.officeOptions, parentGroups);
|
||||
clientData.externalId, clientData.activationDate, clientData.imageId, clientData.officeOptions, parentGroups);
|
||||
}
|
||||
|
||||
public static ClientData clientIdentifier(final Long id, final String accountNo, final EnumOptionData status, final String firstname,
|
||||
@@ -88,14 +81,14 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
|
||||
public static ClientData instance(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName,
|
||||
final Long id, final String firstname, final String middlename, final String lastname, final String fullname,
|
||||
final String displayName, final String externalId, final LocalDate activationDate, final ImageData imageData) {
|
||||
final String displayName, final String externalId, final LocalDate activationDate, final Long imageId) {
|
||||
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
|
||||
externalId, activationDate, imageData, null, null);
|
||||
externalId, activationDate, imageId, null, null);
|
||||
}
|
||||
|
||||
private ClientData(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName, final Long id,
|
||||
final String firstname, final String middlename, final String lastname, final String fullname, final String displayName,
|
||||
final String externalId, final LocalDate activationDate, final ImageData imageKey, final Collection<OfficeData> allowedOffices,
|
||||
final String externalId, final LocalDate activationDate, final Long imageId, final Collection<OfficeData> allowedOffices,
|
||||
final Collection<GroupGeneralData> groups) {
|
||||
this.accountNo = accountNo;
|
||||
this.status = status;
|
||||
@@ -114,11 +107,11 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
this.displayName = StringUtils.defaultIfEmpty(displayName, null);
|
||||
this.externalId = StringUtils.defaultIfEmpty(externalId, null);
|
||||
this.activationDate = activationDate;
|
||||
this.imageData = imageKey;
|
||||
if (imageKey != null) {
|
||||
this.imageId = imageId;
|
||||
if (imageId != null) {
|
||||
this.imagePresent = Boolean.TRUE;
|
||||
} else {
|
||||
this.imagePresent = null;
|
||||
this.imagePresent = Boolean.FALSE;
|
||||
}
|
||||
|
||||
// associations
|
||||
@@ -144,17 +137,14 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
return this.officeName;
|
||||
}
|
||||
|
||||
public String imageKey() {
|
||||
return this.imageData.imageKey();
|
||||
public Long getImageId() {
|
||||
return this.imageId;
|
||||
}
|
||||
|
||||
public boolean imageKeyDoesNotExist() {
|
||||
return imageData.equals(null) && !imageKeyExists();
|
||||
public Boolean getImagePresent() {
|
||||
return this.imagePresent;
|
||||
}
|
||||
|
||||
private boolean imageKeyExists() {
|
||||
return StringUtils.isNotBlank(this.imageData.imageKey());
|
||||
}
|
||||
@Override
|
||||
public int compareTo(final ClientData obj) {
|
||||
if (obj == null) { return -1; }
|
||||
@@ -201,24 +191,4 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
return this.activationDate;
|
||||
}
|
||||
|
||||
public void setImageData(ImageData imageData){
|
||||
this.imageData = imageData;
|
||||
}
|
||||
|
||||
public String imageName() {
|
||||
return imageData.name();
|
||||
}
|
||||
|
||||
public String imageContentType() {
|
||||
return imageData.contentType();
|
||||
}
|
||||
|
||||
public byte[] image(){
|
||||
try{
|
||||
return imageData.getContent();
|
||||
}catch (IOException ioe){
|
||||
logger.error("Error in fetching client image");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package org.mifosplatform.portfolio.client.data;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStore;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreType;
|
||||
import org.mifosplatform.infrastructure.core.service.ImageUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ImageData {
|
||||
|
||||
private final Long clientId;
|
||||
private final String key;
|
||||
// private final DocumentStoreType storeType;
|
||||
private final String storeType;
|
||||
private File file;
|
||||
private String contentType;
|
||||
private String name;
|
||||
private InputStream inputStream;
|
||||
|
||||
|
||||
public ImageData(Long clientId, String key, String storeType) {
|
||||
this.clientId = clientId;
|
||||
this.key = key;
|
||||
this.storeType = storeType;
|
||||
}
|
||||
|
||||
public String imageKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public byte[] getContent() throws IOException {
|
||||
if(inputStream == null){
|
||||
FileInputStream fileInputStream = new FileInputStream(file);
|
||||
return IOUtils.toByteArray(fileInputStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
return IOUtils.toByteArray(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
private String setImageContentType() {
|
||||
String fileName = file.getName();
|
||||
String contentType = ImageUtils.IMAGE_MIME_TYPE.JPEG.getValue();
|
||||
if (StringUtils.endsWith(fileName, ImageUtils.IMAGE_FILE_EXTENSION.GIF.getValue())) {
|
||||
contentType = ImageUtils.IMAGE_MIME_TYPE.GIF.getValue();
|
||||
} else if (StringUtils.endsWith(fileName, ImageUtils.IMAGE_FILE_EXTENSION.PNG.getValue())) {
|
||||
contentType = ImageUtils.IMAGE_MIME_TYPE.PNG.getValue();
|
||||
}
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public String contentType(){
|
||||
return this.contentType;
|
||||
}
|
||||
|
||||
public DocumentStoreType storeType() {
|
||||
return DocumentStore.getDocumentStoreType(storeType);
|
||||
}
|
||||
|
||||
public String name(){
|
||||
return this.file.getName();
|
||||
}
|
||||
|
||||
|
||||
public void setContent(InputStream objectContent) {
|
||||
this.inputStream = objectContent;
|
||||
}
|
||||
|
||||
public void setContent(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
+22
-8
@@ -13,6 +13,7 @@ import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.domain.Image;
|
||||
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
|
||||
@@ -20,6 +21,7 @@ import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Entity
|
||||
@@ -33,6 +35,10 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
@JoinColumn(name = "office_id", nullable = false)
|
||||
private Office office;
|
||||
|
||||
@OneToOne(optional = true)
|
||||
@JoinColumn(name = "image_id", nullable = true)
|
||||
private Image image;
|
||||
|
||||
/**
|
||||
* A value from {@link ClientStatus}.
|
||||
*/
|
||||
@@ -55,7 +61,6 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
@Column(name = "fullname", length = 100)
|
||||
private String fullname;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "display_name", length = 100, nullable = false)
|
||||
private String displayName;
|
||||
|
||||
@@ -365,15 +370,24 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
return this.office.identifiedBy(officeId);
|
||||
}
|
||||
|
||||
// public String imageKey() {
|
||||
// }
|
||||
//
|
||||
// public void updateImageKey(final String imageKey) {
|
||||
// this.image.setKey(imageKey);
|
||||
// }
|
||||
|
||||
public Long officeId() {
|
||||
return this.office.getId();
|
||||
}
|
||||
|
||||
public void setImage(Image image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public Image getImage() {
|
||||
return this.image;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreType;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_image")
|
||||
public final class Image extends AbstractPersistable<Long> {
|
||||
|
||||
// @Column(name = "`client_id`")
|
||||
@OneToOne()
|
||||
@JoinColumn(name = "`client_id`")
|
||||
private Client client;
|
||||
|
||||
@Column(name = "`key`", length = 500)
|
||||
private String key;
|
||||
|
||||
@Column(name = "`storage_type`", length = 50)
|
||||
private String storeType;
|
||||
|
||||
public Image(Client client, String image_key, DocumentStoreType storeType) {
|
||||
this.client = client;
|
||||
this.key = image_key;
|
||||
this.storeType = storeType.getValue();
|
||||
}
|
||||
|
||||
public Image() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Image(Client client) {
|
||||
this.client = client;
|
||||
this.key = null;
|
||||
this.storeType = null;
|
||||
}
|
||||
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String updateKey(String key) {
|
||||
setKey(key);
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public void updateStorageType(String documentStoreType) {
|
||||
this.storeType = documentStoreType;
|
||||
}
|
||||
}
|
||||
+7
-31
@@ -16,7 +16,6 @@ import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreFactory;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
@@ -26,7 +25,6 @@ import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
|
||||
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.client.data.ImageData;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||
@@ -43,11 +41,9 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class ClientReadPlatformServiceImpl implements ClientReadPlatformService {
|
||||
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final PlatformSecurityContext context;
|
||||
private final OfficeReadPlatformService officeReadPlatformService;
|
||||
private final DocumentStoreFactory documentStoreFactory;
|
||||
|
||||
// data mappers
|
||||
private final PaginationHelper<ClientData> paginationHelper = new PaginationHelper<ClientData>();
|
||||
@@ -58,10 +54,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
|
||||
@Autowired
|
||||
public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
||||
final OfficeReadPlatformService officeReadPlatformService, final DocumentStoreFactory documentStoreFactory) {
|
||||
final OfficeReadPlatformService officeReadPlatformService) {
|
||||
this.context = context;
|
||||
this.officeReadPlatformService = officeReadPlatformService;
|
||||
this.documentStoreFactory = documentStoreFactory;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
@@ -178,12 +173,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
Collection<GroupGeneralData> parentGroups = this.jdbcTemplate.query(clientGroupsSql, this.clientGroupsMapper,
|
||||
new Object[] { clientId });
|
||||
|
||||
String clientImageSql = "select * from m_image where client_id =" + clientId;
|
||||
|
||||
try {
|
||||
ImageData imageData = this.jdbcTemplate.queryForObject(clientImageSql, new ImageMapper());
|
||||
clientData.setImageData(documentStoreFactory.getInstanceFromStorageType(imageData.storeType()).retrieveImage(imageData));
|
||||
} catch (EmptyResultDataAccessException e) {}
|
||||
return ClientData.setParentGroups(clientData, parentGroups);
|
||||
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
@@ -234,7 +223,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
sqlBuilder.append("c.office_id as officeId, o.name as officeName, ");
|
||||
sqlBuilder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, ");
|
||||
sqlBuilder.append("c.fullname as fullname, c.display_name as displayName, ");
|
||||
sqlBuilder.append("c.activation_date as activationDate, c.image_key as imagekey ");
|
||||
sqlBuilder.append("c.activation_date as activationDate, c.image_id as imageId");
|
||||
sqlBuilder.append("from m_client c ");
|
||||
sqlBuilder.append("join m_office o on o.id = c.office_id ");
|
||||
sqlBuilder.append("join m_group_client pgc on pgc.client_id = c.id");
|
||||
@@ -262,11 +251,11 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final String displayName = rs.getString("displayName");
|
||||
final String externalId = rs.getString("externalId");
|
||||
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
||||
final String imageKey = rs.getString("imageKey");
|
||||
final Long imageId = JdbcSupport.getLong(rs, "imageId");
|
||||
final String officeName = rs.getString("officeName");
|
||||
|
||||
return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
|
||||
externalId, activationDate, null);
|
||||
externalId, activationDate, imageId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,7 +271,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
builder.append("c.office_id as officeId, o.name as officeName, ");
|
||||
builder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, ");
|
||||
builder.append("c.fullname as fullname, c.display_name as displayName, ");
|
||||
builder.append("c.activation_date as activationDate, c.image_key as imagekey ");
|
||||
builder.append("c.activation_date as activationDate, c.image_id as imageId ");
|
||||
builder.append("from m_client c ");
|
||||
builder.append("join m_office o on o.id = c.office_id ");
|
||||
|
||||
@@ -310,13 +299,12 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final String displayName = rs.getString("displayName");
|
||||
final String externalId = rs.getString("externalId");
|
||||
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
||||
// final String imageKey = rs.getString("imageKey");
|
||||
final String officeName = rs.getString("officeName");
|
||||
final Long imageId = JdbcSupport.getLong(rs, "imageId");
|
||||
|
||||
return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
|
||||
externalId, activationDate, null);
|
||||
externalId, activationDate, imageId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class ParentGroupsMapper implements RowMapper<GroupGeneralData> {
|
||||
@@ -336,18 +324,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ImageMapper implements RowMapper<ImageData> {
|
||||
|
||||
@Override
|
||||
public ImageData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
final Long clientId = rs.getLong("client_id");
|
||||
final String imageKey = rs.getString("key");
|
||||
final String storeType = rs.getString("storage_type");
|
||||
return new ImageData(clientId, imageKey, storeType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class ClientLookupMapper implements RowMapper<ClientData> {
|
||||
|
||||
private final String schema;
|
||||
|
||||
-12
@@ -5,12 +5,8 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.service;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
public interface ClientWritePlatformService {
|
||||
|
||||
@@ -22,12 +18,4 @@ public interface ClientWritePlatformService {
|
||||
|
||||
CommandProcessingResult deleteClient(Long clientId);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')")
|
||||
CommandProcessingResult saveOrUpdateClientImage(Long clientId, String imageName, InputStream inputStream, Long fileSize);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')")
|
||||
CommandProcessingResult saveOrUpdateClientImage(Long clientId, Base64EncodedImage encodedImage);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE')")
|
||||
CommandProcessingResult deleteClientImage(Long clientId);
|
||||
}
|
||||
+11
-90
@@ -5,27 +5,28 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.service;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStore;
|
||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreFactory;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.organisation.office.domain.OfficeRepository;
|
||||
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
|
||||
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
|
||||
import org.mifosplatform.portfolio.client.data.ClientDataValidator;
|
||||
import org.mifosplatform.portfolio.client.domain.*;
|
||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
|
||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientMustBePendingToBeDeletedException;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
||||
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
||||
@@ -38,11 +39,6 @@ import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWritePlatformService {
|
||||
|
||||
@@ -55,14 +51,12 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
private final GroupRepository groupRepository;
|
||||
private final ClientDataValidator fromApiJsonDeserializer;
|
||||
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
|
||||
private final DocumentStoreFactory documentStoreFactory;
|
||||
private final ImageRepository imageRepository;
|
||||
|
||||
@Autowired
|
||||
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository,
|
||||
final ClientDataValidator fromApiJsonDeserializer, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
|
||||
final GroupRepository groupRepository, DocumentStoreFactory documentStoreFactory, ImageRepository imageRepository) {
|
||||
final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository,
|
||||
final ClientDataValidator fromApiJsonDeserializer, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
|
||||
final GroupRepository groupRepository) {
|
||||
this.context = context;
|
||||
this.clientRepository = clientRepository;
|
||||
this.officeRepository = officeRepository;
|
||||
@@ -70,8 +64,6 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
|
||||
this.groupRepository = groupRepository;
|
||||
this.documentStoreFactory = documentStoreFactory;
|
||||
this.imageRepository = imageRepository;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -221,77 +213,6 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult saveOrUpdateClientImage(final Long clientId, final String imageName, final InputStream inputStream, Long fileSize) {
|
||||
try {
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
deletePreviousClientImage(clientId, client);
|
||||
|
||||
DocumentStore documentStore = this.documentStoreFactory.getInstanceFromConfiguration();
|
||||
String imageLocation = documentStore.saveImage(inputStream, clientId, imageName, fileSize);
|
||||
return updateClientImage(clientId, client, imageLocation, documentStore.getType().getValue());
|
||||
} catch (DocumentManagementException dme) {
|
||||
logger.error(dme.getMessage(), dme);
|
||||
throw new DocumentManagementException(imageName);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult deleteClientImage(final Long clientId) {
|
||||
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
|
||||
Image image = imageRepository.findOneByClient(client);
|
||||
String imageKey = image.getKey();
|
||||
// delete image from the file system
|
||||
if (StringUtils.isNotEmpty((imageKey))) {
|
||||
DocumentStore documentStore = this.documentStoreFactory.getInstanceFromConfiguration();
|
||||
documentStore.deleteImage(clientId, imageKey);
|
||||
this.imageRepository.delete(image);
|
||||
}
|
||||
|
||||
return new CommandProcessingResult(clientId) ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult saveOrUpdateClientImage(final Long clientId, final Base64EncodedImage encodedImage) {
|
||||
try {
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
deletePreviousClientImage(clientId, client);
|
||||
|
||||
DocumentStore documentStore = this.documentStoreFactory.getInstanceFromConfiguration();
|
||||
final String imageLocation = documentStore.saveImage(encodedImage, clientId, "image");
|
||||
|
||||
return updateClientImage(clientId, client, imageLocation, documentStore.getType().getValue());
|
||||
} catch (DocumentManagementException dme) {
|
||||
logger.error(dme.getMessage(), dme);
|
||||
throw new DocumentManagementException("image");
|
||||
}
|
||||
}
|
||||
|
||||
private void deletePreviousClientImage(final Long clientId, final Client client) {
|
||||
if (client == null) { throw new ClientNotFoundException(clientId); }
|
||||
|
||||
Image image = imageRepository.findOneByClient(client);
|
||||
if (image != null){
|
||||
this.documentStoreFactory.getInstanceFromConfiguration().deleteImage(clientId, image.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
private CommandProcessingResult updateClientImage(final Long clientId, final Client client, final String imageLocation, final String documentStoreType) {
|
||||
Image image = imageRepository.findOneByClient(client);
|
||||
if(image == null){
|
||||
image = new Image(client);
|
||||
}
|
||||
image.updateKey(imageLocation);
|
||||
image.updateStorageType(documentStoreType);
|
||||
|
||||
this.imageRepository.save(image);
|
||||
return new CommandProcessingResult(clientId);
|
||||
}
|
||||
|
||||
private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) {
|
||||
logger.error(dve.getMessage(), dve);
|
||||
}
|
||||
|
||||
+22
-21
@@ -1,28 +1,28 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ExternalServicesDomainService;
|
||||
import org.mifosplatform.infrastructure.configuration.service.ExternalServicesReadPlatformServiceImpl;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.FileSystemContentRepository;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.S3ContentRepository;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DocumentStoreFactoryTest {
|
||||
|
||||
/**
|
||||
@Test
|
||||
public void shouldReturnS3DocumentStoreObjectIfS3Enabled(){
|
||||
public void shouldReturnS3DocumentStoreObjectIfS3Enabled() {
|
||||
S3ClientFactory s3ClientFactoryMock = mock(S3ClientFactory.class);
|
||||
when(s3ClientFactoryMock.getS3Client()).thenReturn(null);
|
||||
|
||||
ExternalServicesDomainService externalServicesDomainServiceMock = mock(ExternalServicesDomainService.class);
|
||||
ExternalServicesReadPlatformServiceImpl externalServicesDomainServiceMock = mock(ExternalServicesReadPlatformServiceImpl.class);
|
||||
when(externalServicesDomainServiceMock.getValue("s3_bucket_name")).thenReturn("bucket_name");
|
||||
|
||||
ConfigurationDomainService configurationDomainServiceMock = mock(ConfigurationDomainService.class);
|
||||
@@ -30,26 +30,27 @@ public class DocumentStoreFactoryTest {
|
||||
|
||||
ApplicationContext applicationContextMock = mock(ApplicationContext.class);
|
||||
|
||||
when(applicationContextMock.getBean("configurationDomainServiceJpa", ConfigurationDomainService.class)).thenReturn(configurationDomainServiceMock);
|
||||
when(applicationContextMock.getBean("configurationDomainServiceJpa", ConfigurationDomainService.class)).thenReturn(
|
||||
configurationDomainServiceMock);
|
||||
when(applicationContextMock.getBean("s3ClientFactory", S3ClientFactory.class)).thenReturn(s3ClientFactoryMock);
|
||||
when(applicationContextMock.getBean("externalServicesDomainService", ExternalServicesDomainService.class)).thenReturn(externalServicesDomainServiceMock);
|
||||
when(applicationContextMock.getBean("externalServicesDomainService", ExternalServicesReadPlatformServiceImpl.class)).thenReturn(
|
||||
externalServicesDomainServiceMock);
|
||||
|
||||
|
||||
DocumentStoreFactory documentStoreFactory = new DocumentStoreFactory(applicationContextMock);
|
||||
assertEquals(documentStoreFactory.getInstanceFromConfiguration().getClass(),S3DocumentStore.class);
|
||||
ContentRepositoryFactory documentStoreFactory = new ContentRepositoryFactory(applicationContextMock);
|
||||
assertEquals(documentStoreFactory.getInstanceFromConfiguration().getClass(), S3ContentRepository.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnFileSystemDocumentStoreObjectIfS3IsDisabled(){
|
||||
public void shouldReturnFileSystemDocumentStoreObjectIfS3IsDisabled() {
|
||||
ConfigurationDomainService configurationDomainService = mock(ConfigurationDomainService.class);
|
||||
when(configurationDomainService.isAmazonS3Enabled()).thenReturn(false);
|
||||
|
||||
ApplicationContext applicationContext = mock(ApplicationContext.class);
|
||||
when(applicationContext.getBean("configurationDomainServiceJpa", ConfigurationDomainService.class)).thenReturn(configurationDomainService);
|
||||
when(applicationContext.getBean("configurationDomainServiceJpa", ConfigurationDomainService.class)).thenReturn(
|
||||
configurationDomainService);
|
||||
|
||||
DocumentStoreFactory documentStoreFactory = new DocumentStoreFactory(applicationContext);
|
||||
assertEquals(documentStoreFactory.getInstanceFromConfiguration().getClass(),FileSystemDocumentStore.class);
|
||||
ContentRepositoryFactory documentStoreFactory = new ContentRepositoryFactory(applicationContext);
|
||||
assertEquals(documentStoreFactory.getInstanceFromConfiguration().getClass(), FileSystemContentRepository.class);
|
||||
}
|
||||
|
||||
|
||||
**/
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,23 +1,22 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.FileSystemContentRepository;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class FileDocumentStoreTest {
|
||||
|
||||
/**
|
||||
@Test
|
||||
public void shouldRetrieveDocument(){
|
||||
FileSystemDocumentStore fileSystemDocumentStore = new FileSystemDocumentStore();
|
||||
public void shouldRetrieveDocument() {
|
||||
FileSystemContentRepository fileSystemDocumentStore = new FileSystemContentRepository();
|
||||
DocumentData documentDataMock = mock(DocumentData.class);
|
||||
when(documentDataMock.fileName()).thenReturn("some_file");
|
||||
when(documentDataMock.fileName()).thenReturn("content_type");
|
||||
@@ -28,4 +27,5 @@ public class FileDocumentStoreTest {
|
||||
assertEquals(fileData.name(), documentDataMock.fileName());
|
||||
assertEquals(fileData.contentType(), documentDataMock.contentType());
|
||||
}
|
||||
**/
|
||||
}
|
||||
|
||||
+49
-42
@@ -1,27 +1,34 @@
|
||||
package org.mifosplatform.infrastructure.core.service;
|
||||
|
||||
import com.amazonaws.AmazonClientException;
|
||||
import com.amazonaws.AmazonServiceException;
|
||||
import com.amazonaws.services.s3.AmazonS3Client;
|
||||
import com.amazonaws.services.s3.model.*;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.*;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.S3ContentRepository;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.ContentManagementException;
|
||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
import com.amazonaws.AmazonClientException;
|
||||
import com.amazonaws.AmazonServiceException;
|
||||
import com.amazonaws.services.s3.AmazonS3Client;
|
||||
import com.amazonaws.services.s3.model.DeleteObjectRequest;
|
||||
import com.amazonaws.services.s3.model.GetObjectRequest;
|
||||
import com.amazonaws.services.s3.model.PutObjectRequest;
|
||||
import com.amazonaws.services.s3.model.PutObjectResult;
|
||||
import com.amazonaws.services.s3.model.S3Object;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class S3DocumentStoreTest {
|
||||
@@ -30,17 +37,17 @@ public class S3DocumentStoreTest {
|
||||
AmazonS3Client s3ClientMock;
|
||||
DocumentCommand documentCommand;
|
||||
DocumentData documentDataMock;
|
||||
|
||||
/**
|
||||
@Test
|
||||
public void shouldGenerateParentDirectoryFromEntityDetails(){
|
||||
S3DocumentStore s3DocumentStore=new S3DocumentStore("bucketName", null);
|
||||
public void shouldGenerateParentDirectoryFromEntityDetails() {
|
||||
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", null);
|
||||
String actualParentDirectory = s3DocumentStore.generateFileParentDirectory("entity_type", 1234L);
|
||||
assertTrue(actualParentDirectory.startsWith("documents/entity_type/1234"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGenerateClientImageDirectoryFromResourceId(){
|
||||
S3DocumentStore s3DocumentStore=new S3DocumentStore("bucketName", null);
|
||||
public void shouldGenerateClientImageDirectoryFromResourceId() {
|
||||
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", null);
|
||||
String actualParentDirectory = s3DocumentStore.generateClientImageParentDirectory(1234L);
|
||||
assertTrue(actualParentDirectory.startsWith("images/clients/1234"));
|
||||
}
|
||||
@@ -48,20 +55,20 @@ public class S3DocumentStoreTest {
|
||||
@Test
|
||||
public void shouldSaveADocumentToS3() throws IOException {
|
||||
initUpload();
|
||||
when(s3ClientMock.putObject(Matchers.<PutObjectRequest>anyObject())).thenReturn(new PutObjectResult());
|
||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName", s3ClientMock);
|
||||
when(s3ClientMock.putObject(Matchers.<PutObjectRequest> anyObject())).thenReturn(new PutObjectResult());
|
||||
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||
|
||||
s3DocumentStore.saveDocument(inputStream, documentCommand);
|
||||
|
||||
verify(s3ClientMock, times(1)).putObject(Matchers.<PutObjectRequest>anyObject());
|
||||
verify(s3ClientMock, times(1)).putObject(Matchers.<PutObjectRequest> anyObject());
|
||||
}
|
||||
|
||||
@Test(expected = DocumentManagementException.class)
|
||||
public void shouldCatchAmazonServiceExceptionWhenUnableToUploadDocumentToS3() throws IOException {
|
||||
initUpload();
|
||||
when(s3ClientMock.putObject(Matchers.<PutObjectRequest>anyObject())).thenThrow(new AmazonServiceException("serviceException"));
|
||||
when(s3ClientMock.putObject(Matchers.<PutObjectRequest> anyObject())).thenThrow(new AmazonServiceException("serviceException"));
|
||||
|
||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName", s3ClientMock);
|
||||
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||
|
||||
s3DocumentStore.saveDocument(inputStream, documentCommand);
|
||||
}
|
||||
@@ -69,9 +76,9 @@ public class S3DocumentStoreTest {
|
||||
@Test(expected = DocumentManagementException.class)
|
||||
public void shouldCatchAmazonClientExceptionWhenUnableToUploadDocumentToS3() throws IOException {
|
||||
initUpload();
|
||||
when(s3ClientMock.putObject(Matchers.<PutObjectRequest>anyObject())).thenThrow(new AmazonClientException("clientException"));
|
||||
when(s3ClientMock.putObject(Matchers.<PutObjectRequest> anyObject())).thenThrow(new AmazonClientException("clientException"));
|
||||
|
||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName", s3ClientMock);
|
||||
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||
|
||||
s3DocumentStore.saveDocument(inputStream, documentCommand);
|
||||
}
|
||||
@@ -79,12 +86,12 @@ public class S3DocumentStoreTest {
|
||||
@Test
|
||||
public void shouldRetrieveDocumentFromS3() throws IOException {
|
||||
initRetrieve();
|
||||
when(s3ClientMock.getObject(Matchers.<GetObjectRequest>anyObject())).thenReturn(new S3Object());
|
||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName",s3ClientMock);
|
||||
when(s3ClientMock.getObject(Matchers.<GetObjectRequest> anyObject())).thenReturn(new S3Object());
|
||||
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||
|
||||
FileData fileData = s3DocumentStore.retrieveDocument(documentDataMock);
|
||||
|
||||
verify(s3ClientMock, times(1)).getObject(Matchers.<GetObjectRequest>anyObject());
|
||||
verify(s3ClientMock, times(1)).getObject(Matchers.<GetObjectRequest> anyObject());
|
||||
assertEquals(fileData.name(), "name");
|
||||
assertEquals(fileData.contentType(), "type");
|
||||
}
|
||||
@@ -92,8 +99,8 @@ public class S3DocumentStoreTest {
|
||||
@Test(expected = DocumentNotFoundException.class)
|
||||
public void shouldCatchAmazonServiceExceptionWhenUnableToRetrieveDocumentFromS3() throws IOException {
|
||||
initRetrieve();
|
||||
when(s3ClientMock.getObject(Matchers.<GetObjectRequest>anyObject())).thenThrow(new AmazonServiceException("serviceException"));
|
||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName",s3ClientMock);
|
||||
when(s3ClientMock.getObject(Matchers.<GetObjectRequest> anyObject())).thenThrow(new AmazonServiceException("serviceException"));
|
||||
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||
|
||||
s3DocumentStore.retrieveDocument(documentDataMock);
|
||||
}
|
||||
@@ -101,8 +108,8 @@ public class S3DocumentStoreTest {
|
||||
@Test(expected = DocumentNotFoundException.class)
|
||||
public void shouldCatchAmazonClientExceptionWhenUnableToRetrieveDocumentFromS3() throws IOException {
|
||||
initRetrieve();
|
||||
when(s3ClientMock.getObject(Matchers.<GetObjectRequest>anyObject())).thenThrow(new AmazonClientException("clientException"));
|
||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName",s3ClientMock);
|
||||
when(s3ClientMock.getObject(Matchers.<GetObjectRequest> anyObject())).thenThrow(new AmazonClientException("clientException"));
|
||||
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||
|
||||
s3DocumentStore.retrieveDocument(documentDataMock);
|
||||
}
|
||||
@@ -110,11 +117,11 @@ public class S3DocumentStoreTest {
|
||||
@Test
|
||||
public void shouldDeleteImageFromS3() throws IOException {
|
||||
AmazonS3Client s3ClientMock = mock(AmazonS3Client.class);
|
||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName",s3ClientMock);
|
||||
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||
|
||||
s3DocumentStore.deleteImage(123L,"imagekey");
|
||||
s3DocumentStore.deleteImage(123L, "imagekey");
|
||||
|
||||
verify(s3ClientMock, times(1)).deleteObject(Matchers.<DeleteObjectRequest>anyObject());
|
||||
verify(s3ClientMock, times(1)).deleteObject(Matchers.<DeleteObjectRequest> anyObject());
|
||||
}
|
||||
|
||||
private void initRetrieve() {
|
||||
@@ -126,10 +133,10 @@ public class S3DocumentStoreTest {
|
||||
when(documentDataMock.contentType()).thenReturn("type");
|
||||
}
|
||||
|
||||
|
||||
private void initUpload(){
|
||||
private void initUpload() {
|
||||
inputStream = S3DocumentStoreTest.class.getResourceAsStream("DummyString");
|
||||
s3ClientMock = mock(AmazonS3Client.class);
|
||||
documentCommand = new DocumentCommand(null, -1l, "parentEntityType", 1l, null, "someFileName", 3l, null, null, null);
|
||||
documentCommand = new DocumentCommand(null, -1l, "parentEntityType", 1l, null, "someFileName", 3l, null, null, null);
|
||||
}
|
||||
**/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user