/* ************************************************************************
#
# DivConq
#
# http://divconq.com/
#
# Copyright:
# Copyright 2014 eTimeline, LLC. All rights reserved.
#
# License:
# See the license.txt file in the project's top-level directory for details.
#
# Authors:
# * Andy White
#
************************************************************************ */
package divconq.interchange.mws;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import javax.net.ssl.HttpsURLConnection;
import org.joda.time.format.ISODateTimeFormat;
import divconq.lang.op.FuncResult;
import divconq.util.StringUtil;
import divconq.xml.XElement;
import divconq.xml.XmlReader;
public class MwsServices {
static final public String ORDERS_API = "/Orders/2013-09-01";
protected URI endpoint = null;
protected String awsKeyId = null;
protected String awsSecretKey = null;
protected String awsSeller = null;
protected String marketplaceId = null;
public void setAwsKeyId(String awsKeyId) {
this.awsKeyId = awsKeyId;
}
public MwsServices(String endpoint, String awsKeyId, String awsSecretKey, String awsSeller, String marketplaceId) {
this.endpoint = Endpoints.lookup(endpoint);
this.awsKeyId = awsKeyId;
this.awsSecretKey = awsSecretKey;
this.awsSeller = awsSeller;
this.marketplaceId = marketplaceId;
}
public FuncResult<XElement> executeListOrders(String stamp) {
Map<String, String> params = new HashMap<String, String>();
if (StringUtil.isNotEmpty(stamp))
params.put("LastUpdatedAfter", stamp);
params.put("MarketplaceId.Id.1", this.marketplaceId);
return this.execute(MwsServices.ORDERS_API, "ListOrders", params);
}
public FuncResult<XElement> executeListOrderItems(String oid) {
Map<String, String> params = new HashMap<String, String>();
params.put("AmazonOrderId", oid);
return this.execute(MwsServices.ORDERS_API, "ListOrderItems", params);
}
public FuncResult<XElement> execute(String path, String action, Map<String, String> params) {
FuncResult<XElement> res = new FuncResult<>();
try {
URI ep = this.endpoint.resolve(path);
URL url = ep.toURL();
String urlParameters = "";
Map<String, String> sorted = new TreeMap<String, String>();
sorted.put("Action", action);
sorted.put("AWSAccessKeyId", this.awsKeyId);
sorted.put("SellerId", this.awsSeller);
sorted.put("SignatureMethod", "HmacSHA256");
sorted.put("SignatureVersion", "2");
sorted.put("Timestamp", ISODateTimeFormat.dateTime().withZoneUTC().print(System.currentTimeMillis()));
sorted.put("Version", "2013-09-01");
sorted.putAll(params);
boolean firstparam = true;
for (Entry<String, String> pair : sorted.entrySet()) {
if (firstparam)
firstparam = false;
else
urlParameters += "&";
urlParameters += Util.urlEncode(pair.getKey(), false) + "=" + Util.urlEncode(pair.getValue(), false);
}
String algorithm = "HmacSHA256";
String stringToSign = null;
StringBuilder data = new StringBuilder();
data.append("POST\n");
data.append(ep.getHost().toLowerCase());
if (!Util.usesStandardPort(ep)) {
data.append(":");
data.append(ep.getPort());
}
data.append("\n");
data.append(Util.urlEncode(ep.getPath(), true)
+ "\n" + urlParameters);
stringToSign = data.toString();
String x = Util.sign(stringToSign, this.awsSecretKey, algorithm);
//System.out.println("Got: " + x);
urlParameters += "&Signature=" + Util.urlEncode(x, false);
res.debug("Sending 'POST' request to URL : " + ep);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "DivConq/1.0 (Language=Java/8)");
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
res.debug("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null)
response.append(inputLine);
in.close();
FuncResult<XElement> xres = XmlReader.parse(response.toString(), false);
res.setResult(xres.getResult());
}
catch (Exception x) {
res.error("Error loading result" + x);
}
return res;
}
}