Skip to content
This repository has been archived by the owner on Jan 21, 2021. It is now read-only.

Issue355 - Adding functionality to save and download patient images on s3 #357

Open
wants to merge 14 commits into
base: path
Choose a base branch
from
16 changes: 13 additions & 3 deletions assets/config/opensrp.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ form.poll.time.interval=2
mcts.phone.number=8762963816
js.directory.name=/ziggy
form.directory.name=/form
multimedia.directory.name=/opt/multimedia
form.download.files=form.xml, model.xml, form_definition.json
multimedia.directory.name=../multimedia/opensrp
qrcodes.directory.name=/home/opensrp/qr-codes/

schedule.config.path=/schedules/schedule-config.xls
Expand Down Expand Up @@ -59,7 +57,6 @@ jdbc.url-wo-db=jdbc:mysql://localhost:3306

# Hibernate properties for Reporting DB
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=false
# hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.format_sql=false
Expand Down Expand Up @@ -88,3 +85,16 @@ file.maxUploadSize=20971520

#opnenSRP Site url
opensrp.site.url=""

#multimedia directory location - accepted values (s3 or local)
multimedia.directory.location = s3

#if local is preferred this path will be used to store images
multimedia.directory.name= ""

# S3 configuration
aws.access.key.id = ""
aws.secret.access.key = ""
aws.region = ""
aws.bucket = ""
aws.key.folder = ""
18 changes: 12 additions & 6 deletions opensrp-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<resource>
<directory>../assets/schedules</directory>
<targetPath>schedules</targetPath>
</resource>
</resource>
<resource>
<directory>../build</directory>
<filtering>true</filtering>
Expand All @@ -46,6 +46,12 @@


<dependencies>
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.244</version>
</dependency>
<dependency>
<artifactId>motech-platform-server-api</artifactId>
<groupId>org.motechproject</groupId>
Expand All @@ -60,7 +66,7 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.2</version>
<version>2.6.0</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -207,7 +213,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
Expand All @@ -218,7 +224,7 @@
<groupId>com.openpojo</groupId>
<artifactId>openpojo</artifactId>
<version>0.8.6</version>
</dependency>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-annotations -->
<dependency>
<groupId>org.hibernate</groupId>
Expand All @@ -239,7 +245,7 @@
<scope>test</scope>
<classifier>runtime</classifier>
</dependency>


</dependencies>
</project>
231 changes: 152 additions & 79 deletions opensrp-core/src/main/java/org/opensrp/service/MultimediaService.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package org.opensrp.service;

import java.io.File;
import java.util.List;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.json.JSONException;
import org.opensrp.domain.Client;
import org.opensrp.domain.Multimedia;
import org.opensrp.dto.form.MultimediaDTO;
Expand All @@ -14,109 +22,110 @@
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;

@Service
public class MultimediaService {

private static Logger logger = LoggerFactory.getLogger(MultimediaService.class.toString());

public static final String IMAGES_DIR = "patient_images";

private static final String VIDEOS_DIR = "videos";

private final MultimediaRepository multimediaRepository;

private final ClientService clientService;

private String multimediaDirPath;

@Value("#{opensrp['multimedia.directory.name']}")
String baseMultimediaDirPath;

private String baseMultimediaDirPath;

@Value("#{opensrp['aws.access.key.id']}")
private String awsAccessKeyId;

@Value("#{opensrp['aws.secret.access.key']}")
private String awsSecretAccessKey;

@Value("#{opensrp['aws.region']}")
private String awsRegion;

@Value("#{opensrp['aws.bucket']}")
private String awsBucket;

@Value("#{opensrp['aws.key.folder']}")
private String mediaKeyFolder;

@Value("#{opensrp['multimedia.directory.location']}")
private String multimediaDirectoryLocation;

private String successResponse = "success";

private String failedResponse = "fail";

private String imageAttribute = "Patient Image";

@Autowired
public MultimediaService(MultimediaRepository multimediaRepository, ClientService clientService) {
this.multimediaRepository = multimediaRepository;
this.clientService = clientService;
}

public String saveMultimediaFile(MultimediaDTO multimediaDTO, MultipartFile file) {

String fileExtension = makeFileExtension(multimediaDTO);

if (multimediaDirectoryLocation.equalsIgnoreCase("s3")) {
File imageToSave = new File(multimediaDTO.getCaseId() + fileExtension);
try {
file.transferTo(imageToSave);
uploadImageToS3(imageToSave, awsAccessKeyId, awsSecretAccessKey, awsRegion, awsBucket, mediaKeyFolder);
updateClientWithImage(multimediaDTO, fileExtension);
return successResponse;
} catch (IOException e) {
e.printStackTrace();
return failedResponse;
}
}

if (uploadFile(multimediaDTO, file)) {
try {
logger.info("Image path : " + multimediaDirPath);

Multimedia multimediaFile = new Multimedia().withCaseId(multimediaDTO.getCaseId())
.withProviderId(multimediaDTO.getProviderId()).withContentType(multimediaDTO.getContentType())
.withFilePath(multimediaDTO.getFilePath()).withFileCategory(multimediaDTO.getFileCategory());

.withProviderId(multimediaDTO.getProviderId()).withContentType(multimediaDTO.getContentType())
.withFilePath(multimediaDTO.getFilePath()).withFileCategory(multimediaDTO.getFileCategory());
multimediaRepository.add(multimediaFile);
Client client = clientService.getByBaseEntityId(multimediaDTO.getCaseId());
if (client !=null) {
if(client.getAttribute("Patient Image") != null) {
client.removeAttribute("Patient Image");
}
client.addAttribute("Patient Image", multimediaDTO.getCaseId() + ".jpg");
client.setServerVersion(null);
clientService.updateClient(client);
}
return "success";
updateClientWithImage(multimediaDTO, fileExtension);
return successResponse;
}
catch (Exception e) {
e.getMessage();
return failedResponse;
}
}

return "fail";
return failedResponse;
}

public boolean uploadFile(MultimediaDTO multimediaDTO, MultipartFile multimediaFile) {

// String baseMultimediaDirPath = System.getProperty("user.home");


if (!multimediaFile.isEmpty()) {
try {

multimediaDirPath = baseMultimediaDirPath + File.separator;
String fileExt = ".jpg";
switch (multimediaDTO.getContentType()) {

case "application/octet-stream":
multimediaDirPath += VIDEOS_DIR;
fileExt = ".mp4";
break;

case "image/jpeg":
multimediaDirPath += IMAGES_DIR;
fileExt = ".jpg";
break;

case "image/gif":
multimediaDirPath += IMAGES_DIR;
fileExt = ".gif";
break;

case "image/png":
multimediaDirPath += IMAGES_DIR;
fileExt = ".png";
break;

}
new File(multimediaDirPath).mkdir();
String fileName = multimediaDirPath + File.separator + multimediaDTO.getCaseId() + fileExt;
String fileName =
multimediaDirPath + File.separator + multimediaDTO.getCaseId() + makeFileExtension(multimediaDTO);
multimediaDTO.withFilePath(fileName);
File multimediaDir = new File(fileName);

multimediaFile.transferTo(multimediaDir);

/*
byte[] bytes = multimediaFile.getBytes();

BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(multimediaDirPath));
stream.write(bytes);
stream.close();*/


return true;

}
catch (Exception e) {
logger.error("", e);
Expand All @@ -126,19 +135,83 @@ public boolean uploadFile(MultimediaDTO multimediaDTO, MultipartFile multimediaF
return false;
}
}

private void makeMultimediaDir(String dirPath) {
File file = new File(dirPath);
if (!file.exists())
file.mkdirs();

}


public List<Multimedia> getMultimediaFiles(String providerId) {
return multimediaRepository.all(providerId);
}

public Multimedia findByCaseId(String entityId) {
return multimediaRepository.findByCaseId(entityId);
}

public String uploadImageToS3(File imageFile, String awsAccessKeyId, String awsSecretAccessKey, String awsRegion,
String awsBucket, String awsKeyFolder) {

AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(
new AWSStaticCredentialsProvider(new BasicAWSCredentials(awsAccessKeyId, awsSecretAccessKey)))
.withRegion(awsRegion).build();
InputStream inputStream;
try {
byte[] md5 = DigestUtils.md5(new FileInputStream(imageFile));
inputStream = new FileInputStream(imageFile);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(imageFile.length());
metadata.setContentMD5(new String(Base64.encodeBase64(md5)));
PutObjectRequest request = new PutObjectRequest(awsBucket, awsKeyFolder + imageFile.getName(), inputStream,
metadata);
s3Client.putObject(request);
return successResponse;
}
catch (AmazonServiceException e) {
logger.error("", e);
return failedResponse;
}
catch (SdkClientException e) {
logger.error("", e);
return failedResponse;
}
catch (FileNotFoundException e) {
logger.error("", e);
return failedResponse;
}
catch (IOException e) {
logger.error("", e);
return failedResponse;
}
}

public String makeFileExtension(MultimediaDTO multimediaDTO) {
switch (multimediaDTO.getContentType()) {
case "application/octet-stream":
multimediaDirPath += VIDEOS_DIR;
return ".mp4";

case "image/gif":
multimediaDirPath += IMAGES_DIR;
return ".gif";

case "image/png":
multimediaDirPath += IMAGES_DIR;
return ".png";
default:
return ".jpg";
}
}

public void updateClientWithImage(MultimediaDTO multimediaDTO, String fileExtension) {
Client client = clientService.getByBaseEntityId(multimediaDTO.getCaseId());
if (client != null) {
try {
if (client.getAttribute(imageAttribute) != null) {
client.removeAttribute(imageAttribute);
}
client.addAttribute(imageAttribute, multimediaDTO.getCaseId() + fileExtension);
client.setServerVersion(null);
clientService.updateClient(client);
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
}
Loading