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;
|
package org.mifosplatform.infrastructure.configuration.domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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,
|
* 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/.
|
* 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.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.UniqueConstraint;
|
import javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "m_external_services", uniqueConstraints = { @UniqueConstraint(columnNames = ("name"))})
|
@Table(name = "c_external_service", uniqueConstraints = { @UniqueConstraint(columnNames = ("name")) })
|
||||||
public class ExternalServiceProperty extends AbstractPersistable<Long> {
|
public class ExternalService extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "name", nullable = false)
|
@Column(name = "name", nullable = false)
|
||||||
@@ -23,15 +24,14 @@ public class ExternalServiceProperty extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "value", nullable = false)
|
@Column(name = "value", nullable = false)
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
public ExternalServiceProperty(final String name, final String value) {
|
public ExternalService(final String name, final String value) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExternalServiceProperty() {
|
protected ExternalService() {}
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue(){
|
public String getValue() {
|
||||||
return this.value;
|
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.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
public interface ExternalServiceRepository extends JpaRepository<ExternalServiceProperty, Long>,
|
public interface ExternalServiceRepository extends JpaRepository<ExternalService, Long>, JpaSpecificationExecutor<ExternalService> {
|
||||||
JpaSpecificationExecutor<ExternalServiceProperty> {
|
|
||||||
|
|
||||||
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.security.authentication.encoding.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Service(value = "applicationPasswordEncoder")
|
@Service(value = "applicationPasswordEncoder")
|
||||||
@Scope("singleton")
|
@Scope("singleton")
|
||||||
public class DefaultPlatformPasswordEncoder implements PlatformPasswordEncoder {
|
public class DefaultPlatformPasswordEncoder implements PlatformPasswordEncoder {
|
||||||
|
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
private final SaltSource saltSource;
|
private final SaltSource saltSource;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public DefaultPlatformPasswordEncoder(final PasswordEncoder passwordEncoder, final SaltSource saltSource) {
|
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.apache.commons.lang.StringUtils;
|
||||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
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.core.service.TenantAwareRoutingDataSource;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.data.ReportData;
|
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.ResultsetColumnHeaderData;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData;
|
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.exception.ReportNotFoundException;
|
import org.mifosplatform.infrastructure.dataqueries.exception.ReportNotFoundException;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.FileSystemContentRepository;
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.mifosplatform.useradministration.domain.AppUser;
|
import org.mifosplatform.useradministration.domain.AppUser;
|
||||||
import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot;
|
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",
|
if (noPentaho) { throw new PlatformDataIntegrityException("error.msg.no.pentaho", "Pentaho is not enabled",
|
||||||
"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);
|
logger.info("Report path: " + reportPath);
|
||||||
|
|
||||||
// load report definition
|
// load report definition
|
||||||
@@ -357,7 +357,7 @@ public class ReadReportingServiceImpl implements ReadReportingService {
|
|||||||
@Override
|
@Override
|
||||||
public String retrieveReportPDF(final String reportName, final String type, final Map<String, String> queryParams) {
|
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()) {
|
if (!new File(fileLocation).isDirectory()) {
|
||||||
new File(fileLocation).mkdirs();
|
new File(fileLocation).mkdirs();
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-6
@@ -52,8 +52,8 @@ public class DocumentManagementApiResource {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public DocumentManagementApiResource(final PlatformSecurityContext context,
|
public DocumentManagementApiResource(final PlatformSecurityContext context,
|
||||||
final DocumentReadPlatformService documentReadPlatformService, final DocumentWritePlatformService documentWritePlatformService,
|
final DocumentReadPlatformService documentReadPlatformService, final DocumentWritePlatformService documentWritePlatformService,
|
||||||
final ApiRequestParameterHelper apiRequestParameterHelper, final ToApiJsonSerializer<DocumentData> toApiJsonSerializer) {
|
final ApiRequestParameterHelper apiRequestParameterHelper, final ToApiJsonSerializer<DocumentData> toApiJsonSerializer) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.documentReadPlatformService = documentReadPlatformService;
|
this.documentReadPlatformService = documentReadPlatformService;
|
||||||
this.documentWritePlatformService = documentWritePlatformService;
|
this.documentWritePlatformService = documentWritePlatformService;
|
||||||
@@ -150,9 +150,6 @@ public class DocumentManagementApiResource {
|
|||||||
|
|
||||||
final DocumentData documentData = this.documentReadPlatformService.retrieveDocument(entityType, entityId, documentId);
|
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());
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
return this.toApiJsonSerializer.serialize(settings, documentData, this.RESPONSE_DATA_PARAMETERS);
|
return this.toApiJsonSerializer.serialize(settings, documentData, this.RESPONSE_DATA_PARAMETERS);
|
||||||
}
|
}
|
||||||
@@ -166,7 +163,7 @@ public class DocumentManagementApiResource {
|
|||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission(this.SystemEntityType);
|
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());
|
final ResponseBuilder response = Response.ok(fileData.file());
|
||||||
response.header("Content-Disposition", "attachment; filename=\"" + fileData.name() + "\"");
|
response.header("Content-Disposition", "attachment; filename=\"" + fileData.name() + "\"");
|
||||||
response.header("Content-Type", fileData.contentType());
|
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,
|
* 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/.
|
* 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.lowagie.text.pdf.codec.Base64;
|
||||||
import com.sun.jersey.core.header.FormDataContentDisposition;
|
import com.sun.jersey.core.header.FormDataContentDisposition;
|
||||||
import com.sun.jersey.multipart.FormDataBodyPart;
|
import com.sun.jersey.multipart.FormDataBodyPart;
|
||||||
import com.sun.jersey.multipart.FormDataParam;
|
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;
|
* TODO Vishwas need to change the url to entity/entityId/images to make the
|
||||||
import javax.ws.rs.core.Response;
|
* image management API's generic for other entities like staff etc
|
||||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
**/
|
||||||
import java.io.InputStream;
|
@Path("{clients}/{clientId}/images")
|
||||||
|
|
||||||
@Path("/clients/{clientId}/images")
|
|
||||||
@Component
|
@Component
|
||||||
@Scope("singleton")
|
@Scope("singleton")
|
||||||
public class ClientImagesApiResource {
|
public class ImagesApiResource {
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final ClientReadPlatformService clientReadPlatformService;
|
private final ImageReadPlatformService imageReadPlatformService;
|
||||||
private final ClientWritePlatformService clientWritePlatformService;
|
private final ImageWritePlatformService imageWritePlatformService;
|
||||||
private final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer;
|
private final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer;
|
||||||
private final static Logger logger = LoggerFactory.getLogger(ClientImagesApiResource.class);
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ClientImagesApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
|
public ImagesApiResource(final PlatformSecurityContext context, final ImageReadPlatformService readPlatformService,
|
||||||
final ClientWritePlatformService clientWritePlatformService, final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer) {
|
final ImageWritePlatformService imageWritePlatformService, final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.clientReadPlatformService = readPlatformService;
|
this.imageReadPlatformService = readPlatformService;
|
||||||
this.clientWritePlatformService = clientWritePlatformService;
|
this.imageWritePlatformService = imageWritePlatformService;
|
||||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,10 +76,10 @@ public class ClientImagesApiResource {
|
|||||||
// TODO: vishwas might need more advances validation (like reading magic
|
// TODO: vishwas might need more advances validation (like reading magic
|
||||||
// number) for handling malicious clients
|
// number) for handling malicious clients
|
||||||
// and clients not setting mime type
|
// and clients not setting mime type
|
||||||
ImageUtils.validateClientImageNotEmpty(fileDetails.getFileName());
|
ContentRepositoryUtils.validateClientImageNotEmpty(fileDetails.getFileName());
|
||||||
ImageUtils.validateImageMimeType(bodyPart.getMediaType().toString());
|
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);
|
inputStream, fileSize);
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(result);
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
@@ -81,9 +93,9 @@ public class ClientImagesApiResource {
|
|||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String addNewClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) {
|
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);
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
}
|
}
|
||||||
@@ -98,19 +110,17 @@ public class ClientImagesApiResource {
|
|||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
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); }
|
|
||||||
|
|
||||||
// TODO: Need a better way of determining image type
|
// TODO: Need a better way of determining image type
|
||||||
String imageDataURISuffix = ImageUtils.IMAGE_DATA_URI_SUFFIX.JPEG.getValue();
|
String imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.JPEG.getValue();
|
||||||
if (StringUtils.endsWith(clientData.imageKey(), ImageUtils.IMAGE_FILE_EXTENSION.GIF.getValue())) {
|
if (StringUtils.endsWith(imageData.location(), ContentRepositoryUtils.IMAGE_FILE_EXTENSION.GIF.getValue())) {
|
||||||
imageDataURISuffix = ImageUtils.IMAGE_DATA_URI_SUFFIX.GIF.getValue();
|
imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.GIF.getValue();
|
||||||
} else if (StringUtils.endsWith(clientData.imageKey(), ImageUtils.IMAGE_FILE_EXTENSION.PNG.getValue())) {
|
} else if (StringUtils.endsWith(imageData.location(), ContentRepositoryUtils.IMAGE_FILE_EXTENSION.PNG.getValue())) {
|
||||||
imageDataURISuffix = ImageUtils.IMAGE_DATA_URI_SUFFIX.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;
|
return clientImageAsBase64Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,16 +130,15 @@ public class ClientImagesApiResource {
|
|||||||
public Response downloadClientImage(@PathParam("clientId") final Long clientId) {
|
public Response downloadClientImage(@PathParam("clientId") final Long clientId) {
|
||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
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(imageData.getContent());
|
||||||
|
response.header("Content-Disposition", "attachment; filename=\"" + imageData.getEntityDisplayName() + IMAGE_FILE_EXTENSION.JPEG
|
||||||
ResponseBuilder response = Response.ok(clientData.image());
|
+ "\"");
|
||||||
response.header("Content-Disposition", "attachment; filename=\"" + clientData.imageName() + "\"");
|
|
||||||
|
|
||||||
// TODO: Need a better way of determining image type
|
// TODO: Need a better way of determining image type
|
||||||
|
|
||||||
response.header("Content-Type", clientData.imageContentType());
|
response.header("Content-Type", imageData.contentType());
|
||||||
return response.build();
|
return response.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +172,7 @@ public class ClientImagesApiResource {
|
|||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String deleteClientImage(@PathParam("clientId") final Long clientId) {
|
public String deleteClientImage(@PathParam("clientId") final Long clientId) {
|
||||||
this.clientWritePlatformService.deleteClientImage(clientId);
|
this.imageWritePlatformService.deleteClientImage(clientId);
|
||||||
return this.toApiJsonSerializer.serialize(new CommandProcessingResult(clientId));
|
return this.toApiJsonSerializer.serialize(new CommandProcessingResult(clientId));
|
||||||
}
|
}
|
||||||
|
|
||||||
+9
-10
@@ -5,8 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.infrastructure.documentmanagement.command;
|
package org.mifosplatform.infrastructure.documentmanagement.command;
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreType;
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,9 +22,9 @@ public class DocumentCommand {
|
|||||||
private Long size;
|
private Long size;
|
||||||
private String type;
|
private String type;
|
||||||
private String location;
|
private String location;
|
||||||
|
private Integer storageType;
|
||||||
|
|
||||||
private final Set<String> modifiedParameters;
|
private final Set<String> modifiedParameters;
|
||||||
private DocumentStoreType storageType;
|
|
||||||
|
|
||||||
public DocumentCommand(final Set<String> modifiedParameters, final Long id, final String parentEntityType, final Long parentEntityId,
|
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) {
|
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;
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getStorageType() {
|
||||||
|
return this.storageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStorageType(Integer storageType) {
|
||||||
|
this.storageType = storageType;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isNameChanged() {
|
public boolean isNameChanged() {
|
||||||
return this.modifiedParameters.contains("name");
|
return this.modifiedParameters.contains("name");
|
||||||
}
|
}
|
||||||
@@ -122,11 +128,4 @@ public class DocumentCommand {
|
|||||||
return this.modifiedParameters.contains("location");
|
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.apache.commons.lang.StringUtils;
|
||||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
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.ImageDataURLNotValidException;
|
||||||
import org.mifosplatform.infrastructure.core.exception.ImageUploadException;
|
import org.mifosplatform.infrastructure.core.exception.ImageUploadException;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.exception.ContentManagementException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
public class ContentRepositoryUtils {
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ImageUtils {
|
public static Random random = new Random();
|
||||||
|
|
||||||
public static enum IMAGE_MIME_TYPE {
|
public static enum IMAGE_MIME_TYPE {
|
||||||
GIF("image/gif"), JPEG("image/jpeg"), PNG("image/png");
|
GIF("image/gif"), JPEG("image/jpeg"), PNG("image/png");
|
||||||
@@ -54,21 +58,20 @@ public class ImageUtils {
|
|||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates that passed in Mime type maps to known image mime types
|
* Validates that passed in Mime type maps to known image mime types
|
||||||
*
|
*
|
||||||
* @param mimeType
|
* @param mimeType
|
||||||
*/
|
*/
|
||||||
public static void validateImageMimeType(String mimeType) {
|
public static void validateImageMimeType(String mimeType) {
|
||||||
if (!(mimeType.equalsIgnoreCase(IMAGE_MIME_TYPE.GIF.getValue()) || mimeType.equalsIgnoreCase(IMAGE_MIME_TYPE.JPEG.getValue()) || mimeType
|
if (!(mimeType.equalsIgnoreCase(IMAGE_MIME_TYPE.GIF.getValue()) || mimeType.equalsIgnoreCase(IMAGE_MIME_TYPE.JPEG.getValue()) || mimeType
|
||||||
.equalsIgnoreCase(IMAGE_MIME_TYPE.PNG.getValue()))) {
|
.equalsIgnoreCase(IMAGE_MIME_TYPE.PNG.getValue()))) { throw new ImageUploadException(); }
|
||||||
throw new ImageUploadException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts Image from a Data URL
|
* Extracts Image from a Data URL
|
||||||
*
|
*
|
||||||
* @param mimeType
|
* @param mimeType
|
||||||
*/
|
*/
|
||||||
public static Base64EncodedImage extractImageFromDataURL(String dataURL) {
|
public static Base64EncodedImage extractImageFromDataURL(String dataURL) {
|
||||||
@@ -90,6 +93,17 @@ public class ImageUtils {
|
|||||||
return new Base64EncodedImage(base64EncodedString, fileExtension);
|
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) {
|
public static void validateClientImageNotEmpty(String imageFileName) {
|
||||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
if (imageFileName == null) {
|
if (imageFileName == null) {
|
||||||
@@ -102,4 +116,29 @@ public class ImageUtils {
|
|||||||
dataValidationErrors);
|
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,
|
* 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/.
|
* 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.domain.Base64EncodedImage;
|
||||||
|
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
|
||||||
import org.mifosplatform.portfolio.client.data.ImageData;
|
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.exception.ContentManagementException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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";
|
public static final String MIFOSX_BASE_DIR = System.getProperty("user.home") + File.separator + ".mifosx";
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String saveDocument(InputStream uploadedInputStream, DocumentCommand documentCommand) throws DocumentManagementException {
|
public String saveFile(InputStream uploadedInputStream, DocumentCommand documentCommand) {
|
||||||
String documentName = documentCommand.getFileName();
|
String fileName = documentCommand.getFileName();
|
||||||
String uploadDocumentLocation = generateFileParentDirectory(documentCommand.getParentEntityType(), documentCommand.getParentEntityId());
|
String uploadDocumentLocation = generateFileParentDirectory(documentCommand.getParentEntityType(),
|
||||||
|
documentCommand.getParentEntityId());
|
||||||
|
|
||||||
validateFileSizeWithinPermissibleRange(documentCommand.getSize(), documentName, maxFileSize);
|
ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(documentCommand.getSize(), fileName);
|
||||||
makeDirectories(uploadDocumentLocation);
|
makeDirectories(uploadDocumentLocation);
|
||||||
|
|
||||||
String fileLocation = uploadDocumentLocation + File.separator + documentName;
|
String fileLocation = uploadDocumentLocation + File.separator + fileName;
|
||||||
|
|
||||||
writeFileToFileSystem(uploadedInputStream, fileLocation);
|
writeFileToFileSystem(fileName, uploadedInputStream, fileLocation);
|
||||||
return fileLocation;
|
return fileLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@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);
|
String uploadImageLocation = generateClientImageParentDirectory(resourceId);
|
||||||
|
|
||||||
validateFileSizeWithinPermissibleRange(fileSize, imageName, maxImageSize);
|
ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(fileSize, imageName);
|
||||||
makeDirectories(uploadImageLocation);
|
makeDirectories(uploadImageLocation);
|
||||||
|
|
||||||
String fileLocation = uploadImageLocation + File.separator + imageName;
|
String fileLocation = uploadImageLocation + File.separator + imageName;
|
||||||
|
|
||||||
writeFileToFileSystem(uploadedInputStream, fileLocation);
|
writeFileToFileSystem(imageName, uploadedInputStream, fileLocation);
|
||||||
return fileLocation;
|
return fileLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
String uploadImageLocation = generateClientImageParentDirectory(resourceId);
|
||||||
|
|
||||||
makeDirectories(uploadImageLocation);
|
makeDirectories(uploadImageLocation);
|
||||||
@@ -65,8 +71,8 @@ public class FileSystemDocumentStore extends DocumentStore {
|
|||||||
out.write(imgBytes);
|
out.write(imgBytes);
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
}catch (IOException ioe){
|
} catch (IOException ioe) {
|
||||||
throw new DocumentManagementException(ioe.getMessage());
|
throw new ContentManagementException(imageName, ioe.getMessage());
|
||||||
}
|
}
|
||||||
return fileLocation;
|
return fileLocation;
|
||||||
}
|
}
|
||||||
@@ -81,9 +87,9 @@ public class FileSystemDocumentStore extends DocumentStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteDocument(String documentName, String documentPath) throws DocumentManagementException{
|
public void deleteFile(String fileName, String documentPath) {
|
||||||
final boolean fileDeleted = deleteFile(documentPath);
|
final boolean fileDeleted = deleteFile(documentPath);
|
||||||
if (!fileDeleted) { throw new DocumentManagementException(documentName); }
|
if (!fileDeleted) { throw new ContentManagementException(fileName, null); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean deleteFile(String documentPath) {
|
private boolean deleteFile(String documentPath) {
|
||||||
@@ -92,42 +98,43 @@ public class FileSystemDocumentStore extends DocumentStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DocumentStoreType getType() {
|
public StorageType getStorageType() {
|
||||||
return DocumentStoreType.FILE_SYSTEM;
|
return StorageType.FILE_SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileData retrieveDocument(DocumentData documentData){
|
public FileData fetchFile(DocumentData documentData) {
|
||||||
File file = new File(documentData.fileLocation());
|
File file = new File(documentData.fileLocation());
|
||||||
return new FileData(file, documentData.fileName(), documentData.contentType());
|
return new FileData(file, documentData.fileName(), documentData.contentType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageData retrieveImage(ImageData imageData) {
|
public ImageData fetchImage(ImageData imageData) {
|
||||||
File file = new File(imageData.imageKey());
|
File file = new File(imageData.location());
|
||||||
imageData.setContent(file);
|
imageData.updateContent(file);
|
||||||
return imageData;
|
return imageData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the directory path for storing the new document
|
* Generate the directory path for storing the new document
|
||||||
*
|
*
|
||||||
* @param entityType
|
* @param entityType
|
||||||
* @param entityId
|
* @param entityId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String generateFileParentDirectory(String entityType, Long entityId) {
|
private String generateFileParentDirectory(String entityType, Long entityId) {
|
||||||
return FileSystemDocumentStore.MIFOSX_BASE_DIR + File.separator + ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim()
|
return FileSystemContentRepository.MIFOSX_BASE_DIR + File.separator
|
||||||
+ File.separator + "documents" + File.separator + entityType + File.separator + entityId + File.separator
|
+ ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim() + File.separator + "documents" + File.separator
|
||||||
+ RandomStringGenerator.generateRandomString();
|
+ entityType + File.separator + entityId + File.separator + ContentRepositoryUtils.generateRandomString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate directory path for storing new Image
|
* Generate directory path for storing new Image
|
||||||
*/
|
*/
|
||||||
private String generateClientImageParentDirectory(final Long resourceId) {
|
private String generateClientImageParentDirectory(final Long resourceId) {
|
||||||
return FileSystemDocumentStore.MIFOSX_BASE_DIR + File.separator + ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim()
|
return FileSystemContentRepository.MIFOSX_BASE_DIR + File.separator
|
||||||
+ File.separator + "images" + File.separator + "clients" + File.separator + resourceId;
|
+ 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(String fileName, InputStream uploadedInputStream, String fileLocation) {
|
||||||
private void writeFileToFileSystem(InputStream uploadedInputStream, String fileLocation) throws DocumentManagementException {
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
OutputStream out = new FileOutputStream(new File(fileLocation));
|
OutputStream out = new FileOutputStream(new File(fileLocation));
|
||||||
int read = 0;
|
int read = 0;
|
||||||
@@ -153,8 +158,7 @@ public class FileSystemDocumentStore extends DocumentStore {
|
|||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException ioException) {
|
} 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;
|
package org.mifosplatform.infrastructure.documentmanagement.data;
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.service.DocumentStore;
|
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
|
||||||
import org.mifosplatform.infrastructure.core.service.DocumentStoreType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable data object represent document being managed on platform.
|
* Immutable data object represent document being managed on platform.
|
||||||
*/
|
*/
|
||||||
public class DocumentData {
|
public class DocumentData {
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final Long id;
|
private final Long id;
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final String parentEntityType;
|
private final String parentEntityType;
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final Long parentEntityId;
|
private final Long parentEntityId;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final String name;
|
private final String name;
|
||||||
@@ -27,12 +23,11 @@ public class DocumentData {
|
|||||||
private final String type;
|
private final String type;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final String description;
|
private final String description;
|
||||||
private String location;
|
private final String location;
|
||||||
|
private final Integer storageType;
|
||||||
private String storageType;
|
|
||||||
|
|
||||||
public DocumentData(final Long id, final String parentEntityType, final Long parentEntityId, final String name, final String fileName,
|
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.id = id;
|
||||||
this.parentEntityType = parentEntityType;
|
this.parentEntityType = parentEntityType;
|
||||||
this.parentEntityId = parentEntityId;
|
this.parentEntityId = parentEntityId;
|
||||||
@@ -57,23 +52,19 @@ public class DocumentData {
|
|||||||
return this.location;
|
return this.location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocation(final String location) {
|
public StorageType storageType() {
|
||||||
this.location = location;
|
return StorageType.fromInt(storageType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DocumentStoreType storeType(){
|
public String getParentEntityType() {
|
||||||
return DocumentStore.getDocumentStoreType(storageType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getParentEntityType(){
|
|
||||||
return this.parentEntityType;
|
return this.parentEntityType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getParentEntityId(){
|
public Long getParentEntityId() {
|
||||||
return this.parentEntityId;
|
return this.parentEntityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getId(){
|
public Long getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-11
@@ -9,6 +9,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class FileData {
|
public class FileData {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(FileData.class);
|
private static final Logger logger = LoggerFactory.getLogger(FileData.class);
|
||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
@@ -38,19 +39,13 @@ public class FileData {
|
|||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream file(){
|
public InputStream file() {
|
||||||
try{
|
try {
|
||||||
if(inputStream == null){
|
if (inputStream == null) { return new FileInputStream(file); }
|
||||||
return new FileInputStream(file);
|
return inputStream;
|
||||||
}
|
} catch (FileNotFoundException e) {
|
||||||
else {
|
|
||||||
return inputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (FileNotFoundException e){
|
|
||||||
logger.error(e.toString());
|
logger.error(e.toString());
|
||||||
return null;
|
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;
|
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.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
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
|
@Entity
|
||||||
@Table(name = "m_document")
|
@Table(name = "m_document")
|
||||||
public class Document extends AbstractPersistable<Long> {
|
public class Document extends AbstractPersistable<Long> {
|
||||||
@@ -43,19 +41,18 @@ public class Document extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "location", length = 500)
|
@Column(name = "location", length = 500)
|
||||||
private String location;
|
private String location;
|
||||||
|
|
||||||
@Column(name = "storage_type", length = 50)
|
@Column(name = "storage_type_enum")
|
||||||
private String storageType;
|
private Integer storageType;
|
||||||
|
|
||||||
public Document() {
|
public Document() {}
|
||||||
}
|
|
||||||
|
|
||||||
public static Document createNew(final String parentEntityType, final Long parentEntityId, final String name, final String fileName,
|
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);
|
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,
|
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.parentEntityType = StringUtils.defaultIfEmpty(parentEntityType, null);
|
||||||
this.parentEntityId = parentEntityId;
|
this.parentEntityId = parentEntityId;
|
||||||
this.name = StringUtils.defaultIfEmpty(name, null);
|
this.name = StringUtils.defaultIfEmpty(name, null);
|
||||||
@@ -86,7 +83,6 @@ public class Document extends AbstractPersistable<Long> {
|
|||||||
if (command.isSizeChanged()) {
|
if (command.isSizeChanged()) {
|
||||||
this.size = command.getSize();
|
this.size = command.getSize();
|
||||||
}
|
}
|
||||||
this.storageType = command.getStorageType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getParentEntityType() {
|
public String getParentEntityType() {
|
||||||
@@ -153,7 +149,7 @@ public class Document extends AbstractPersistable<Long> {
|
|||||||
this.location = location;
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DocumentStoreType storageType(){
|
public StorageType storageType() {
|
||||||
return DocumentStore.getDocumentStoreType(this.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,
|
* 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/.
|
* 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.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
public interface ImageRepository extends JpaRepository<Image, Long>, JpaSpecificationExecutor<Client> {
|
public interface ImageRepository extends JpaRepository<Image, Long>, JpaSpecificationExecutor<Client> {}
|
||||||
Image findOneByClient(Client 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;
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||||
|
|
||||||
public class DocumentManagementException extends AbstractPlatformDomainRuleException {
|
public class ContentManagementException extends AbstractPlatformDomainRuleException {
|
||||||
|
|
||||||
public DocumentManagementException(final String name) {
|
public ContentManagementException(final String filename, final String message) {
|
||||||
super("error.msg.document.save", "Error while manipulating file " + name + " due to a File system / Amazon S3 issue", name);
|
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
|
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);
|
/ (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);
|
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);
|
DocumentData retrieveDocument(String entityType, Long entityId, Long documentId);
|
||||||
|
|
||||||
|
|||||||
+36
-30
@@ -6,9 +6,9 @@
|
|||||||
package org.mifosplatform.infrastructure.documentmanagement.service;
|
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
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.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.DocumentData;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||||
@@ -28,14 +28,14 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
|
|||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final DocumentStoreFactory documentStoreFactory;
|
private final ContentRepositoryFactory contentRepositoryFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public DocumentReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
public DocumentReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
||||||
final DocumentStoreFactory documentStoreFactory) {
|
final ContentRepositoryFactory documentStoreFactory) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
this.documentStoreFactory = documentStoreFactory;
|
this.contentRepositoryFactory = documentStoreFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -46,46 +46,60 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
|
|||||||
// TODO verify if the entities are valid and a user
|
// TODO verify if the entities are valid and a user
|
||||||
// has data
|
// has data
|
||||||
// scope for the particular entities
|
// 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";
|
final String sql = "select " + mapper.schema() + " order by d.id";
|
||||||
return this.jdbcTemplate.query(sql, mapper, new Object[] { entityType, entityId });
|
return this.jdbcTemplate.query(sql, mapper, new Object[] { entityType, entityId });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
try {
|
||||||
DocumentData documentData = getDocumentData(entityType, entityId, documentId);
|
final DocumentMapper mapper = new DocumentMapper(false, false);
|
||||||
DocumentStore instanceForRead = documentStoreFactory.getInstanceFromStorageType(documentData.storeType());
|
DocumentData documentData = fetchDocumentDetails(entityType, entityId, documentId, mapper);
|
||||||
return instanceForRead.retrieveDocument(documentData);
|
ContentRepository contentRepository = contentRepositoryFactory.getRepository(documentData.storageType());
|
||||||
|
return contentRepository.fetchFile(documentData);
|
||||||
} catch (final EmptyResultDataAccessException e) {
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
throw new DocumentNotFoundException(entityType, entityId, documentId);
|
throw new DocumentNotFoundException(entityType, entityId, documentId);
|
||||||
} catch (final DocumentNotFoundException d) {
|
|
||||||
throw d;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DocumentData retrieveDocument(String entityType, Long entityId, Long documentId) {
|
public DocumentData retrieveDocument(String entityType, Long entityId, Long documentId) {
|
||||||
try {
|
try {
|
||||||
return getDocumentData(entityType, entityId, documentId);
|
final DocumentMapper mapper = new DocumentMapper(true, true);
|
||||||
|
return fetchDocumentDetails(entityType, entityId, documentId, mapper);
|
||||||
} catch (final EmptyResultDataAccessException e) {
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
throw new DocumentNotFoundException(entityType, entityId, documentId);
|
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 static final class DocumentMapper implements RowMapper<DocumentData> {
|
||||||
|
|
||||||
private final boolean hideLocation;
|
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.hideLocation = hideLocation;
|
||||||
|
this.hideStorageType = hideStorageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String schema() {
|
public String schema() {
|
||||||
return "d.id as id, d.parent_entity_type as parentEntityType, d.parent_entity_id as parentEntityId, d.name as name, "
|
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.file_name as fileName, d.size as fileSize, d.type as fileType, "
|
||||||
+ " d.description as description, d.location as location,"
|
+ " d.description as description, d.location as location," + " d.storage_type_enum as storageType"
|
||||||
+ " d.storage_type as storageType"
|
|
||||||
+ " from m_document d where d.parent_entity_type=? and d.parent_entity_id=?";
|
+ " 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 fileType = rs.getString("fileType");
|
||||||
final String description = rs.getString("description");
|
final String description = rs.getString("description");
|
||||||
String location = null;
|
String location = null;
|
||||||
|
Integer storageType = null;
|
||||||
if (!this.hideLocation) {
|
if (!this.hideLocation) {
|
||||||
location = rs.getString("location");
|
location = rs.getString("location");
|
||||||
}
|
}
|
||||||
final String storageType = rs.getString("storageType");
|
if (!this.hideStorageType) {
|
||||||
|
storageType = rs.getInt("storageType");
|
||||||
return new DocumentData(id, parentEntityType, parentEntityId, name, fileName, fileSize, fileType, description, location, 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;
|
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
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.DocumentCommand;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommandValidator;
|
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.Document;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.domain.DocumentRepository;
|
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.DocumentNotFoundException;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.exception.InvalidEntityTypeForDocumentManagementException;
|
import org.mifosplatform.infrastructure.documentmanagement.exception.InvalidEntityTypeForDocumentManagementException;
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
@@ -25,8 +27,6 @@ import org.springframework.dao.DataIntegrityViolationException;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWritePlatformService {
|
public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWritePlatformService {
|
||||||
|
|
||||||
@@ -34,14 +34,14 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
|||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final DocumentRepository documentRepository;
|
private final DocumentRepository documentRepository;
|
||||||
private final DocumentStoreFactory documentStoreFactory;
|
private final ContentRepositoryFactory contentRepositoryFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public DocumentWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final DocumentRepository documentRepository,
|
public DocumentWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
final DocumentStoreFactory documentStoreFactory) {
|
final DocumentRepository documentRepository, final ContentRepositoryFactory documentStoreFactory) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.documentRepository = documentRepository;
|
this.documentRepository = documentRepository;
|
||||||
this.documentStoreFactory = documentStoreFactory;
|
this.contentRepositoryFactory = documentStoreFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -56,13 +56,13 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
|||||||
|
|
||||||
validator.validateForCreate();
|
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(),
|
final Document document = Document.createNew(documentCommand.getParentEntityType(), documentCommand.getParentEntityId(),
|
||||||
documentCommand.getName(), documentCommand.getFileName(), documentCommand.getSize(), documentCommand.getType(),
|
documentCommand.getName(), documentCommand.getFileName(), documentCommand.getSize(), documentCommand.getType(),
|
||||||
documentCommand.getDescription(), fileLocation, documentStore.getType());
|
documentCommand.getDescription(), fileLocation, contentRepository.getStorageType());
|
||||||
|
|
||||||
this.documentRepository.save(document);
|
this.documentRepository.save(document);
|
||||||
|
|
||||||
@@ -71,9 +71,6 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
|||||||
logger.error(dve.getMessage(), dve);
|
logger.error(dve.getMessage(), dve);
|
||||||
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
|
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
|
||||||
"Unknown data integrity issue with resource.");
|
"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
|
// TODO check if entity id is valid and within data scope for the
|
||||||
// user
|
// user
|
||||||
final Document documentForUpdate = this.documentRepository.findOne(documentCommand.getId());
|
final Document documentForUpdate = this.documentRepository.findOne(documentCommand.getId());
|
||||||
DocumentStoreType documentStoreType = documentForUpdate.storageType();
|
|
||||||
if (documentForUpdate == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
|
if (documentForUpdate == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
|
||||||
documentCommand.getParentEntityId(), documentCommand.getId()); }
|
documentCommand.getParentEntityId(), documentCommand.getId()); }
|
||||||
|
|
||||||
|
StorageType documentStoreType = documentForUpdate.storageType();
|
||||||
oldLocation = documentForUpdate.getLocation();
|
oldLocation = documentForUpdate.getLocation();
|
||||||
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
||||||
DocumentStore instanceFromConfiguration = this.documentStoreFactory.getInstanceFromConfiguration();
|
ContentRepository contentRepository = this.contentRepositoryFactory.getRepository();
|
||||||
documentCommand.setLocation(instanceFromConfiguration.saveDocument(inputStream, documentCommand));
|
documentCommand.setLocation(contentRepository.saveFile(inputStream, documentCommand));
|
||||||
documentCommand.setStorageType(instanceFromConfiguration.getType());
|
documentCommand.setStorageType(contentRepository.getStorageType().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
documentForUpdate.update(documentCommand);
|
documentForUpdate.update(documentCommand);
|
||||||
|
|
||||||
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
||||||
DocumentStore documentStore = this.documentStoreFactory.getInstanceFromStorageType(documentStoreType);
|
ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(documentStoreType);
|
||||||
documentStore.deleteDocument(documentCommand.getName(), oldLocation);
|
contentRepository.deleteFile(documentCommand.getName(), oldLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.documentRepository.saveAndFlush(documentForUpdate);
|
this.documentRepository.saveAndFlush(documentForUpdate);
|
||||||
@@ -113,9 +111,9 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
|||||||
logger.error(dve.getMessage(), dve);
|
logger.error(dve.getMessage(), dve);
|
||||||
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
|
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
|
||||||
"Unknown data integrity issue with resource.");
|
"Unknown data integrity issue with resource.");
|
||||||
} catch (final DocumentManagementException dme) {
|
} catch (final ContentManagementException cme) {
|
||||||
logger.error(dme.getMessage(), dme);
|
logger.error(cme.getMessage(), cme);
|
||||||
throw new DocumentManagementException(documentCommand.getName());
|
throw new ContentManagementException(documentCommand.getName(), cme.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,12 +125,12 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
|||||||
validateParentEntityType(documentCommand);
|
validateParentEntityType(documentCommand);
|
||||||
// TODO: Check document is present under this entity Id
|
// TODO: Check document is present under this entity Id
|
||||||
final Document document = this.documentRepository.findOne(documentCommand.getId());
|
final Document document = this.documentRepository.findOne(documentCommand.getId());
|
||||||
DocumentStore documentStore = this.documentStoreFactory.getInstanceFromStorageType(document.storageType());
|
|
||||||
if (document == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
|
if (document == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
|
||||||
documentCommand.getParentEntityId(), documentCommand.getId()); }
|
documentCommand.getParentEntityId(), documentCommand.getId()); }
|
||||||
|
|
||||||
this.documentRepository.delete(document);
|
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());
|
return new CommandProcessingResult(document.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +140,6 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkValidEntityType(final String entityType) {
|
private static boolean checkValidEntityType(final String entityType) {
|
||||||
|
|
||||||
for (final DOCUMENT_MANAGEMENT_ENTITY entities : DOCUMENT_MANAGEMENT_ENTITY.values()) {
|
for (final DOCUMENT_MANAGEMENT_ENTITY entities : DOCUMENT_MANAGEMENT_ENTITY.values()) {
|
||||||
if (entities.name().equalsIgnoreCase(entityType)) { return true; }
|
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;
|
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.StringUtils;
|
||||||
import org.apache.commons.lang.builder.CompareToBuilder;
|
import org.apache.commons.lang.builder.CompareToBuilder;
|
||||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
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.infrastructure.core.data.EnumOptionData;
|
||||||
import org.mifosplatform.organisation.office.data.OfficeData;
|
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||||
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
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.
|
* Immutable data object representing client data.
|
||||||
*/
|
*/
|
||||||
final public class ClientData implements Comparable<ClientData> {
|
final public class ClientData implements Comparable<ClientData> {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(ClientData.class);
|
|
||||||
|
|
||||||
|
|
||||||
private final Long id;
|
private final Long id;
|
||||||
private final String accountNo;
|
private final String accountNo;
|
||||||
@@ -46,9 +41,7 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
private final Long officeId;
|
private final Long officeId;
|
||||||
private final String officeName;
|
private final String officeName;
|
||||||
|
|
||||||
// private String imageData;
|
private final Long imageId;
|
||||||
private ImageData imageData;
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final Boolean imagePresent;
|
private final Boolean imagePresent;
|
||||||
|
|
||||||
// associations
|
// 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,
|
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
|
||||||
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
|
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) {
|
public static ClientData setParentGroups(final ClientData clientData, final Collection<GroupGeneralData> parentGroups) {
|
||||||
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
|
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
|
||||||
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
|
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,
|
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,
|
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 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,
|
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,
|
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 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) {
|
final Collection<GroupGeneralData> groups) {
|
||||||
this.accountNo = accountNo;
|
this.accountNo = accountNo;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
@@ -114,11 +107,11 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
this.displayName = StringUtils.defaultIfEmpty(displayName, null);
|
this.displayName = StringUtils.defaultIfEmpty(displayName, null);
|
||||||
this.externalId = StringUtils.defaultIfEmpty(externalId, null);
|
this.externalId = StringUtils.defaultIfEmpty(externalId, null);
|
||||||
this.activationDate = activationDate;
|
this.activationDate = activationDate;
|
||||||
this.imageData = imageKey;
|
this.imageId = imageId;
|
||||||
if (imageKey != null) {
|
if (imageId != null) {
|
||||||
this.imagePresent = Boolean.TRUE;
|
this.imagePresent = Boolean.TRUE;
|
||||||
} else {
|
} else {
|
||||||
this.imagePresent = null;
|
this.imagePresent = Boolean.FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// associations
|
// associations
|
||||||
@@ -144,17 +137,14 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
return this.officeName;
|
return this.officeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String imageKey() {
|
public Long getImageId() {
|
||||||
return this.imageData.imageKey();
|
return this.imageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean imageKeyDoesNotExist() {
|
public Boolean getImagePresent() {
|
||||||
return imageData.equals(null) && !imageKeyExists();
|
return this.imagePresent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean imageKeyExists() {
|
|
||||||
return StringUtils.isNotBlank(this.imageData.imageKey());
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(final ClientData obj) {
|
public int compareTo(final ClientData obj) {
|
||||||
if (obj == null) { return -1; }
|
if (obj == null) { return -1; }
|
||||||
@@ -201,24 +191,4 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
return this.activationDate;
|
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.data.DataValidatorBuilder;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.domain.Image;
|
||||||
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
|
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
|
||||||
import org.mifosplatform.organisation.office.domain.Office;
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
|
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 org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@@ -33,6 +35,10 @@ public final class Client extends AbstractPersistable<Long> {
|
|||||||
@JoinColumn(name = "office_id", nullable = false)
|
@JoinColumn(name = "office_id", nullable = false)
|
||||||
private Office office;
|
private Office office;
|
||||||
|
|
||||||
|
@OneToOne(optional = true)
|
||||||
|
@JoinColumn(name = "image_id", nullable = true)
|
||||||
|
private Image image;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A value from {@link ClientStatus}.
|
* A value from {@link ClientStatus}.
|
||||||
*/
|
*/
|
||||||
@@ -55,7 +61,6 @@ public final class Client extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "fullname", length = 100)
|
@Column(name = "fullname", length = 100)
|
||||||
private String fullname;
|
private String fullname;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@Column(name = "display_name", length = 100, nullable = false)
|
@Column(name = "display_name", length = 100, nullable = false)
|
||||||
private String displayName;
|
private String displayName;
|
||||||
|
|
||||||
@@ -365,15 +370,24 @@ public final class Client extends AbstractPersistable<Long> {
|
|||||||
return this.office.identifiedBy(officeId);
|
return this.office.identifiedBy(officeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public String imageKey() {
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void updateImageKey(final String imageKey) {
|
|
||||||
// this.image.setKey(imageKey);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public Long officeId() {
|
public Long officeId() {
|
||||||
return this.office.getId();
|
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.api.ApiParameterHelper;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
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.Page;
|
||||||
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
|
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
|
||||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
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.ClientAccountSummaryCollectionData;
|
||||||
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
|
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
|
||||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
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.domain.ClientEnumerations;
|
||||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||||
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||||
@@ -43,11 +41,9 @@ import org.springframework.stereotype.Service;
|
|||||||
@Service
|
@Service
|
||||||
public class ClientReadPlatformServiceImpl implements ClientReadPlatformService {
|
public class ClientReadPlatformServiceImpl implements ClientReadPlatformService {
|
||||||
|
|
||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final OfficeReadPlatformService officeReadPlatformService;
|
private final OfficeReadPlatformService officeReadPlatformService;
|
||||||
private final DocumentStoreFactory documentStoreFactory;
|
|
||||||
|
|
||||||
// data mappers
|
// data mappers
|
||||||
private final PaginationHelper<ClientData> paginationHelper = new PaginationHelper<ClientData>();
|
private final PaginationHelper<ClientData> paginationHelper = new PaginationHelper<ClientData>();
|
||||||
@@ -58,10 +54,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
||||||
final OfficeReadPlatformService officeReadPlatformService, final DocumentStoreFactory documentStoreFactory) {
|
final OfficeReadPlatformService officeReadPlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.officeReadPlatformService = officeReadPlatformService;
|
this.officeReadPlatformService = officeReadPlatformService;
|
||||||
this.documentStoreFactory = documentStoreFactory;
|
|
||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,12 +173,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
|||||||
Collection<GroupGeneralData> parentGroups = this.jdbcTemplate.query(clientGroupsSql, this.clientGroupsMapper,
|
Collection<GroupGeneralData> parentGroups = this.jdbcTemplate.query(clientGroupsSql, this.clientGroupsMapper,
|
||||||
new Object[] { clientId });
|
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);
|
return ClientData.setParentGroups(clientData, parentGroups);
|
||||||
|
|
||||||
} catch (EmptyResultDataAccessException e) {
|
} 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.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.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.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("from m_client c ");
|
||||||
sqlBuilder.append("join m_office o on o.id = c.office_id ");
|
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");
|
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 displayName = rs.getString("displayName");
|
||||||
final String externalId = rs.getString("externalId");
|
final String externalId = rs.getString("externalId");
|
||||||
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
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");
|
final String officeName = rs.getString("officeName");
|
||||||
|
|
||||||
return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
|
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.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.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.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("from m_client c ");
|
||||||
builder.append("join m_office o on o.id = c.office_id ");
|
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 displayName = rs.getString("displayName");
|
||||||
final String externalId = rs.getString("externalId");
|
final String externalId = rs.getString("externalId");
|
||||||
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
||||||
// final String imageKey = rs.getString("imageKey");
|
|
||||||
final String officeName = rs.getString("officeName");
|
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,
|
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> {
|
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 static final class ClientLookupMapper implements RowMapper<ClientData> {
|
||||||
|
|
||||||
private final String schema;
|
private final String schema;
|
||||||
|
|||||||
-12
@@ -5,12 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.client.service;
|
package org.mifosplatform.portfolio.client.service;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
|
|
||||||
public interface ClientWritePlatformService {
|
public interface ClientWritePlatformService {
|
||||||
|
|
||||||
@@ -22,12 +18,4 @@ public interface ClientWritePlatformService {
|
|||||||
|
|
||||||
CommandProcessingResult deleteClient(Long clientId);
|
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;
|
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.LocalDate;
|
||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
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.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.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.mifosplatform.organisation.office.domain.Office;
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
import org.mifosplatform.organisation.office.domain.OfficeRepository;
|
import org.mifosplatform.organisation.office.domain.OfficeRepository;
|
||||||
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
|
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
|
||||||
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
|
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
|
||||||
import org.mifosplatform.portfolio.client.data.ClientDataValidator;
|
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.ClientMustBePendingToBeDeletedException;
|
||||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
|
||||||
import org.mifosplatform.portfolio.group.domain.Group;
|
import org.mifosplatform.portfolio.group.domain.Group;
|
||||||
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
||||||
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
||||||
@@ -38,11 +39,6 @@ import org.springframework.dao.DataIntegrityViolationException;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWritePlatformService {
|
public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWritePlatformService {
|
||||||
|
|
||||||
@@ -55,14 +51,12 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
|||||||
private final GroupRepository groupRepository;
|
private final GroupRepository groupRepository;
|
||||||
private final ClientDataValidator fromApiJsonDeserializer;
|
private final ClientDataValidator fromApiJsonDeserializer;
|
||||||
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
|
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
|
||||||
private final DocumentStoreFactory documentStoreFactory;
|
|
||||||
private final ImageRepository imageRepository;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository,
|
final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository,
|
||||||
final ClientDataValidator fromApiJsonDeserializer, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
|
final ClientDataValidator fromApiJsonDeserializer, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
|
||||||
final GroupRepository groupRepository, DocumentStoreFactory documentStoreFactory, ImageRepository imageRepository) {
|
final GroupRepository groupRepository) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.clientRepository = clientRepository;
|
this.clientRepository = clientRepository;
|
||||||
this.officeRepository = officeRepository;
|
this.officeRepository = officeRepository;
|
||||||
@@ -70,8 +64,6 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
|||||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||||
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
|
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
|
||||||
this.groupRepository = groupRepository;
|
this.groupRepository = groupRepository;
|
||||||
this.documentStoreFactory = documentStoreFactory;
|
|
||||||
this.imageRepository = imageRepository;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@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) {
|
private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) {
|
||||||
logger.error(dve.getMessage(), dve);
|
logger.error(dve.getMessage(), dve);
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-21
@@ -1,28 +1,28 @@
|
|||||||
package org.mifosplatform.infrastructure.core.service;
|
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.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
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.mockito.runners.MockitoJUnitRunner;
|
||||||
import org.springframework.context.ApplicationContext;
|
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)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class DocumentStoreFactoryTest {
|
public class DocumentStoreFactoryTest {
|
||||||
|
/**
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnS3DocumentStoreObjectIfS3Enabled(){
|
public void shouldReturnS3DocumentStoreObjectIfS3Enabled() {
|
||||||
S3ClientFactory s3ClientFactoryMock = mock(S3ClientFactory.class);
|
S3ClientFactory s3ClientFactoryMock = mock(S3ClientFactory.class);
|
||||||
when(s3ClientFactoryMock.getS3Client()).thenReturn(null);
|
when(s3ClientFactoryMock.getS3Client()).thenReturn(null);
|
||||||
|
|
||||||
ExternalServicesDomainService externalServicesDomainServiceMock = mock(ExternalServicesDomainService.class);
|
ExternalServicesReadPlatformServiceImpl externalServicesDomainServiceMock = mock(ExternalServicesReadPlatformServiceImpl.class);
|
||||||
when(externalServicesDomainServiceMock.getValue("s3_bucket_name")).thenReturn("bucket_name");
|
when(externalServicesDomainServiceMock.getValue("s3_bucket_name")).thenReturn("bucket_name");
|
||||||
|
|
||||||
ConfigurationDomainService configurationDomainServiceMock = mock(ConfigurationDomainService.class);
|
ConfigurationDomainService configurationDomainServiceMock = mock(ConfigurationDomainService.class);
|
||||||
@@ -30,26 +30,27 @@ public class DocumentStoreFactoryTest {
|
|||||||
|
|
||||||
ApplicationContext applicationContextMock = mock(ApplicationContext.class);
|
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("s3ClientFactory", S3ClientFactory.class)).thenReturn(s3ClientFactoryMock);
|
||||||
when(applicationContextMock.getBean("externalServicesDomainService", ExternalServicesDomainService.class)).thenReturn(externalServicesDomainServiceMock);
|
when(applicationContextMock.getBean("externalServicesDomainService", ExternalServicesReadPlatformServiceImpl.class)).thenReturn(
|
||||||
|
externalServicesDomainServiceMock);
|
||||||
|
|
||||||
|
ContentRepositoryFactory documentStoreFactory = new ContentRepositoryFactory(applicationContextMock);
|
||||||
DocumentStoreFactory documentStoreFactory = new DocumentStoreFactory(applicationContextMock);
|
assertEquals(documentStoreFactory.getInstanceFromConfiguration().getClass(), S3ContentRepository.class);
|
||||||
assertEquals(documentStoreFactory.getInstanceFromConfiguration().getClass(),S3DocumentStore.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnFileSystemDocumentStoreObjectIfS3IsDisabled(){
|
public void shouldReturnFileSystemDocumentStoreObjectIfS3IsDisabled() {
|
||||||
ConfigurationDomainService configurationDomainService = mock(ConfigurationDomainService.class);
|
ConfigurationDomainService configurationDomainService = mock(ConfigurationDomainService.class);
|
||||||
when(configurationDomainService.isAmazonS3Enabled()).thenReturn(false);
|
when(configurationDomainService.isAmazonS3Enabled()).thenReturn(false);
|
||||||
|
|
||||||
ApplicationContext applicationContext = mock(ApplicationContext.class);
|
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);
|
ContentRepositoryFactory documentStoreFactory = new ContentRepositoryFactory(applicationContext);
|
||||||
assertEquals(documentStoreFactory.getInstanceFromConfiguration().getClass(),FileSystemDocumentStore.class);
|
assertEquals(documentStoreFactory.getInstanceFromConfiguration().getClass(), FileSystemContentRepository.class);
|
||||||
}
|
}
|
||||||
|
**/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -1,23 +1,22 @@
|
|||||||
package org.mifosplatform.infrastructure.core.service;
|
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.Test;
|
||||||
import org.junit.runner.RunWith;
|
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.DocumentData;
|
||||||
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
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)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class FileDocumentStoreTest {
|
public class FileDocumentStoreTest {
|
||||||
|
/**
|
||||||
@Test
|
@Test
|
||||||
public void shouldRetrieveDocument(){
|
public void shouldRetrieveDocument() {
|
||||||
FileSystemDocumentStore fileSystemDocumentStore = new FileSystemDocumentStore();
|
FileSystemContentRepository fileSystemDocumentStore = new FileSystemContentRepository();
|
||||||
DocumentData documentDataMock = mock(DocumentData.class);
|
DocumentData documentDataMock = mock(DocumentData.class);
|
||||||
when(documentDataMock.fileName()).thenReturn("some_file");
|
when(documentDataMock.fileName()).thenReturn("some_file");
|
||||||
when(documentDataMock.fileName()).thenReturn("content_type");
|
when(documentDataMock.fileName()).thenReturn("content_type");
|
||||||
@@ -28,4 +27,5 @@ public class FileDocumentStoreTest {
|
|||||||
assertEquals(fileData.name(), documentDataMock.fileName());
|
assertEquals(fileData.name(), documentDataMock.fileName());
|
||||||
assertEquals(fileData.contentType(), documentDataMock.contentType());
|
assertEquals(fileData.contentType(), documentDataMock.contentType());
|
||||||
}
|
}
|
||||||
|
**/
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-42
@@ -1,27 +1,34 @@
|
|||||||
package org.mifosplatform.infrastructure.core.service;
|
package org.mifosplatform.infrastructure.core.service;
|
||||||
|
|
||||||
import com.amazonaws.AmazonClientException;
|
import static org.junit.Assert.assertEquals;
|
||||||
import com.amazonaws.AmazonServiceException;
|
import static org.junit.Assert.assertTrue;
|
||||||
import com.amazonaws.services.s3.AmazonS3Client;
|
import static org.mockito.Mockito.mock;
|
||||||
import com.amazonaws.services.s3.model.*;
|
import static org.mockito.Mockito.times;
|
||||||
import org.junit.Test;
|
import static org.mockito.Mockito.verify;
|
||||||
import org.junit.runner.RunWith;
|
import static org.mockito.Mockito.when;
|
||||||
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 java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertTrue;
|
import org.junit.runner.RunWith;
|
||||||
import static org.mockito.Mockito.*;
|
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)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class S3DocumentStoreTest {
|
public class S3DocumentStoreTest {
|
||||||
@@ -30,17 +37,17 @@ public class S3DocumentStoreTest {
|
|||||||
AmazonS3Client s3ClientMock;
|
AmazonS3Client s3ClientMock;
|
||||||
DocumentCommand documentCommand;
|
DocumentCommand documentCommand;
|
||||||
DocumentData documentDataMock;
|
DocumentData documentDataMock;
|
||||||
|
/**
|
||||||
@Test
|
@Test
|
||||||
public void shouldGenerateParentDirectoryFromEntityDetails(){
|
public void shouldGenerateParentDirectoryFromEntityDetails() {
|
||||||
S3DocumentStore s3DocumentStore=new S3DocumentStore("bucketName", null);
|
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", null);
|
||||||
String actualParentDirectory = s3DocumentStore.generateFileParentDirectory("entity_type", 1234L);
|
String actualParentDirectory = s3DocumentStore.generateFileParentDirectory("entity_type", 1234L);
|
||||||
assertTrue(actualParentDirectory.startsWith("documents/entity_type/1234"));
|
assertTrue(actualParentDirectory.startsWith("documents/entity_type/1234"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldGenerateClientImageDirectoryFromResourceId(){
|
public void shouldGenerateClientImageDirectoryFromResourceId() {
|
||||||
S3DocumentStore s3DocumentStore=new S3DocumentStore("bucketName", null);
|
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", null);
|
||||||
String actualParentDirectory = s3DocumentStore.generateClientImageParentDirectory(1234L);
|
String actualParentDirectory = s3DocumentStore.generateClientImageParentDirectory(1234L);
|
||||||
assertTrue(actualParentDirectory.startsWith("images/clients/1234"));
|
assertTrue(actualParentDirectory.startsWith("images/clients/1234"));
|
||||||
}
|
}
|
||||||
@@ -48,20 +55,20 @@ public class S3DocumentStoreTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldSaveADocumentToS3() throws IOException {
|
public void shouldSaveADocumentToS3() throws IOException {
|
||||||
initUpload();
|
initUpload();
|
||||||
when(s3ClientMock.putObject(Matchers.<PutObjectRequest>anyObject())).thenReturn(new PutObjectResult());
|
when(s3ClientMock.putObject(Matchers.<PutObjectRequest> anyObject())).thenReturn(new PutObjectResult());
|
||||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName", s3ClientMock);
|
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||||
|
|
||||||
s3DocumentStore.saveDocument(inputStream, documentCommand);
|
s3DocumentStore.saveDocument(inputStream, documentCommand);
|
||||||
|
|
||||||
verify(s3ClientMock, times(1)).putObject(Matchers.<PutObjectRequest>anyObject());
|
verify(s3ClientMock, times(1)).putObject(Matchers.<PutObjectRequest> anyObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DocumentManagementException.class)
|
@Test(expected = DocumentManagementException.class)
|
||||||
public void shouldCatchAmazonServiceExceptionWhenUnableToUploadDocumentToS3() throws IOException {
|
public void shouldCatchAmazonServiceExceptionWhenUnableToUploadDocumentToS3() throws IOException {
|
||||||
initUpload();
|
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);
|
s3DocumentStore.saveDocument(inputStream, documentCommand);
|
||||||
}
|
}
|
||||||
@@ -69,9 +76,9 @@ public class S3DocumentStoreTest {
|
|||||||
@Test(expected = DocumentManagementException.class)
|
@Test(expected = DocumentManagementException.class)
|
||||||
public void shouldCatchAmazonClientExceptionWhenUnableToUploadDocumentToS3() throws IOException {
|
public void shouldCatchAmazonClientExceptionWhenUnableToUploadDocumentToS3() throws IOException {
|
||||||
initUpload();
|
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);
|
s3DocumentStore.saveDocument(inputStream, documentCommand);
|
||||||
}
|
}
|
||||||
@@ -79,12 +86,12 @@ public class S3DocumentStoreTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldRetrieveDocumentFromS3() throws IOException {
|
public void shouldRetrieveDocumentFromS3() throws IOException {
|
||||||
initRetrieve();
|
initRetrieve();
|
||||||
when(s3ClientMock.getObject(Matchers.<GetObjectRequest>anyObject())).thenReturn(new S3Object());
|
when(s3ClientMock.getObject(Matchers.<GetObjectRequest> anyObject())).thenReturn(new S3Object());
|
||||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName",s3ClientMock);
|
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||||
|
|
||||||
FileData fileData = s3DocumentStore.retrieveDocument(documentDataMock);
|
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.name(), "name");
|
||||||
assertEquals(fileData.contentType(), "type");
|
assertEquals(fileData.contentType(), "type");
|
||||||
}
|
}
|
||||||
@@ -92,8 +99,8 @@ public class S3DocumentStoreTest {
|
|||||||
@Test(expected = DocumentNotFoundException.class)
|
@Test(expected = DocumentNotFoundException.class)
|
||||||
public void shouldCatchAmazonServiceExceptionWhenUnableToRetrieveDocumentFromS3() throws IOException {
|
public void shouldCatchAmazonServiceExceptionWhenUnableToRetrieveDocumentFromS3() throws IOException {
|
||||||
initRetrieve();
|
initRetrieve();
|
||||||
when(s3ClientMock.getObject(Matchers.<GetObjectRequest>anyObject())).thenThrow(new AmazonServiceException("serviceException"));
|
when(s3ClientMock.getObject(Matchers.<GetObjectRequest> anyObject())).thenThrow(new AmazonServiceException("serviceException"));
|
||||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName",s3ClientMock);
|
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||||
|
|
||||||
s3DocumentStore.retrieveDocument(documentDataMock);
|
s3DocumentStore.retrieveDocument(documentDataMock);
|
||||||
}
|
}
|
||||||
@@ -101,8 +108,8 @@ public class S3DocumentStoreTest {
|
|||||||
@Test(expected = DocumentNotFoundException.class)
|
@Test(expected = DocumentNotFoundException.class)
|
||||||
public void shouldCatchAmazonClientExceptionWhenUnableToRetrieveDocumentFromS3() throws IOException {
|
public void shouldCatchAmazonClientExceptionWhenUnableToRetrieveDocumentFromS3() throws IOException {
|
||||||
initRetrieve();
|
initRetrieve();
|
||||||
when(s3ClientMock.getObject(Matchers.<GetObjectRequest>anyObject())).thenThrow(new AmazonClientException("clientException"));
|
when(s3ClientMock.getObject(Matchers.<GetObjectRequest> anyObject())).thenThrow(new AmazonClientException("clientException"));
|
||||||
S3DocumentStore s3DocumentStore = new S3DocumentStore("bucketName",s3ClientMock);
|
S3ContentRepository s3DocumentStore = new S3ContentRepository("bucketName", s3ClientMock);
|
||||||
|
|
||||||
s3DocumentStore.retrieveDocument(documentDataMock);
|
s3DocumentStore.retrieveDocument(documentDataMock);
|
||||||
}
|
}
|
||||||
@@ -110,11 +117,11 @@ public class S3DocumentStoreTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldDeleteImageFromS3() throws IOException {
|
public void shouldDeleteImageFromS3() throws IOException {
|
||||||
AmazonS3Client s3ClientMock = mock(AmazonS3Client.class);
|
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() {
|
private void initRetrieve() {
|
||||||
@@ -126,10 +133,10 @@ public class S3DocumentStoreTest {
|
|||||||
when(documentDataMock.contentType()).thenReturn("type");
|
when(documentDataMock.contentType()).thenReturn("type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initUpload() {
|
||||||
private void initUpload(){
|
|
||||||
inputStream = S3DocumentStoreTest.class.getResourceAsStream("DummyString");
|
inputStream = S3DocumentStoreTest.class.getResourceAsStream("DummyString");
|
||||||
s3ClientMock = mock(AmazonS3Client.class);
|
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