Hey guys today we will cover the AWS S3 integration for getting and uploading file into S3 bucket
here I have used the custom meta data to store my S3 details named S3_Cred_Details__mdt
Bucket__c
Key__c
Secret__c
These are the field to store bucket name, access key and secret key this is not a good practices to hardcode the S3 credentials into Apex Class
that’s why we use the metadata to store credentials
Get the file from S3
public static String getFile(String fileName){
fileName = EncodingUtil.urlEncode(fileName, 'UTF-8');
S3_Cred_Details__mdt s3 = S3_Cred_Details__mdt.getInstance('s3_Cred');
String BucketName = s3.Bucket__c;
String AccessKey = s3.Key__c;
String SecretKey = s3.Secret__c;
Datetime currentTime = DateTime.now();
Datetime expireson = currentTime.AddSeconds(50);
Long Lexpires = expireson.getTime()/1000;
// if you want to access the file that is inside any folder
String stringtosign = 'GET\n\n\n'+Lexpires+'\n/'+BucketName+'/folerName/'+fileName;
Blob mac = Crypto.generateMac('HMacSHA1', blob.valueof(stringtosign),blob.valueof(SecretKey));
String signed = EncodingUtil.base64Encode(mac);
String fileurl = 'http://'+BucketName+'.s3.amazonaws.com/folerName/'+fileName+'?AWSAccessKeyId='+AccessKey+
'&Expires='+Lexpires+'&Signature='+signed;
return fileurl;
}
upload file into S3
public static Boolean PutfileintoS3(Id cvId){
Boolean isSuccess = false;
try{
ContentVersion cv = [SELECT FileType, PathOnClient, VersionData FROM ContentVersion WHERE Id = :cvId LIMIT 1];
long currTime = system.currentTimeMillis();
String filename = String.valueOf(currTime)+'-'+cv.PathOnClient;
String base64Data = EncodingUtil.base64Encode(cv.VersionData);
String contentType = '';
if(cv.FileType.toUpperCase() == 'JPEG' || cv.FileType.toUpperCase() == 'JPG' || cv.FileType.toUpperCase() == 'PNG'){
contentType = 'image/'+cv.FileType;
}else{
contentType = 'application/pdf';
}
Http http = new http();
S3_Cred_Details__mdt s3 = S3_Cred_Details__mdt.getInstance('s3_Cred');
String bucketname = s3.Bucket__c; //AWS bucket name
String host = 's3.us-west-2.amazonaws.com';
String cvBody = base64Data;
String accessKeyId = s3.Key__c;
String accessSecret = s3.Secret__c;
String formattedDateString = Datetime.now().formatGMT('EEE, dd MMM yyyy HH:mm:ss z');
String filePath = 'https://' + bucketname + '.' + host + '/' + EncodingUtil.urlEncode(filename, 'UTF-8');
HttpRequest req = new HttpRequest();
req.setMethod('PUT');
req.setEndpoint(filePath);
req.setHeader('Host', bucketname + '.' + host);
req.setHeader('Content-Length', String.valueOf(cvBody.length()));
req.setHeader('Content-Encoding', 'UTF-8');
req.setHeader('Content-Type', contentType);
req.setHeader('Connection', 'keep-alive');
req.setHeader('Date', formattedDateString);
req.setHeader('ACL', 'public-read');
//base64 decode the body to get the correct blob format
req.setBodyAsBlob(EncodingUtil.base64Decode(base64Data));
String stringToSign = 'PUT\n\n'+ contentType +'\n' + formattedDateString + '\n' + '/' + bucketname + '/OCRProject/' + EncodingUtil.urlEncode(filename, 'UTF-8');
String encodedStringToSign = EncodingUtil.urlEncode(stringToSign, 'UTF-8');
Blob mac = Crypto.generateMac('HMACSHA1', blob.valueof(stringToSign),blob.valueof(accessSecret));
String signedKey = EncodingUtil.base64Encode(mac);
String authHeader = 'AWS' + ' ' + accessKeyId + ':' + signedKey;
req.setHeader('Authorization',authHeader);
HttpResponse resp = http.send(req);
System.debug('Response' + String.ValueOf(resp.getBody()));
if(resp.getStatusCode() == 200){
System.debug('SUCCESS');
isSuccess = true;
}else{
System.debug('fail');
isSuccess = false;
}
}catch(Exception e){
System.debug(e.getMessage());
}
return isSuccess;
}