Created
June 4, 2014 11:07
-
-
Save loriopatrick/18d960f9edc23c85845f to your computer and use it in GitHub Desktop.
A helper class to make requests to Amazon's product api.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.joda.time.DateTime; | |
import javax.crypto.Mac; | |
import javax.crypto.spec.SecretKeySpec; | |
import javax.xml.bind.DatatypeConverter; | |
import java.io.UnsupportedEncodingException; | |
import java.net.URLEncoder; | |
import java.security.InvalidKeyException; | |
import java.security.NoSuchAlgorithmException; | |
import java.util.Iterator; | |
import java.util.Map; | |
import java.util.SortedMap; | |
/** | |
* @author Patrick Lorio | |
*/ | |
public class Amazon { | |
private static final String UTF8 = "UTF-8"; | |
private static final String HMAC_SHA256 = "HmacSHA256"; | |
private static final String AMNZ_URI = "/onca/xml"; | |
private final String associateTag; | |
private final String accessKeyId; | |
private final Mac mac; | |
public Amazon(String associateTag, String accessKeyId, String secretKey) | |
throws NoSuchAlgorithmException, InvalidKeyException { | |
this.associateTag = associateTag; | |
this.accessKeyId = accessKeyId; | |
mac = Mac.getInstance(HMAC_SHA256); | |
mac.init(new SecretKeySpec(getByte(secretKey), HMAC_SHA256)); | |
} | |
public String getUrl(String endpoint, SortedMap<String, String> params) { | |
params.put("AWSAccessKeyId", accessKeyId); | |
params.put("Timestamp", getTimestamp()); | |
params.put("AssociateTag", associateTag); | |
String paramStr = getParams(params); | |
String sign = String.format("GET\n%s\n%s\n%s", endpoint, AMNZ_URI, paramStr); | |
String signature = DatatypeConverter.printBase64Binary(mac.doFinal(getByte(sign))); | |
return String.format("http://%s%s?%s&Signature=%s", endpoint, AMNZ_URI, paramStr, encodeRFC3986(signature)); | |
} | |
private String getParams(SortedMap<String, String> params) { | |
StringBuilder sb = new StringBuilder(); | |
Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator(); | |
while (iterator.hasNext()) { | |
Map.Entry<String, String> item = iterator.next(); | |
sb.append(encodeRFC3986(item.getKey())).append("=").append(encodeRFC3986(item.getValue())); | |
if (iterator.hasNext()) { | |
sb.append('&'); | |
} | |
} | |
return sb.toString(); | |
} | |
private String encodeRFC3986(String str) { | |
try { | |
return URLEncoder.encode(str, UTF8) | |
.replace("+", "%20") | |
.replace("*", "%2A") | |
.replace("%7E", "~"); | |
} catch (UnsupportedEncodingException ignored) { | |
return str; | |
} | |
} | |
private String getTimestamp() { | |
return new DateTime().toString("yyyy-MM-dd'T'HH:mm:ss'Z'"); | |
} | |
private byte[] getByte(String str) { | |
try { | |
return str.getBytes(UTF8); | |
} catch (UnsupportedEncodingException e) { | |
throw new RuntimeException(UTF8 + " is not supported.", e); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment