In our business project we need to integrate with an external system which uses amazon sqs WS in order to manage client requests. Is there an example implementation in apex for sending/receiving messages to/from an amazon simple queue?
I've started from this point: https://webmonkeyswithlaserbeams.wordpress.com/2011/03/08/salesforce-and-amazon-sqs/
Is this correct?
public class AmazonSqsSender{
private String getCurrentDate() {
return DateTime.now().formatGmt('yyyy-MM-dd\'T\'HH:mm:ss.SSS\'Z\'');
}
public void sendMessage(String message) {
//AmazonAws__c is a custom setting object that stores our keys, an Amazon Host, and a queue name
//You can just put your keys, host and queue below as strings /CUSTOM SETTINGS
AmazonAws__c aws = AmazonAws__c.getOrgDefaults();
String accessKey =aws.accessKey__c;
String secretKey = aws.secretKey__c;
String host = aws.host__c;
String queue = aws.queue__c;
Map<String,String> params = new Map<String,String>();
params.put('AWSAccessKeyId',encode(accessKey));
params.put('Action','SendMessage');
params.put('MessageBody',encode(message));
params.put('Timestamp',encode(getCurrentDate()));
params.put('SignatureMethod','HmacSHA1');
params.put('SignatureVersion','2');
params.put('Version','2009-02-01');
//The string to sign has to be sorted by keys
List<String> sortedKeys = new List<String>();
sortedKeys.addAll(params.keySet());
sortedKeys.sort();
String toSign = 'GET\n' + host +'\n'+queue+'\n';
Integer p = 0;
for (String key : sortedKeys) {
String value = params.get(key);
if (p > 0) {
toSign += '&';
}
p++;
toSign += key+'='+value;
}
params.put('Signature',getMac(toSign,secretKey));
String url = 'https://'+ host+queue+'?';
p = 0;
for (String key : params.keySet()) {
if (p > 0) {
url += '&';
}
p++;
url += key+'='+params.get(key);
}
HttpRequest req = new HttpRequest();
req.setEndPoint(url);
req.setMethod('GET');
Http http = new Http();
try {
//System.debug('Signed string: ' + toSign);
//System.debug('Url: ' + url);
HttpResponse res = http.send(req);
//System.debug('Status: ' + res.getStatus());
//System.debug('Code : ' + res.getStatusCode());
//System.debug('Body : ' + res.getBody());
}
catch (System.CalloutException e) {
System.debug('ERROR: ' + e);
}
}
public void receiveMessage(String message) {
//MAYBE I NEED TO CHANGE THE QUERIES
AmazonAws__c aws = AmazonAws__c.getOrgDefaults();
String accessKey =aws.accessKey__c;
String secretKey = aws.secretKey__c;
String host = aws.host__c;
String queue = aws.queue__c;
Map<String,String> params = new Map<String,String>();
params.put('AWSAccessKeyId',encode(accessKey));
params.put('Action','ReceiveMessage');
params.put('MessageBody',encode(message));
params.put('Timestamp',encode(getCurrentDate()));
params.put('SignatureMethod','HmacSHA1');
params.put('SignatureVersion','2');
params.put('Version','2009-02-01');
//The string to sign has to be sorted by keys
List<String> sortedKeys = new List<String>();
sortedKeys.addAll(params.keySet());
sortedKeys.sort();
String toSign = 'GET\n' + host +'\n'+queue+'\n';
Integer p = 0;
for (String key : sortedKeys) {
String value = params.get(key);
if (p > 0) {
toSign += '&';
}
p++;
toSign += key+'='+value;
}
params.put('Signature',getMac(toSign,secretKey));
String url = 'https://'+ host+queue+'?';
p = 0;
for (String key : params.keySet()) {
if (p > 0) {
url += '&';
}
p++;
url += key+'='+params.get(key);
}
HttpRequest req = new HttpRequest();
req.setEndPoint(url);
req.setMethod('GET');
Http http = new Http();
try {
//System.debug('Signed string: ' + toSign);
//System.debug('Url: ' + url);
HttpResponse res = http.send(req);
//System.debug('Status: ' + res.getStatus());
//System.debug('Code : ' + res.getStatusCode());
//System.debug('Body : ' + res.getBody());
}
catch (System.CalloutException e) {
System.debug('ERROR: ' + e);
}
}
private String encode(String message){
return EncodingUtil.urlEncode(message,'UTF-8').replace('+', '%20').replace('*', '%2A').replace('%7E','~');
}
private String getMac(String RequestString, String secretkey) {
String algorithmName = 'hmacSHA1';
Blob input = Blob.valueOf(RequestString);
Blob key = Blob.valueOf(secretkey);
Blob signing =Crypto.generateMac(algorithmName, input, key);
return EncodingUtil.urlEncode(EncodingUtil.base64Encode(signing), 'UTF-8');
}
public static void sendTest() {
AmazonSqsSender t = new AmazonSqsSender();
t.sendMessage('Hello from Salesforce ' + Math.random());
}
EDIT: After testing the first method i've encountered the anouthorized endpoint error, even if the endpoint has been inserted in the remote site setting, could it depend on the 'builded' url used in the method?