Upload and get file from AWS S3

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;
    }
				
			

Leave a Comment