例のごとくapexからSimpleDB触ってみる。
/**
* SimpleDBのコモンクラス
*/
public with sharing class SimpleDBCommon {
/**
* AccessKey
*/
public String AWSAccessKeyId = EnvSetting__c.getOrgDefaults().AWSAccessKeyId__c;
/**
* SecretKey
*/
public String AWSSecretKeyId = EnvSetting__c.getOrgDefaults().AWSAccessKeySecret__c;
/**
* ドメイン作成
*/
public String createDomain(String domainName) {
Map<String, String> params = new Map<String, String>{
'Action' => 'CreateDomain',
'AWSAccessKeyId' => this.AWSAccessKeyId,
'SignatureMethod' => 'HmacSHA256',
'SignatureVersion' => '2',
'DomainName' => domainName,
'Version' => '2009-04-15',
'Timestamp' => DateTime.now().formatGmt('YYYY-MM-dd') + 'T' + DateTime.now().formatGmt('HH:mm:ssZ')
};
params.put('Signature', this.createSignature('POST', 'sdb.amazonaws.com', '/', params));
HttpRequest req = new HttpRequest();
req.setEndpoint('https://sdb.amazonaws.com');
req.setMethod('POST');
req.setBody(Utility.getSortedParam(params));
Http http = new Http();
HTTPResponse res = http.send(req);
return res.getBody();
}
/**
* ドメイン削除
*/
public String deleteDomain(String domainName) {
Map<String, String> params = new Map<String, String>{
'Action' => 'DeleteDomain',
'AWSAccessKeyId' => this.AWSAccessKeyId,
'SignatureMethod' => 'HmacSHA256',
'SignatureVersion' => '2',
'DomainName' => domainName,
'Version' => '2009-04-15',
'Timestamp' => DateTime.now().formatGmt('YYYY-MM-dd') + 'T' + DateTime.now().formatGmt('HH:mm:ssZ')
};
params.put('Signature', this.createSignature('POST', 'sdb.amazonaws.com', '/', params));
HttpRequest req = new HttpRequest();
req.setEndpoint('https://sdb.amazonaws.com');
req.setMethod('POST');
req.setBody(Utility.getSortedParam(params));
Http http = new Http();
HTTPResponse res = http.send(req);
return res.getBody();
}
/**
* アイテム作成
*/
public String putAttributes(String domainName, String itemName, Map<String, String> attributes) {
Map<String, String> params = new Map<String, String>{
'Action' => 'PutAttributes',
'AWSAccessKeyId' => this.AWSAccessKeyId,
'SignatureMethod' => 'HmacSHA256',
'SignatureVersion' => '2',
'DomainName' => domainName,
'Version' => '2009-04-15',
'Timestamp' => DateTime.now().formatGmt('YYYY-MM-dd') + 'T' + DateTime.now().formatGmt('HH:mm:ssZ'),
'ItemName' => itemName
};
Integer i = 1;
for (String key : attributes.keySet()) {
params.put('Attribute.' + i + '.Name', key);
params.put('Attribute.' + i + '.Value', attributes.get(key));
i++;
}
params.put('Signature', this.createSignature('POST', 'sdb.amazonaws.com', '/', params));
HttpRequest req = new HttpRequest();
req.setEndpoint('https://sdb.amazonaws.com');
req.setMethod('POST');
req.setBody(Utility.getSortedParam(params));
Http http = new Http();
HTTPResponse res = http.send(req);
return res.getBody();
}
/**
* クエリ
*/
public String query(String queryString) {
Map<String, String> params = new Map<String, String>{
'Action' => 'Select',
'AWSAccessKeyId' => this.AWSAccessKeyId,
'SignatureMethod' => 'HmacSHA256',
'SignatureVersion' => '2',
'SelectExpression' => queryString,
'Version' => '2009-04-15',
'Timestamp' => DateTime.now().formatGmt('YYYY-MM-dd') + 'T' + DateTime.now().formatGmt('HH:mm:ssZ')
};
params.put('Signature', this.createSignature('POST', 'sdb.amazonaws.com', '/', params));
HttpRequest req = new HttpRequest();
req.setEndpoint('https://sdb.amazonaws.com');
req.setMethod('POST');
req.setBody(Utility.getSortedParam(params));
Http http = new Http();
HTTPResponse res = http.send(req);
return res.getBody();
}
private String createSignature(
String method,
String hostname,
String resource,
Map<String, String> params
) {
String signature =
method + Constants.LF +
hostname.toLowerCase() + Constants.LF +
resource + Constants.LF +
Utility.getSortedParam(params);
System.debug(signature);
return String.valueOf(EncodingUtil.base64Encode(
Crypto.generateMac(
'hmacSHA256',
Blob.valueOf(signature),
Blob.valueOf(this.AWSSecretKeyId)
)
));
}
}
/**
* Utilityクラス
*/
public without sharing class Utility {
public static List getSortedList(Set keys) {
List sortedList = new List();
sortedList.addAll(keys);
sortedList.sort();
return sortedList;
}
/**
* key=value&...でつないだ文字列を返却
* @param mapParam 対象文字列=>文字列マップ
* @return key=value&...でつないだ文字列
*/
public static String getSortedParam(Map<String,String> mapParam){
if (mapParam == null || mapParam.keySet().isEmpty()) {
return '';
}
String param = '';
List sortedKey = getSortedList(mapParam.keySet());
for(String key: sortedKey){
param += percentEncodeRfc3986(key) + '=' + percentEncodeRfc3986(mapParam.get(key)) + '&';
}
return param.substring(0,param.length() - 1);
}
public static String percentEncodeRfc3986(String s) {
return EncodingUtil.urlEncode(s, 'UTF-8')
.replace('+', '%20')
.replace('*', '%2A')
.replace('%7E', '~');
}
}
signature生成はSignature Version 2なので簡単っす。
あと、simpleDBは1GBまで無料とか結構安いみたいなので
S3オブジェクトに対する情報付与のためのテーブルとかそういうのに気軽に使えそう。
スナップショット系にもいけるかなー。
http://aws.amazon.com/jp/simpledb/pricing/
ただし、ベータ版だからエンタープライズ分野にはまだ着手しずらいかも。
dynamoもRDSよりは安いので、エンタープライズ系だとdynamo使った方が色々と無難な気がします。