diff --git a/pom.xml b/pom.xml index 561eb05..ac1e2f9 100755 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,18 @@ - co.poynt.api - java-cloud-sdk + poynt-java-cloud-sdk 1.0.0-SNAPSHOT 4.0.0 jar Poynt Java Cloud SDK http://services.poynt.net + + 1.2.16 + 1.7.2 + 6.1.1 + https://github.com/poynt/java-cloud-sdk scm:git:ssh://git@github.com/poynt/java-cloud-sdk @@ -38,7 +44,7 @@ co.poynt.api api-model - 1.2.64 + 1.2.132 com.fasterxml.jackson.core @@ -65,12 +71,22 @@ httpclient 4.5 + org.slf4j slf4j-api - 1.7.12 + ${slf4j.version} + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + + + log4j + log4j + ${log4j.version} - @@ -83,8 +99,8 @@ maven-compiler-plugin 2.3.2 - 1.8 - 1.8 + 1.7 + 1.7 diff --git a/src/main/java/co/poynt/api/model/Amount.java b/src/main/java/co/poynt/api/model/Amount.java new file mode 100644 index 0000000..c062720 --- /dev/null +++ b/src/main/java/co/poynt/api/model/Amount.java @@ -0,0 +1,88 @@ +package co.poynt.api.model; + +import java.util.HashMap; +import java.util.Map; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "country", + "currency", + "value" +}) +public class Amount { + + @JsonProperty("country") + private String country; + @JsonProperty("currency") + private String currency; + @JsonProperty("value") + private Integer value; + @JsonIgnore + @Valid + private Map additionalProperties = new HashMap(); + + @JsonProperty("country") + public String getCountry() { + return country; + } + + @JsonProperty("country") + public void setCountry(String country) { + this.country = country; + } + + @JsonProperty("currency") + public String getCurrency() { + return currency; + } + + @JsonProperty("currency") + public void setCurrency(String currency) { + this.currency = currency; + } + + @JsonProperty("value") + public Integer getValue() { + return value; + } + + @JsonProperty("value") + public void setValue(Integer value) { + this.value = value; + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Amount [country="); + builder.append(country); + builder.append(", currency="); + builder.append(currency); + builder.append(", value="); + builder.append(value); + builder.append(", additionalProperties="); + builder.append(additionalProperties); + builder.append("]"); + return builder.toString(); + } + + + +} \ No newline at end of file diff --git a/src/main/java/co/poynt/api/model/Plan.java b/src/main/java/co/poynt/api/model/Plan.java new file mode 100644 index 0000000..244f00c --- /dev/null +++ b/src/main/java/co/poynt/api/model/Plan.java @@ -0,0 +1,253 @@ +package co.poynt.api.model; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "createdAt", + "updatedAt", + "amounts", + "interval", + "trialPeriodDays", + "startPolicy", + "cancelPolicy", + "appId", + "amount", + "planId", + "scope", + "description", + "status", + "name" +}) +public class Plan { + + @JsonProperty("createdAt") + private String createdAt; + @JsonProperty("updatedAt") + private String updatedAt; + @JsonProperty("amounts") + @Valid + private List amounts = null; + @JsonProperty("interval") + private String interval; + @JsonProperty("trialPeriodDays") + private Integer trialPeriodDays; + @JsonProperty("startPolicy") + private String startPolicy; + @JsonProperty("cancelPolicy") + private String cancelPolicy; + @JsonProperty("appId") + private String appId; + @JsonProperty("amount") + private Integer amount; + @JsonProperty("planId") + private String planId; + @JsonProperty("scope") + private String scope; + @JsonProperty("description") + private String description; + @JsonProperty("status") + private String status; + @JsonProperty("name") + private String name; + @JsonIgnore + @Valid + private Map additionalProperties = new HashMap(); + + @JsonProperty("createdAt") + public String getCreatedAt() { + return createdAt; + } + + @JsonProperty("createdAt") + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + @JsonProperty("updatedAt") + public String getUpdatedAt() { + return updatedAt; + } + + @JsonProperty("updatedAt") + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; + } + + @JsonProperty("amounts") + public List getAmounts() { + return amounts; + } + + @JsonProperty("amounts") + public void setAmounts(List amounts) { + this.amounts = amounts; + } + + @JsonProperty("interval") + public String getInterval() { + return interval; + } + + @JsonProperty("interval") + public void setInterval(String interval) { + this.interval = interval; + } + + @JsonProperty("trialPeriodDays") + public Integer getTrialPeriodDays() { + return trialPeriodDays; + } + + @JsonProperty("trialPeriodDays") + public void setTrialPeriodDays(Integer trialPeriodDays) { + this.trialPeriodDays = trialPeriodDays; + } + + @JsonProperty("startPolicy") + public String getStartPolicy() { + return startPolicy; + } + + @JsonProperty("startPolicy") + public void setStartPolicy(String startPolicy) { + this.startPolicy = startPolicy; + } + + @JsonProperty("cancelPolicy") + public String getCancelPolicy() { + return cancelPolicy; + } + + @JsonProperty("cancelPolicy") + public void setCancelPolicy(String cancelPolicy) { + this.cancelPolicy = cancelPolicy; + } + + @JsonProperty("appId") + public String getAppId() { + return appId; + } + + @JsonProperty("appId") + public void setAppId(String appId) { + this.appId = appId; + } + + @JsonProperty("amount") + public Integer getAmount() { + return amount; + } + + @JsonProperty("amount") + public void setAmount(Integer amount) { + this.amount = amount; + } + + @JsonProperty("planId") + public String getPlanId() { + return planId; + } + + @JsonProperty("planId") + public void setPlanId(String planId) { + this.planId = planId; + } + + @JsonProperty("scope") + public String getScope() { + return scope; + } + + @JsonProperty("scope") + public void setScope(String scope) { + this.scope = scope; + } + + @JsonProperty("description") + public String getDescription() { + return description; + } + + @JsonProperty("description") + public void setDescription(String description) { + this.description = description; + } + + @JsonProperty("status") + public String getStatus() { + return status; + } + + @JsonProperty("status") + public void setStatus(String status) { + this.status = status; + } + + @JsonProperty("name") + public String getName() { + return name; + } + + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Plan [createdAt="); + builder.append(createdAt); + builder.append(", updatedAt="); + builder.append(updatedAt); + builder.append(", amounts="); + builder.append(amounts); + builder.append(", interval="); + builder.append(interval); + builder.append(", trialPeriodDays="); + builder.append(trialPeriodDays); + builder.append(", startPolicy="); + builder.append(startPolicy); + builder.append(", cancelPolicy="); + builder.append(cancelPolicy); + builder.append(", appId="); + builder.append(appId); + builder.append(", amount="); + builder.append(amount); + builder.append(", planId="); + builder.append(planId); + builder.append(", scope="); + builder.append(scope); + builder.append(", description="); + builder.append(description); + builder.append(", status="); + builder.append(status); + builder.append(", name="); + builder.append(name); + builder.append(", additionalProperties="); + builder.append(additionalProperties); + builder.append("]"); + return builder.toString(); + } + +} \ No newline at end of file diff --git a/src/main/java/co/poynt/api/model/ResourceList.java b/src/main/java/co/poynt/api/model/ResourceList.java new file mode 100644 index 0000000..440c4ac --- /dev/null +++ b/src/main/java/co/poynt/api/model/ResourceList.java @@ -0,0 +1,51 @@ +package co.poynt.api.model; + +import java.util.List; + +public class ResourceList { + + private List list; + private int start; + private int total; + private int count; + public List getList() { + return list; + } + public void setList(List list) { + this.list = list; + } + public int getStart() { + return start; + } + public void setStart(int start) { + this.start = start; + } + public int getTotal() { + return total; + } + public void setTotal(int total) { + this.total = total; + } + public int getCount() { + return count; + } + public void setCount(int count) { + this.count = count; + } + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("ResourceList [list="); + builder.append(list); + builder.append(", start="); + builder.append(start); + builder.append(", total="); + builder.append(total); + builder.append(", count="); + builder.append(count); + builder.append("]"); + return builder.toString(); + } + + +} diff --git a/src/main/java/co/poynt/api/model/Subscription.java b/src/main/java/co/poynt/api/model/Subscription.java new file mode 100644 index 0000000..81b6bc1 --- /dev/null +++ b/src/main/java/co/poynt/api/model/Subscription.java @@ -0,0 +1,202 @@ +package co.poynt.api.model; + +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "createdAt", + "updatedAt", + "startAt", + "businessId", + "appId", + "subscriptionId", + "phase", + "planId", + "bundleId", + "status", + "storeId" +}) +public class Subscription { + + @JsonProperty("createdAt") + private String createdAt; + @JsonProperty("updatedAt") + private String updatedAt; + @JsonProperty("startAt") + private String startAt; + @JsonProperty("businessId") + private String businessId; + @JsonProperty("appId") + private String appId; + @JsonProperty("subscriptionId") + private String subscriptionId; + @JsonProperty("phase") + private String phase; + @JsonProperty("planId") + private String planId; + @JsonProperty("bundleId") + private String bundleId; + @JsonProperty("status") + private String status; + @JsonProperty("storeId") + private String storeId; + @JsonIgnore + private Map additionalProperties = new HashMap(); + + @JsonProperty("createdAt") + public String getCreatedAt() { + return createdAt; + } + + @JsonProperty("createdAt") + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + @JsonProperty("updatedAt") + public String getUpdatedAt() { + return updatedAt; + } + + @JsonProperty("updatedAt") + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; + } + + @JsonProperty("startAt") + public String getStartAt() { + return startAt; + } + + @JsonProperty("startAt") + public void setStartAt(String startAt) { + this.startAt = startAt; + } + + @JsonProperty("businessId") + public String getBusinessId() { + return businessId; + } + + @JsonProperty("businessId") + public void setBusinessId(String businessId) { + this.businessId = businessId; + } + + @JsonProperty("appId") + public String getAppId() { + return appId; + } + + @JsonProperty("appId") + public void setAppId(String appId) { + this.appId = appId; + } + + @JsonProperty("subscriptionId") + public String getSubscriptionId() { + return subscriptionId; + } + + @JsonProperty("subscriptionId") + public void setSubscriptionId(String subscriptionId) { + this.subscriptionId = subscriptionId; + } + + @JsonProperty("phase") + public String getPhase() { + return phase; + } + + @JsonProperty("phase") + public void setPhase(String phase) { + this.phase = phase; + } + + @JsonProperty("planId") + public String getPlanId() { + return planId; + } + + @JsonProperty("planId") + public void setPlanId(String planId) { + this.planId = planId; + } + + @JsonProperty("bundleId") + public String getBundleId() { + return bundleId; + } + + @JsonProperty("bundleId") + public void setBundleId(String bundleId) { + this.bundleId = bundleId; + } + + @JsonProperty("status") + public String getStatus() { + return status; + } + + @JsonProperty("status") + public void setStatus(String status) { + this.status = status; + } + @JsonProperty("storeId") + public String getStoreId() { + return storeId; + } + + @JsonProperty("storeId") + public void setStoreId(String storeId) { + this.storeId = storeId; + } + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Subscription [createdAt="); + builder.append(createdAt); + builder.append(", updatedAt="); + builder.append(updatedAt); + builder.append(", startAt="); + builder.append(startAt); + builder.append(", businessId="); + builder.append(businessId); + builder.append(", appId="); + builder.append(appId); + builder.append(", subscriptionId="); + builder.append(subscriptionId); + builder.append(", phase="); + builder.append(phase); + builder.append(", planId="); + builder.append(planId); + builder.append(", bundleId="); + builder.append(bundleId); + builder.append(", status="); + builder.append(status); + builder.append(", storeId="); + builder.append(storeId); + builder.append(", additionalProperties="); + builder.append(additionalProperties); + builder.append("]"); + return builder.toString(); + } + +} \ No newline at end of file diff --git a/src/main/java/co/poynt/api/sdk/Api.java b/src/main/java/co/poynt/api/sdk/Api.java index 690bffb..445eae8 100644 --- a/src/main/java/co/poynt/api/sdk/Api.java +++ b/src/main/java/co/poynt/api/sdk/Api.java @@ -13,215 +13,253 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import co.poynt.api.model.Code; import co.poynt.api.model.ErrorInfo; public abstract class Api { - protected PoyntSdk sdk; - protected String endPoint; - - public Api(PoyntSdk sdk, String endPoint) { - this.sdk = sdk; - this.endPoint = endPoint; - } - - public HttpGet createGetRequest(String url) { - HttpGet get = new HttpGet(url); - get.setHeader(HttpHeaders.USER_AGENT, Constants.SDK_AGENT + ": " + this.sdk.getConfig().getAppId()); - get.setHeader("api-version", Constants.POYNT_API_VERSION); - return get; - } - - public HttpPost createPostRequest(String url) { - HttpPost post = new HttpPost(url); - post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json"); - post.setHeader(HttpHeaders.USER_AGENT, Constants.SDK_AGENT + ": " + this.sdk.getConfig().getAppId()); - post.setHeader("api-version", Constants.POYNT_API_VERSION); - return post; - } - - public void handleError(HttpResponse response) { - try { - ErrorInfo error = this.readResponse(response, ErrorInfo.class); - - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { - if (error.getCode() == Code.INVALID_ACCESS_TOKEN) { - this.sdk.clearAccessToken(); - } else if (error.getCode() == Code.INVALID_REFRESH_TOKEN) { - this.sdk.clearRefreshToken(); - } - } - - throw new PoyntSdkException(error.getDeveloperMessage(), error); - } catch (IOException e) { - throw new PoyntSdkException("Failed to handle error for response."); - } - } - - private String readResponse(HttpResponse response) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); - StringBuffer sb = new StringBuffer(); - String line = ""; - while ((line = reader.readLine()) != null) { - sb.append(line); - } - - return sb.toString(); - } - - public T readResponse(HttpResponse response, Class resourceType) throws IOException { - String responseContent = readResponse(response); - - T result = (T) this.sdk.getOm().readValue(responseContent, resourceType); - return result; - } - - public List readListResponse(HttpResponse response, Class resourceType) throws IOException { - String responseContent = readResponse(response); - - List> tmp = this.sdk.getOm().readValue(responseContent, List.class); - List result = new ArrayList(tmp.size()); - for (Map obj : tmp) { - T item = this.sdk.getOm().convertValue(obj, resourceType); - result.add(item); - } - - return result; - } - - public T get(Class resourceType, String itemId) { - String accessToken = sdk.getAccessToken(); - - String baseUrl = this.endPoint + "/" + itemId; - HttpGet get = this.createGetRequest(baseUrl); - - get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - T result = null; - try { - HttpResponse response = this.sdk.getHttpClient().execute(get); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { - result = (T) this.readResponse(response, resourceType); - } else { - handleError(response); - } - } catch (IOException e) { - throw new PoyntSdkException("Failed to get resource."); - } finally { - get.releaseConnection(); - } - - return result; - } - - public T getFromBusiness(Class resourceType, String businessId, String resourceId) { - String accessToken = sdk.getAccessToken(); - - String baseUrl = this.endPoint.replace("{businessId}", businessId) + "/" + resourceId; - HttpGet get = this.createGetRequest(baseUrl); - - get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - T result = null; - try { - HttpResponse response = this.sdk.getHttpClient().execute(get); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { - result = (T) this.readResponse(response, resourceType); - } else { - handleError(response); - } - } catch (IOException e) { - throw new PoyntSdkException("Failed to get resource."); - } finally { - get.releaseConnection(); - } - - return result; - } - - public List getAllFromBusiness(Class resourceType, String businessId) { - List result = null; - String accessToken = sdk.getAccessToken(); - - String baseUrl = this.endPoint.replace("{businessId}", businessId); - HttpGet get = this.createGetRequest(baseUrl); - - get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - try { - HttpResponse response = this.sdk.getHttpClient().execute(get); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { - result = this.readListResponse(response, resourceType); - } else { - handleError(response); - } - } catch (IOException e) { - throw new PoyntSdkException("Failed to get business"); - } finally { - get.releaseConnection(); - } - - return result; - } - - public T create(T resource) { - String accessToken = sdk.getAccessToken(); - - String baseUrl = this.endPoint; - HttpPost post = this.createPostRequest(baseUrl); - - post.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - T result = null; - try { - String payload = this.sdk.getOm().writeValueAsString(resource); - StringEntity entity = new StringEntity(payload); - post.setEntity(entity); - - HttpResponse response = this.sdk.getHttpClient().execute(post); - int httpCode = response.getStatusLine().getStatusCode(); - if (httpCode == HttpStatus.SC_ACCEPTED || httpCode == HttpStatus.SC_NO_CONTENT) { - // no result - result = null; - } else if (httpCode == HttpStatus.SC_CREATED || httpCode == HttpStatus.SC_OK) { - result = (T) this.readResponse(response, resource.getClass()); - } else { - handleError(response); - } - } catch (IOException e) { - throw new PoyntSdkException("Failed to create resource."); - } finally { - post.releaseConnection(); - } - - return result; - } - - public T createAtBusiness(T resource, String businessId) { - String accessToken = sdk.getAccessToken(); - - String baseUrl = this.endPoint.replace("{businessId}", businessId); - HttpPost post = this.createPostRequest(baseUrl); - - post.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - T result = null; - try { - String payload = this.sdk.getOm().writeValueAsString(resource); - StringEntity entity = new StringEntity(payload); - post.setEntity(entity); - - HttpResponse response = this.sdk.getHttpClient().execute(post); - int httpCode = response.getStatusLine().getStatusCode(); - if (httpCode == HttpStatus.SC_ACCEPTED || httpCode == HttpStatus.SC_NO_CONTENT) { - result = null; - } else if (httpCode == HttpStatus.SC_CREATED || httpCode == HttpStatus.SC_OK) { - result = (T) this.readResponse(response, resource.getClass()); - } else { - handleError(response); - } - } catch (IOException e) { - throw new PoyntSdkException("Failed to create resource at business."); - } finally { - post.releaseConnection(); - } - - return result; - } + + private static final Logger logger = LoggerFactory.getLogger(Api.class); + protected PoyntSdk sdk; + protected String endPoint; + + public Api(PoyntSdk sdk, String endPoint) { + this.sdk = sdk; + this.endPoint = endPoint; + } + + public HttpGet createGetRequest(String url) { + HttpGet get = new HttpGet(url); + get.setHeader(HttpHeaders.USER_AGENT, Constants.SDK_AGENT + ": " + this.sdk.getConfig().getAppId()); + get.setHeader("api-version", Constants.POYNT_API_VERSION); + return get; + } + + public HttpPost createPostRequest(String url) { + HttpPost post = new HttpPost(url); + post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json"); + post.setHeader(HttpHeaders.USER_AGENT, Constants.SDK_AGENT + ": " + this.sdk.getConfig().getAppId()); + post.setHeader("api-version", Constants.POYNT_API_VERSION); + return post; + } + + public void handleError(HttpResponse response) { + try { + logger.debug("response={}", response.toString()); + ErrorInfo error = this.readResponse(response, ErrorInfo.class); + + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { + if (error.getCode() == Code.INVALID_ACCESS_TOKEN) { + this.sdk.clearAccessToken(); + } + else if (error.getCode() == Code.INVALID_REFRESH_TOKEN) { + this.sdk.clearRefreshToken(); + } + } + + throw new PoyntSdkException(error.getDeveloperMessage(), error); + } + catch (IOException e) { + throw new PoyntSdkException("Failed to handle error for response."); + } + } + + private String readResponse(HttpResponse response) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); + StringBuffer sb = new StringBuffer(); + String line = ""; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + + return sb.toString(); + } + + public T readResponse(HttpResponse response, Class resourceType) throws IOException { + String responseContent = readResponse(response); + + T result = (T)this.sdk.getOm().readValue(responseContent, resourceType); + return result; + } + + public List readListResponse(HttpResponse response, Class resourceType) throws IOException { + String responseContent = readResponse(response); + + List> tmp = this.sdk.getOm().readValue(responseContent, List.class); + List result = new ArrayList(tmp.size()); + for (Map obj : tmp) { + T item = this.sdk.getOm().convertValue(obj, resourceType); + result.add(item); + } + + return result; + } + + public T get(Class resourceType, String itemId) { + String accessToken = sdk.getAccessToken(); + + String baseUrl = this.endPoint + "/" + itemId; + HttpGet get = this.createGetRequest(baseUrl); + + get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + T result = null; + try { + HttpResponse response = this.sdk.getHttpClient().execute(get); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = (T)this.readResponse(response, resourceType); + } + else { + handleError(response); + } + } + catch (IOException e) { + + logger.error("Failed to get resource.", e); + + throw new PoyntSdkException("Failed to get resource."); + } + finally { + get.releaseConnection(); + } + + return result; + } + + public T getFromBusiness(Class resourceType, String businessId, String resourceId) { + String accessToken = sdk.getAccessToken(); + + String baseUrl = this.endPoint.replace("{businessId}", businessId) + "/" + resourceId; + HttpGet get = this.createGetRequest(baseUrl); + + get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + T result = null; + try { + HttpResponse response = this.sdk.getHttpClient().execute(get); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = (T)this.readResponse(response, resourceType); + } + else { + handleError(response); + } + } + catch (IOException e) { + + logger.error("Failed to get resource.", e); + + throw new PoyntSdkException("Failed to get resource."); + } + finally { + get.releaseConnection(); + } + + return result; + } + + public List getAllFromBusiness(Class resourceType, String businessId) { + List result = null; + String accessToken = sdk.getAccessToken(); + + String baseUrl = this.endPoint.replace("{businessId}", businessId); + HttpGet get = this.createGetRequest(baseUrl); + + get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + try { + HttpResponse response = this.sdk.getHttpClient().execute(get); + + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = this.readListResponse(response, resourceType); + } + else { + handleError(response); + } + } + catch (IOException e) { + e.printStackTrace(); + logger.error("Failed to get from business {}", businessId, e); + + throw new PoyntSdkException("Failed to get business"); + } + finally { + get.releaseConnection(); + } + + return result; + } + + public T create(T resource) { + String accessToken = sdk.getAccessToken(); + + String baseUrl = this.endPoint; + HttpPost post = this.createPostRequest(baseUrl); + + post.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + T result = null; + try { + String payload = this.sdk.getOm().writeValueAsString(resource); + StringEntity entity = new StringEntity(payload); + post.setEntity(entity); + + HttpResponse response = this.sdk.getHttpClient().execute(post); + int httpCode = response.getStatusLine().getStatusCode(); + if (httpCode == HttpStatus.SC_ACCEPTED || httpCode == HttpStatus.SC_NO_CONTENT) { + // no result + result = null; + } + else if (httpCode == HttpStatus.SC_CREATED || httpCode == HttpStatus.SC_OK) { + result = (T)this.readResponse(response, resource.getClass()); + } + else { + handleError(response); + } + } + catch (IOException e) { + + logger.error("Failed to create resource.", e); + + throw new PoyntSdkException("Failed to create resource."); + } + finally { + post.releaseConnection(); + } + + return result; + } + + public T createAtBusiness(T resource, String businessId) { + String accessToken = sdk.getAccessToken(); + + String baseUrl = this.endPoint.replace("{businessId}", businessId); + HttpPost post = this.createPostRequest(baseUrl); + + post.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + T result = null; + try { + String payload = this.sdk.getOm().writeValueAsString(resource); + StringEntity entity = new StringEntity(payload); + post.setEntity(entity); + + HttpResponse response = this.sdk.getHttpClient().execute(post); + int httpCode = response.getStatusLine().getStatusCode(); + if (httpCode == HttpStatus.SC_ACCEPTED || httpCode == HttpStatus.SC_NO_CONTENT) { + result = null; + } + else if (httpCode == HttpStatus.SC_CREATED || httpCode == HttpStatus.SC_OK) { + result = (T)this.readResponse(response, resource.getClass()); + } + else { + handleError(response); + } + } + catch (IOException e) { + logger.error("Failed to create resource at business.", e); + throw new PoyntSdkException("Failed to create resource at business."); + } + finally { + post.releaseConnection(); + } + + return result; + } } diff --git a/src/main/java/co/poynt/api/sdk/ApiCustomer.java b/src/main/java/co/poynt/api/sdk/ApiCustomer.java new file mode 100644 index 0000000..9416984 --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/ApiCustomer.java @@ -0,0 +1,62 @@ +package co.poynt.api.sdk; + +import java.io.IOException; + +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import co.poynt.api.model.Customer; +import co.poynt.api.model.CustomerList; + +//by Wavelety, Inc. +public class ApiCustomer extends Api { + public static final String API_CUSTOMERS = "/businesses/{businessId}/customers"; + private static final Logger logger = LoggerFactory.getLogger(ApiCustomer.class); + + public ApiCustomer(PoyntSdk sdk) { + super(sdk, Constants.POYNT_API_HOST + API_CUSTOMERS); + } + + + public Customer get(String businessId, String customerId) { + return this.getFromBusiness(Customer.class, businessId, customerId); + } + + + public CustomerList getAll(String businessId, String next) { + CustomerList result = null; + String accessToken = sdk.getAccessToken(); + + String baseUrl = this.endPoint.replace("{businessId}", businessId); + baseUrl += "?limit=100"; + if(next != null) { + baseUrl = Constants.POYNT_API_HOST + next; + } + + logger.info("getAll: url={}", baseUrl); + HttpGet get = this.createGetRequest(baseUrl); + + get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + try { + HttpResponse response = this.sdk.getHttpClient().execute(get); + + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = this.readResponse(response, CustomerList.class); + } else { + handleError(response); + } + } catch (IOException e) { + e.printStackTrace(); + logger.error("Failed to get customers from business {}", businessId, e); + throw new PoyntSdkException("Failed to get customers from business=" + businessId); + } finally { + get.releaseConnection(); + } + return result; + + } +} diff --git a/src/main/java/co/poynt/api/sdk/ApiPlan.java b/src/main/java/co/poynt/api/sdk/ApiPlan.java new file mode 100644 index 0000000..10c641c --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/ApiPlan.java @@ -0,0 +1,62 @@ +package co.poynt.api.sdk; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ApiPlan extends CustomApi { + + static final Logger logger = LoggerFactory.getLogger(ApiPlan.class); + + public static final String API_PLANS = "/apps/{appId}/plans"; + + public ApiPlan(PoyntSdk sdk, String appId) { + + super(sdk, Constants.POYNT_BILLING_API_HOST + API_PLANS.replace("{appId}", appId)); + + } + /** + * { + "list": [{ + "description": "Wifi plan", + "scope": "STORE", + "createdAt": "2018-10-23T19:18:25Z", + "updatedAt": "2018-10-23T19:18:25Z", + "amounts": [{ + "country": "US", + "currency": "USD", + "value": 100 + }], + "interval": "MONTH", + "trialPeriodDays": 0, + "startPolicy": "IMMEDIATE", + "cancelPolicy": "BILLING", + "appId": "urn:aid:08bc7784-a262-4b97-a84c-348ba0f21c3f", + "amount": 100, + "planId": "21e8ad2b-0fde-43b6-bcd9-276855ed092c", + "status": "ACTIVE", + "name": "Test WiFi" + }, { + "description": "Use this test plan for testing", + "scope": "STORE", + "createdAt": "2018-10-23T19:18:21Z", + "updatedAt": "2018-10-23T19:18:21Z", + "amounts": [{ + "country": "US", + "currency": "USD", + "value": 100 + }], + "interval": "MONTH", + "trialPeriodDays": 0, + "startPolicy": "IMMEDIATE", + "cancelPolicy": "BILLING", + "appId": "urn:aid:08bc7784-a262-4b97-a84c-348ba0f21c3f", + "amount": 100, + "planId": "9f89bac6-732d-4fdf-b8f5-9f255e246489", + "status": "ACTIVE", + "name": "Test Email" + }], + "start": 0, + "total": 2, + "count": 2 + */ +} diff --git a/src/main/java/co/poynt/api/sdk/ApiStore.java b/src/main/java/co/poynt/api/sdk/ApiStore.java new file mode 100644 index 0000000..1ecd3fd --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/ApiStore.java @@ -0,0 +1,21 @@ +package co.poynt.api.sdk; + +import java.util.List; + + +import co.poynt.api.model.Store; + +public class ApiStore extends Api { + + public ApiStore(PoyntSdk sdk) { + super(sdk, Constants.POYNT_API_HOST + Constants.API_STORES); + } + + public List getAll(String businessId) { + return this.getAllFromBusiness(Store.class, businessId); + } + + public Store get(String businessId, String storeId) { + return this.getFromBusiness(Store.class, businessId, storeId); + } +} diff --git a/src/main/java/co/poynt/api/sdk/ApiSubscription.java b/src/main/java/co/poynt/api/sdk/ApiSubscription.java new file mode 100644 index 0000000..de6a787 --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/ApiSubscription.java @@ -0,0 +1,61 @@ +package co.poynt.api.sdk; + +import java.io.IOException; + +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import co.poynt.api.model.ResourceList; +import co.poynt.api.model.Subscription; + +public class ApiSubscription extends CustomApi { + + private static final Logger logger = LoggerFactory.getLogger(ApiSubscription.class); + + public static final String API_SUBSCRIPTIONS = "/apps/{appId}/subscriptions"; + + public ApiSubscription(PoyntSdk sdk, String appId) { + + super(sdk, Constants.POYNT_BILLING_API_HOST + API_SUBSCRIPTIONS.replace("{appId}", appId)); + + } + + public ResourceList getAllFromBusiness(String businessId) { + ResourceList result = null; + String accessToken = sdk.getAccessToken(); + String baseUrl = this.endPoint + "?businessId={businessId}"; + + baseUrl = baseUrl.replace("{businessId}", businessId); + HttpGet get = this.createGetRequest(baseUrl); + + get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + try { + HttpResponse response = this.sdk.getHttpClient().execute(get); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = this.readResourceListResponse(response); + } + else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) { + logger.error("No subscription found for businessId={} error={}", businessId, response.toString()); + } + else { + handleError(response); + } + } + catch (IOException e) { + + logger.error("Failed to get subscriptions", e); + + throw new PoyntSdkException("Failed to get subscriptions"); + } + finally { + get.releaseConnection(); + } + + return result; + } + +} diff --git a/src/main/java/co/poynt/api/sdk/ApiWebhooks.java b/src/main/java/co/poynt/api/sdk/ApiWebhooks.java new file mode 100644 index 0000000..e4a6b86 --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/ApiWebhooks.java @@ -0,0 +1,59 @@ +package co.poynt.api.sdk; + + +import java.io.IOException; + +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import co.poynt.api.model.ResourceList; +import co.poynt.api.model.Hook; + +public class ApiWebhooks extends CustomApi { + + private static final Logger logger = LoggerFactory.getLogger(ApiWebhooks.class); + public ApiWebhooks(PoyntSdk sdk) { + + super(sdk, Constants.POYNT_API_HOST + Constants.API_WEBHOOKS); + + } + + public ResourceList getAllFromBusiness(String businessId) { + ResourceList result = null; + String accessToken = sdk.getAccessToken(); + String baseUrl = this.endPoint + "?businessId={businessId}"; + + baseUrl = baseUrl.replace("{businessId}", businessId); + HttpGet get = this.createGetRequest(baseUrl); + + get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + try { + HttpResponse response = this.sdk.getHttpClient().execute(get); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = this.readResourceListResponse(response); + } + else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) { + logger.error("No Hook found for businessId={} error={}", businessId, response.toString()); + } + else { + handleError(response); + } + } + catch (IOException e) { + + logger.error("Failed to get Hooks", e); + + throw new PoyntSdkException("Failed to get Hooks"); + } + finally { + get.releaseConnection(); + } + + return result; + } + +} diff --git a/src/main/java/co/poynt/api/sdk/Constants.java b/src/main/java/co/poynt/api/sdk/Constants.java index aadcddc..125e7a0 100644 --- a/src/main/java/co/poynt/api/sdk/Constants.java +++ b/src/main/java/co/poynt/api/sdk/Constants.java @@ -1,26 +1,28 @@ package co.poynt.api.sdk; public class Constants { - public static final String SDK_AGENT = "PoyntJavaSDK 1.0"; + public static final String SDK_AGENT = "PoyntJavaSDK 1.0"; - public static final String PROP_APP_ID = "appId"; - public static final String PROP_APP_KEY_FILE = "appKeyFile"; + public static final String PROP_APP_ID = "appId"; + public static final String PROP_APP_KEY_FILE = "appKeyFile"; - public static final String PROP_API_SOCKET_TIMEOUT = "httpSocketTimeout"; - public static final String PROP_API_CONNECT_TIMEOUT = "httpConnectTimeout"; - public static final String PROP_API_REQUEST_TIMEOUT = "httpRequestTimeout"; - public static final String PROP_API_MAX_CONNECTION = "httpMaxConnection"; - public static final String PROP_API_MAX_CONN_PER_ROUTE = "httpMaxConnectionPerRoute"; + public static final String PROP_API_SOCKET_TIMEOUT = "httpSocketTimeout"; + public static final String PROP_API_CONNECT_TIMEOUT = "httpConnectTimeout"; + public static final String PROP_API_REQUEST_TIMEOUT = "httpRequestTimeout"; + public static final String PROP_API_MAX_CONNECTION = "httpMaxConnection"; + public static final String PROP_API_MAX_CONN_PER_ROUTE = "httpMaxConnectionPerRoute"; - public static final String POYNT_API_VERSION = "1.2"; - public static final String POYNT_API_HOST = "https://services.poynt.net"; - public static final String API_TOKEN = "/token"; - public static final String API_BUSINESSES = "/businesses"; - public static final String API_BUSINESS_USERS = "/businesses/{businessId}/businessUsers"; - public static final String API_CATALOGS = "/businesses/{businessId}/catalogs"; - public static final String API_PRODUCTS = "/businesses/{businessId}/products"; - public static final String API_TRANSACTIONS = "/businesses/{businessId}/transactions"; - public static final String API_ORDERS = "/businesses/{businessId}/orders"; - public static final String API_CLOUD_MESSAGES = "/cloudMessages"; - public static final String API_WEBHOOKS = "/hooks"; + public static final String POYNT_API_VERSION = "1.2"; + public static final String POYNT_API_HOST = "https://services.poynt.net"; + public static final String POYNT_BILLING_API_HOST = "https://billing.poynt.net"; + public static final String API_TOKEN = "/token"; + public static final String API_BUSINESSES = "/businesses"; + public static final String API_BUSINESS_USERS = "/businesses/{businessId}/businessUsers"; + public static final String API_CATALOGS = "/businesses/{businessId}/catalogs"; + public static final String API_PRODUCTS = "/businesses/{businessId}/products"; + public static final String API_TRANSACTIONS = "/businesses/{businessId}/transactions"; + public static final String API_ORDERS = "/businesses/{businessId}/orders"; + public static final String API_STORES = "/businesses/{businessId}/stores"; + public static final String API_CLOUD_MESSAGES = "/cloudMessages"; + public static final String API_WEBHOOKS = "/hooks"; } diff --git a/src/main/java/co/poynt/api/sdk/CustomApi.java b/src/main/java/co/poynt/api/sdk/CustomApi.java new file mode 100644 index 0000000..e411fc0 --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/CustomApi.java @@ -0,0 +1,85 @@ +package co.poynt.api.sdk; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; + +import co.poynt.api.model.ResourceList; + +/** + * ColigsoApi provides methods to manage Poynt Billing, WebHooks, etc. + * @author sanjay + * + */ +public class CustomApi extends Api { + + static final Logger logger = LoggerFactory.getLogger(CustomApi.class); + + public CustomApi(PoyntSdk sdk, String endPoint) { + super(sdk, endPoint); + // TODO Auto-generated constructor stub + } + + public ResourceList readResourceListResponse(HttpResponse response) throws IOException { + String responseContent = readResponse(response); + + ResourceList responseList = this.sdk.getOm().readValue(responseContent, new TypeReference>() {}); + return responseList; + } + + private String readResponse(HttpResponse response) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); + StringBuffer sb = new StringBuffer(); + String line = ""; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + + return sb.toString(); + } + + /** + * getAll + * @param resourceType + * @return + */ + public ResourceList getAll() { + ResourceList result = null; + String accessToken = sdk.getAccessToken(); + + String baseUrl = this.endPoint; + HttpGet get = this.createGetRequest(baseUrl); + + get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + try { + HttpResponse response = this.sdk.getHttpClient().execute(get); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = this.readResourceListResponse(response); + } + else { + handleError(response); + } + } + catch (IOException e) { + + logger.error("Failed to get resource", e); + + throw new PoyntSdkException("Failed to get resource " + e.getMessage()); + } + finally { + get.releaseConnection(); + } + + return result; + } + +} diff --git a/src/main/java/co/poynt/api/sdk/GetCustomer.java b/src/main/java/co/poynt/api/sdk/GetCustomer.java new file mode 100644 index 0000000..f714353 --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/GetCustomer.java @@ -0,0 +1,43 @@ +package co.poynt.api.sdk; + +import java.io.FileNotFoundException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Map; + +import co.poynt.api.model.Customer; + +/** + * Utility to get customer for given app + * + */ +public class GetCustomer { + public static void main(String[] args) throws FileNotFoundException { + + final String businessId = "11616893-4a93-4f1a-b81a-8762abf1d8c6"; //cafe cafe + final String appId = "urn:aid:f3bb639a-2073-4928-9d2d-6ebf34a80f04"; //spotindev + + PoyntSdk sdk = PoyntSdk.builder().configure("config.properties").build(); + + PoyntSdkBuilder builder2 = new PoyntSdkBuilder(); + Reader reader = new InputStreamReader(GetCustomer.class.getClassLoader().getResourceAsStream("urn_aid_f3bb639a-2073-4928-9d2d-6ebf34a80f04_publicprivatekey.pem")); + + builder2.configure(appId, reader); + builder2.rebuild(sdk); + + ApiCustomer apiCustomer = new ApiCustomer(sdk); + + //getAllCustomers has parsing problems +// List customers = apiCustomer.getAllCustomers(businessId); +// for (Customer customer : customers) { +// System.out.println("Customer=" + customer.toString()); +// } + Customer customer = apiCustomer.getFromBusiness(Customer.class, businessId, "" + 77416525); + System.out.println("retrieve customer=" + customer.toString()); + Map atts = customer.getAttributes(); + for(Map.Entry entry: atts.entrySet()) { + System.out.println("k=" + entry.getKey() + " val=" + entry.getValue()); + } + System.out.println("=============Done!"); + } +} diff --git a/src/main/java/co/poynt/api/sdk/JsonWebTokenService.java b/src/main/java/co/poynt/api/sdk/JsonWebTokenService.java new file mode 100644 index 0000000..604f9d4 --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/JsonWebTokenService.java @@ -0,0 +1,123 @@ +package co.poynt.api.sdk; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.security.KeyPair; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.JWSVerifier; +import com.nimbusds.jose.crypto.RSASSASigner; +import com.nimbusds.jose.crypto.RSASSAVerifier; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; + +//by Wavelety, Inc. +public class JsonWebTokenService extends JsonWebToken { + private String appId; + private KeyPair keyPair; + + public JsonWebTokenService(Config config) { + super(config); + } + + /** + * init initializes with given appId and key pair in string format + * @param appId + * @param keyPairString + * @return + * @throws IOException + */ + public JsonWebTokenService init(String appId, Reader keyPairReader) throws IOException { + if (appId == null || appId.isEmpty()) { + throw new IllegalArgumentException("appId is required"); + } + if (keyPairReader == null) { + throw new IllegalArgumentException("keyPairReader is required"); + } + this.appId = appId; + + try (PEMParser pp = new PEMParser(keyPairReader)) { + PEMKeyPair pemKeyPair = (PEMKeyPair)pp.readObject(); + keyPair = new JcaPEMKeyConverter().getKeyPair(pemKeyPair); + } + return this; + } + + @Override + public String selfIssue() { + JWSSigner signer = new RSASSASigner((RSAPrivateKey)keyPair.getPrivate()); + + List aud = new ArrayList(); + aud.add(Constants.POYNT_API_HOST); + + JWTClaimsSet claimsSet = new JWTClaimsSet(); + claimsSet.setAudience(aud); + claimsSet.setSubject(appId); + claimsSet.setIssuer(appId); + Calendar now = Calendar.getInstance(); + claimsSet.setIssueTime(now.getTime()); + now.add(Calendar.MINUTE, 15); + claimsSet.setExpirationTime(now.getTime()); + claimsSet.setJWTID(UUID.randomUUID().toString()); + + SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet); + + try { + signedJWT.sign(signer); + } + catch (JOSEException e) { + throw new PoyntSdkException("Failed to sign self issued JWT."); + } + return signedJWT.serialize(); + } + + /** + * decode decodes given JWT and returns claims + * @param jwtString + * @return claims + * { + * "sub": "urn:aid:08bc7784-a262-4b97-a84c-348ba0f21c3f", + * "aud": "urn:aid:08bc7784-a262-4b97-a84c-348ba0f21c3f", + * "poynt.sct": "J", + * "poynt.org": "6dc5a48d-8f99-41e9-b716-b3c564f0711c", + * "iss": "https:\/\/services.poynt.net", + * "poynt.kid": 6155246152827141777, + * "poynt.aty": "S", + * "exp": 1534773013, + * "iat": 1534686613, + * "jti": "533b9d4e-03e0-40de-9b27-bc2c4d4d8c6a" + * } + */ + public Map decode(String jwtString) { + try { + + SignedJWT signedJWT = SignedJWT.parse(jwtString); + + JWTClaimsSet claimsSet = (JWTClaimsSet)signedJWT.getJWTClaimsSet(); + return claimsSet.getAllClaims(); + + } + catch (ParseException e) { + throw new PoyntSdkException("Failed to parse given JWT."); + } + + } + +} diff --git a/src/main/java/co/poynt/api/sdk/Main.java b/src/main/java/co/poynt/api/sdk/Main.java index 5394337..2706c8e 100644 --- a/src/main/java/co/poynt/api/sdk/Main.java +++ b/src/main/java/co/poynt/api/sdk/Main.java @@ -34,7 +34,7 @@ public static void main(String[] args) { System.out.println("=============Webhooks"); Hook hook = new Hook(); hook.setApplicationId(sdk.getConfig().getAppId()); - hook.setBusinessId(UUID.fromString(businessId)); + //hook.setBusinessId(UUID.fromString(businessId)); hook.setDeliveryUrl("https://my-webhook-recipient.com/somewhere"); hook.setEventTypes(Arrays.asList(new String[] { "ORDER_OPENED", "PRODUCT_CREATED" })); diff --git a/src/main/java/co/poynt/api/sdk/PoyntSdk.java b/src/main/java/co/poynt/api/sdk/PoyntSdk.java index 1fd3ce9..65f5f0d 100644 --- a/src/main/java/co/poynt/api/sdk/PoyntSdk.java +++ b/src/main/java/co/poynt/api/sdk/PoyntSdk.java @@ -18,8 +18,10 @@ import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.ssl.SSLContexts; @@ -35,228 +37,245 @@ import co.poynt.api.model.TokenResponse; public class PoyntSdk implements Closeable { - private static final Logger logger = LoggerFactory.getLogger(PoyntSdk.class); - private Config config; - private ObjectMapper om; - - private JsonWebToken jsonWebToken; - private CloseableHttpClient httpClient; - - private String accessToken; - private String refreshToken; - - private PoyntSdk() { - // private on purpose - } - - @Override - public void close() { - if (httpClient != null) { - try { - httpClient.close(); - } catch (IOException e) { - e.printStackTrace(); - // ignore - } - } - } - - public void setConfig(Config config) { - this.config = config; - } - - public void jsonWebToken(JsonWebToken jwt) { - this.jsonWebToken = jwt; - } - - public void setHttpClient(CloseableHttpClient client) { - this.httpClient = client; - } - - public void setObjectMapper(ObjectMapper om) { - this.om = om; - } - - public static class Builder { - Config cfg; - JsonWebToken jwt; - CloseableHttpClient client; - ObjectMapper om; - - public Builder config(Config cfg) { - this.cfg = cfg; - return this; - } - - public Builder jwtGenerator(JsonWebToken jwtGen) { - this.jwt = jwtGen; - return this; - } - - public Builder httpClient(CloseableHttpClient client) { - this.client = client; - return this; - } - - public Builder jackson(ObjectMapper om) { - this.om = om; - return this; - } - - public Builder configure(String configFile) throws PoyntSdkException { - - this.cfg = new Config(); - try { - cfg.load(configFile); - } catch (IOException e) { - throw new PoyntSdkException("Failed to load configuration"); - } - - this.jwt = new JsonWebToken(cfg); - try { - jwt.init(); - } catch (IOException e) { - throw new PoyntSdkException("Failed to load keys for JWT generator."); - } - - RequestConfig httpCfg = RequestConfig.custom().setSocketTimeout(cfg.getHttpSocketTimeout()) - .setConnectTimeout(cfg.getHttpConnectTimeout()) - .setConnectionRequestTimeout(cfg.getHttpRequestTimeout()).build(); - - try { - PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); - cm.setMaxTotal(cfg.getHttpMaxConnection()); - cm.setDefaultMaxPerRoute(cfg.getHttpMaxConnPerRoute()); - - SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1.2").build(); - - this.client = HttpClientBuilder.create().setSSLContext(sslContext).setDefaultRequestConfig(httpCfg) - .setConnectionManager(cm).build(); - - } catch (KeyManagementException | NoSuchAlgorithmException e) { - throw new PoyntSdkException("Failed to create http client"); - } - - this.om = new ObjectMapper(); - this.om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); - - this.om.setDateFormat(new ISO8601DateFormat()); - this.om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - this.om.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false); - this.om.setSerializationInclusion(JsonInclude.Include.NON_NULL); - - return this; - } - - public PoyntSdk build() { - PoyntSdk sdk = new PoyntSdk(); - sdk.setConfig(cfg); - sdk.setHttpClient(client); - sdk.jsonWebToken(jwt); - sdk.setObjectMapper(this.om); - return sdk; - } - } - - public static Builder builder() { - return new Builder(); - } - - public void clearAccessToken() { - this.accessToken = null; - } - - public void clearRefreshToken() { - this.accessToken = null; - this.refreshToken = null; - } - - public String getAccessToken() { - if (this.accessToken != null) { - return this.accessToken; - } - HttpPost post = new HttpPost(Constants.POYNT_API_HOST + Constants.API_TOKEN); - post.setHeader("User-Agent", Constants.SDK_AGENT + ": " + this.config.getAppId()); - post.setHeader("api-version", Constants.POYNT_API_VERSION); - String requestId = UUID.randomUUID().toString(); - logger.debug("Poynt-Request-Id: " + requestId); - post.setHeader("Poynt-Request-Id", requestId); - - List urlParameters = new ArrayList(); - - if (this.refreshToken == null) { - String selfIssuedJwt = this.jsonWebToken.selfIssue(); - urlParameters.add(new BasicNameValuePair("grantType", "urn:ietf:params:oauth:grant-type:jwt-bearer")); - urlParameters.add(new BasicNameValuePair("assertion", selfIssuedJwt)); - } else { - urlParameters.add(new BasicNameValuePair("grantType", "REFRESH_TOKEN")); - urlParameters.add(new BasicNameValuePair("refreshToken", this.refreshToken)); - } - - try { - post.setEntity(new UrlEncodedFormEntity(urlParameters)); - - HttpResponse response = httpClient.execute(post); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { - BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); - StringBuffer result = new StringBuffer(); - String line = ""; - while ((line = reader.readLine()) != null) { - result.append(line); - } - - TokenResponse tokenResponse = om.readValue(result.toString(), TokenResponse.class); - this.accessToken = tokenResponse.getAccessToken(); - this.refreshToken = tokenResponse.getRefreshToken(); - return this.accessToken; - } else { - throw new PoyntSdkException( - response.getStatusLine().getStatusCode() + ": " + response.getStatusLine().getReasonPhrase()); - } - } catch (Exception e) { - throw new PoyntSdkException("Failed to obtain access token."); - } finally { - post.releaseConnection(); - } - } - - public Config getConfig() { - return config; - } - - public ObjectMapper getOm() { - return om; - } - - public CloseableHttpClient getHttpClient() { - return httpClient; - } - - public ApiBusiness business() { - return new ApiBusiness(this); - } - - public ApiBusinessUser businessUser() { - return new ApiBusinessUser(this); - } - - public ApiCatalog catalog() { - return new ApiCatalog(this); - } - - public ApiProduct product() { - return new ApiProduct(this); - } - - public ApiTransaction transaction() { - return new ApiTransaction(this); - } - - public ApiOrder order() { - return new ApiOrder(this); - } - - public ApiWebhook webhook() { - return new ApiWebhook(this); - } + private static final Logger logger = LoggerFactory.getLogger(PoyntSdk.class); + private Config config; + private ObjectMapper om; + + private JsonWebToken jsonWebToken; + private CloseableHttpClient httpClient; + + private String accessToken; + private String refreshToken; + + private PoyntSdk() { + // private on purpose + } + + @Override + public void close() { + if (httpClient != null) { + try { + httpClient.close(); + } + catch (IOException e) { + e.printStackTrace(); + // ignore + } + } + } + + public void setConfig(Config config) { + this.config = config; + } + + public void jsonWebToken(JsonWebToken jwt) { + this.jsonWebToken = jwt; + } + + public void setHttpClient(CloseableHttpClient client) { + this.httpClient = client; + } + + public void setObjectMapper(ObjectMapper om) { + this.om = om; + } + + public static class Builder { + Config cfg; + JsonWebToken jwt; + CloseableHttpClient client; + ObjectMapper om; + + public Builder config(Config cfg) { + this.cfg = cfg; + return this; + } + + public Builder jwtGenerator(JsonWebToken jwtGen) { + this.jwt = jwtGen; + return this; + } + + public Builder httpClient(CloseableHttpClient client) { + this.client = client; + return this; + } + + public Builder jackson(ObjectMapper om) { + this.om = om; + return this; + } + + public Builder configure(String configFile) throws PoyntSdkException { + + this.cfg = new Config(); + try { + cfg.load(configFile); + } + catch (IOException e) { + throw new PoyntSdkException("Failed to load configuration"); + } + + this.jwt = new JsonWebToken(cfg); + try { + jwt.init(); + } + catch (IOException e) { + throw new PoyntSdkException("Failed to load keys for JWT generator."); + } + + RequestConfig httpCfg = RequestConfig.custom().setSocketTimeout(cfg.getHttpSocketTimeout()) + .setConnectTimeout(cfg.getHttpConnectTimeout()) + .setConnectionRequestTimeout(cfg.getHttpRequestTimeout()).build(); + + try { + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + cm.setMaxTotal(cfg.getHttpMaxConnection()); + cm.setDefaultMaxPerRoute(cfg.getHttpMaxConnPerRoute()); + + SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1.2").build(); + //following works with jdk 1.7 -sd + SSLConnectionSocketFactory sslCSFactory = new SSLConnectionSocketFactory( + sslContext, + new String[] { "TLSv1.2" }, + null, + SSLConnectionSocketFactory.getDefaultHostnameVerifier()); + this.client = HttpClients.custom() + .setSSLSocketFactory(sslCSFactory) + .build(); + + //setting cm and httpcfg overrides tls1.2 setting + //.setConnectionManager(cm).setDefaultRequestConfig(httpCfg) + + } catch (KeyManagementException | NoSuchAlgorithmException e) { + throw new PoyntSdkException("Failed to create http client"); + } + + this.om = new ObjectMapper(); + this.om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + + this.om.setDateFormat(new ISO8601DateFormat()); + this.om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + //not compatible with jdk 7 -sd + //this.om.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false); + this.om.setSerializationInclusion(JsonInclude.Include.NON_NULL); + + return this; + } + + public PoyntSdk build() { + PoyntSdk sdk = new PoyntSdk(); + sdk.setConfig(cfg); + sdk.setHttpClient(client); + sdk.jsonWebToken(jwt); + sdk.setObjectMapper(this.om); + return sdk; + } + } + + public static Builder builder() { + return new Builder(); + } + + public void clearAccessToken() { + this.accessToken = null; + } + + public void clearRefreshToken() { + this.accessToken = null; + this.refreshToken = null; + } + + public String getAccessToken() { + if (this.accessToken != null) { + return this.accessToken; + } + HttpPost post = new HttpPost(Constants.POYNT_API_HOST + Constants.API_TOKEN); + post.setHeader("User-Agent", Constants.SDK_AGENT + ": " + this.config.getAppId()); + post.setHeader("api-version", Constants.POYNT_API_VERSION); + String requestId = UUID.randomUUID().toString(); + logger.debug("Poynt-Request-Id: " + requestId); + post.setHeader("Poynt-Request-Id", requestId); + + List urlParameters = new ArrayList(); + + if (this.refreshToken == null) { + String selfIssuedJwt = this.jsonWebToken.selfIssue(); + urlParameters.add(new BasicNameValuePair("grantType", "urn:ietf:params:oauth:grant-type:jwt-bearer")); + urlParameters.add(new BasicNameValuePair("assertion", selfIssuedJwt)); + } + else { + urlParameters.add(new BasicNameValuePair("grantType", "REFRESH_TOKEN")); + urlParameters.add(new BasicNameValuePair("refreshToken", this.refreshToken)); + } + + try { + post.setEntity(new UrlEncodedFormEntity(urlParameters)); + + HttpResponse response = httpClient.execute(post); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); + StringBuffer result = new StringBuffer(); + String line = ""; + while ((line = reader.readLine()) != null) { + result.append(line); + } + + TokenResponse tokenResponse = om.readValue(result.toString(), TokenResponse.class); + this.accessToken = tokenResponse.getAccessToken(); + this.refreshToken = tokenResponse.getRefreshToken(); + return this.accessToken; + } + else { + throw new PoyntSdkException( + response.getStatusLine().getStatusCode() + ": " + response.getStatusLine().getReasonPhrase()); + } + } + catch (Exception e) { + throw new PoyntSdkException("Failed to obtain access token."); + } + finally { + post.releaseConnection(); + } + } + + public Config getConfig() { + return config; + } + + public ObjectMapper getOm() { + return om; + } + + public CloseableHttpClient getHttpClient() { + return httpClient; + } + + public ApiBusiness business() { + return new ApiBusiness(this); + } + + public ApiBusinessUser businessUser() { + return new ApiBusinessUser(this); + } + + public ApiCatalog catalog() { + return new ApiCatalog(this); + } + + public ApiProduct product() { + return new ApiProduct(this); + } + + public ApiTransaction transaction() { + return new ApiTransaction(this); + } + + public ApiOrder order() { + return new ApiOrder(this); + } + + public ApiWebhook webhook() { + return new ApiWebhook(this); + } } diff --git a/src/main/java/co/poynt/api/sdk/PoyntSdkBuilder.java b/src/main/java/co/poynt/api/sdk/PoyntSdkBuilder.java new file mode 100644 index 0000000..70402dc --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/PoyntSdkBuilder.java @@ -0,0 +1,140 @@ +package co.poynt.api.sdk; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicNameValuePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +// by Wavelety, Inc. +public class PoyntSdkBuilder extends PoyntSdk.Builder { + private static final Logger logger = LoggerFactory.getLogger(PoyntSdkBuilder.class); + public static final String POYNT_MERCHANT_ID = "poynt.biz"; + public static final String POYNT_ACCESS_TOKEN = "accessToken"; + public static final String POYNT_REFRESH_TOKEN = "refreshToken"; + public static final String POYNT_TOKEN_EXPIRY = "expiresIn"; + + private PoyntSdk sdk; + private JsonWebTokenService jwt2; + + /** + * getJwt2 gives access to JSONToken util providing sign and verify functions + * @return + */ + public JsonWebTokenService getJwt2() { + return jwt2; + } + + public PoyntSdkBuilder configure(String appId, Reader keyPairReader) throws PoyntSdkException { + try { + PoyntSdkConfig config = new PoyntSdkConfig(); + config.load("config.properties"); + config.setAppId(appId); + config.setKeyPair(keyPairReader); + + this.cfg = config; + + //create jwt util + jwt2 = new JsonWebTokenService(null); + jwt2.init(cfg.getAppId(), config.getKeyPair()); + //set in parent so it could be used to set in sdk + this.jwt = jwt2; + + } + catch (IOException e) { + logger.error("Failed to configure ", e); + throw new PoyntSdkException("Failed to initialize JWT2."); + } + + //set httpclient if needed + + return this; + } + + public void rebuild(PoyntSdk sdk) { + sdk.jsonWebToken(this.jwt); + sdk.setConfig(this.cfg); + this.sdk = sdk; + } + + /** + * getAccessToken gets access token after merchant authorizes our app + * @param code + * @param redirectUri + * @return + */ + public Map getAccessToken(String code, String redirectUri) { + + if (code == null) { + throw new IllegalArgumentException("code is required!"); + } + if (redirectUri == null) { + throw new IllegalArgumentException("redirectUri is required!"); + } + /** + * From your server make a HTTP POST request to https://services.poynt.net/token and include the following headers and arguments: + Header: Accept: application/json + Header: Authorization: Bearer {self-signed-JWT} + HTTP param: grant_type=authorization_code + HTTP param: redirect_uri={redirect_uri} + HTTP param: client_id={appId} + HTTP param: code={code} + */ + HttpPost post = new HttpPost(Constants.POYNT_API_HOST + Constants.API_TOKEN); + + post.setHeader("Accept", "application/json"); + post.setHeader("Authorization", "Bearer " + jwt.selfIssue()); + + List urlParameters = new ArrayList(); + + urlParameters.add(new BasicNameValuePair("grant_type", "authorization_code")); + urlParameters.add(new BasicNameValuePair("redirect_uri", redirectUri)); + urlParameters.add(new BasicNameValuePair("client_id", sdk.getConfig().getAppId())); + urlParameters.add(new BasicNameValuePair("code", code)); + + try { + post.setEntity(new UrlEncodedFormEntity(urlParameters)); + + HttpResponse response = sdk.getHttpClient().execute(post); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); + StringBuffer result = new StringBuffer(); + String line = ""; + while ((line = reader.readLine()) != null) { + result.append(line); + } + + @SuppressWarnings("unchecked") + Map tokenProperties = sdk.getOm().readValue(result.toString(), HashMap.class); + return tokenProperties; + } + else { + String emsg = String.format("Failed to get access token for authz code=%s response status=%d message=%s", code, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + logger.error(emsg); + throw new PoyntSdkException(emsg); + } + } + catch (Exception e) { + if(e instanceof PoyntSdkException) { + throw (PoyntSdkException)e; + } + logger.error("Failed to get access token for authz code={}", code, e); + throw new PoyntSdkException("Failed to obtain access token."); + } + finally { + post.releaseConnection(); + } + } +} diff --git a/src/main/java/co/poynt/api/sdk/PoyntSdkConfig.java b/src/main/java/co/poynt/api/sdk/PoyntSdkConfig.java new file mode 100644 index 0000000..093a014 --- /dev/null +++ b/src/main/java/co/poynt/api/sdk/PoyntSdkConfig.java @@ -0,0 +1,24 @@ +package co.poynt.api.sdk; + +import java.io.Reader; + +//by Wavelety, Inc. +public class PoyntSdkConfig extends Config { + + private Reader keyPairReader; + + public void setAppId(String appId) { + prop.setProperty(Constants.PROP_APP_ID, appId); + } + + public Reader getKeyPair() { + return keyPairReader; + } + + public void setKeyPair(Reader keyPairReader) { + this.keyPairReader = keyPairReader; + } + + + +} diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml new file mode 100644 index 0000000..7c1c4a8 --- /dev/null +++ b/src/main/resources/log4j.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +