storagehub/src/main/java/org/gcube/data/access/storagehub/storage/backend/impl/S3Backend.java

208 lines
6.6 KiB
Java

package org.gcube.data.access.storagehub.storage.backend.impl;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.gcube.common.storagehub.model.exceptions.StorageIdNotFoundException;
import org.gcube.common.storagehub.model.items.nodes.Content;
import org.gcube.common.storagehub.model.items.nodes.PayloadBackend;
import org.gcube.common.storagehub.model.storages.MetaInfo;
import org.gcube.common.storagehub.model.storages.StorageBackend;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
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.S3ClientOptions;
import com.amazonaws.services.s3.model.ObjectMetadata;
public class S3Backend extends StorageBackend{
private static Logger log = LoggerFactory.getLogger(S3Backend.class);
Function<Void, String> keyGenerator;
String bucketName;
AmazonS3 client;
@Override
protected void setPayloadConfiguration(PayloadBackend payloadConfiguration) {
super.setPayloadConfiguration(payloadConfiguration);
}
public S3Backend(PayloadBackend payloadConfiguration, Function<Void, String> keyGenerator) {
super(payloadConfiguration);
this.keyGenerator = keyGenerator;
Map<String, Object> parameters = payloadConfiguration.getParameters();
this.bucketName = (String)parameters.get("bucketName");
String accessKey = (String)parameters.get("key");
String secret = (String)parameters.get("secret");
String url = (String)parameters.get("url");
boolean createBucket = Boolean.valueOf((String)parameters.get("createBucket"));
log.debug("parameters are: bucketName = {}, url = {}, createBucket = {}",this.bucketName, url, createBucket);
try {
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secret);
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol(Protocol.HTTPS);
client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials)).withClientConfiguration(clientConfig).build();
client.setEndpoint(url);
client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build());
if (createBucket && !client.doesBucketExistV2(bucketName)) {
client.createBucket(bucketName);
log.debug("bucket {} created",this.bucketName);
}
} catch (Exception e) {
log.error("error initializing s3",e);
throw new RuntimeException("error initializing s3", e);
}
}
public boolean isAlive() {
boolean toReturn = true;
try {
client.doesBucketExistV2(bucketName);
}catch (Exception e) {
log.error("error checking aliveness",e);
toReturn = false;
}
log.debug("the S3 backend is {} Alive",toReturn?"":"not");
return toReturn;
}
@Override
public MetaInfo onCopy(Content content, String newParentPath, String newName) {
String sourceKey = content.getStorageId();
String destinationKey = keyGenerator.apply(null);
try {
client.copyObject(bucketName, sourceKey, bucketName, destinationKey);
} catch (Exception e) {
throw new RuntimeException("error copying file on s3", e);
}
return new MetaInfo(content.getSize(), destinationKey, null, getPayloadConfiguration());
}
@Override
public MetaInfo onMove(Content content, String newParentPath) {
//new contentPath can be set as remotePath to the storage backend ?
return new MetaInfo(content.getSize(),content.getStorageId(), content.getRemotePath(), getPayloadConfiguration());
}
@Override
public void delete(String storageId) {
try {
client.deleteObject(bucketName, storageId);
} catch (Exception e) {
throw new RuntimeException("error deleting file on s3", e);
}
}
@Override
public MetaInfo upload(InputStream stream, String relativePath, String name, String user) {
return this.upload(stream, relativePath, name, null, user);
}
@Override
public MetaInfo upload(InputStream stream, String relativePath, String name, Long size, String user) {
String storageId = keyGenerator.apply(null);
return upload(stream, relativePath, name, storageId, size, user);
}
@Override
public MetaInfo upload(InputStream stream, String relativePath, String name, String storageId, Long size, String user) {
try {
/*Map<String, String> headers = new HashMap<>();
headers.put("X-Amz-Storage-Class", "REDUCED_REDUNDANCY");
Map<String, String> userMetadata = new HashMap<>();*/
ObjectMetadata objMeta = new ObjectMetadata();
objMeta.addUserMetadata("user", user);
objMeta.addUserMetadata("title", name);
if (size != null && size >0) {
objMeta.setContentLength(size);
log.info("content length set to {}",size);
} else
log.info("content length not set");
log.info("uploading file {} with id {} in bucket {} ",name, storageId, bucketName);
client.putObject(bucketName, storageId, stream, objMeta);
long fileSize;
if (size != null && size>0)
fileSize = size;
else
fileSize = client.getObjectMetadata(bucketName, storageId).getContentLength();
return new MetaInfo(fileSize,storageId, null, getPayloadConfiguration());
} catch (Exception e) {
log.error("error uploading file on s3",e);
throw new RuntimeException("error uploading file on s3", e);
}
}
@Override
public InputStream download(String id) throws StorageIdNotFoundException{
try {
InputStream inputStream = client.getObject(bucketName, id).getObjectContent();
return inputStream;
}catch (Exception e) {
log.error("error downloading file form s3");
throw new RuntimeException("error downloading file from s3",e);
}
}
@Override
public InputStream download(Content content) throws StorageIdNotFoundException {
return download(content.getStorageId());
}
@Override
public Map<String, String> getFileMetadata(String id) {
try {
ObjectMetadata objMeta = client.getObjectMetadata(bucketName, id);
Map<String, String> userMetadata = objMeta.getUserMetadata();
HashMap<String, String> toReturn = new HashMap<>(userMetadata);
toReturn.put("size" , Long.toString(objMeta.getContentLength()));
return toReturn;
} catch (Exception e) {
log.error("error getting metadata from s3");
throw new RuntimeException("error downloading file from s3",e);
}
}
@Override
public String getTotalSizeStored() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getTotalItemsCount() {
// TODO Auto-generated method stub
return null;
}
}