Java Auth and auth lib changes
This commit is contained in:
parent
39dd71cdb6
commit
fcf32fdff6
|
@ -38,39 +38,6 @@ com.squareup.okhttp.Request signedRequest = new LWAAuthorizationSigner(lwaAuthor
|
||||||
.sign(request);
|
.sign(request);
|
||||||
```
|
```
|
||||||
|
|
||||||
## AWSSigV4Signer
|
|
||||||
Signs a request with [AWS Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)
|
|
||||||
using the provided AWS developer account credentials.
|
|
||||||
|
|
||||||
*Example*
|
|
||||||
```
|
|
||||||
com.squareup.okhttp.Request request = new Request.Builder()
|
|
||||||
.url(...)
|
|
||||||
...
|
|
||||||
.build();
|
|
||||||
|
|
||||||
AWSAuthenticationCredentials awsAuthenticationCredentials = AWSAuthenticationCredentials.builder()
|
|
||||||
.accessKeyId("...")
|
|
||||||
.secretKey("...")
|
|
||||||
.region("...")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
com.squareup.okhttp.Request signedRequest = new AWSSigV4Signer(awsAuthenticationCredentials)
|
|
||||||
.sign(request);
|
|
||||||
|
|
||||||
/*Signs request using IAM role credentials.
|
|
||||||
|
|
||||||
AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider = AWSAuthenticationCredentialsProvider.builder()
|
|
||||||
.roleArn("...")
|
|
||||||
.roleSessionName("...")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
com.squareup.okhttp.Request signedRequest = new
|
|
||||||
AWSSigV4Signer(awsAuthenticationCredentialsProvider.getCredentials())
|
|
||||||
.sign(request);
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## LWAAccessTokenCache
|
## LWAAccessTokenCache
|
||||||
Interface to implement cache for access token that is returned in LWAClient and reuse the access token until time to live.
|
Interface to implement cache for access token that is returned in LWAClient and reuse the access token until time to live.
|
||||||
|
|
||||||
|
@ -79,7 +46,6 @@ Interface to set and get rateLimit configurations that are used with RateLimiter
|
||||||
|
|
||||||
*Example*
|
*Example*
|
||||||
```
|
```
|
||||||
|
|
||||||
com.squareup.okhttp.Request request = new Request.Builder()
|
com.squareup.okhttp.Request request = new Request.Builder()
|
||||||
.url(...)
|
.url(...)
|
||||||
...
|
...
|
||||||
|
@ -89,8 +55,22 @@ com.squareup.okhttp.Request request = new Request.Builder()
|
||||||
.rateLimitPermit(...)
|
.rateLimitPermit(...)
|
||||||
.waitTimeOutInMilliSeconds(...)
|
.waitTimeOutInMilliSeconds(...)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
```
|
```
|
||||||
|
## Exception
|
||||||
|
This package returns a custom LWAException when there is an error returned during LWA authorization. LWAException provides additional details like errorCode and errorDescription to help fix the issue.
|
||||||
|
|
||||||
|
*Example*
|
||||||
|
```
|
||||||
|
catch (LWAException e) {
|
||||||
|
System.err.println("LWA Exception when calling Selling partner API");
|
||||||
|
System.err.println(e.getErrorCode());
|
||||||
|
System.err.println(e.getErrorMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Version
|
||||||
|
Selling Partner API Authentication/Authorization Library version 2.0.
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
This package features Mustache templates designed for use with [swagger codegen](https://swagger.io/tools/swagger-codegen/).
|
This package features Mustache templates designed for use with [swagger codegen](https://swagger.io/tools/swagger-codegen/).
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<groupId>com.amazon.sellingpartnerapi</groupId>
|
<groupId>com.amazon.sellingpartnerapi</groupId>
|
||||||
<artifactId>sellingpartnerapi-aa-java</artifactId>
|
<artifactId>sellingpartnerapi-aa-java</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>1.0</version>
|
<version>2.0</version>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"artifactVersion": "2.0"
|
||||||
|
}
|
|
@ -51,10 +51,10 @@ import {{invokerPackage}}.auth.HttpBasicAuth;
|
||||||
import {{invokerPackage}}.auth.ApiKeyAuth;
|
import {{invokerPackage}}.auth.ApiKeyAuth;
|
||||||
import {{invokerPackage}}.auth.OAuth;
|
import {{invokerPackage}}.auth.OAuth;
|
||||||
|
|
||||||
import com.amazon.SellingPartnerAPIAA.AWSSigV4Signer;
|
|
||||||
import com.amazon.SellingPartnerAPIAA.LWAAuthorizationSigner;
|
import com.amazon.SellingPartnerAPIAA.LWAAuthorizationSigner;
|
||||||
import com.google.common.util.concurrent.RateLimiter;
|
import com.google.common.util.concurrent.RateLimiter;
|
||||||
import com.amazon.SellingPartnerAPIAA.RateLimitConfiguration;
|
import com.amazon.SellingPartnerAPIAA.RateLimitConfiguration;
|
||||||
|
import com.amazon.SellingPartnerAPIAA.LWAException;
|
||||||
|
|
||||||
public class ApiClient {
|
public class ApiClient {
|
||||||
|
|
||||||
|
@ -79,7 +79,6 @@ public class ApiClient {
|
||||||
private HttpLoggingInterceptor loggingInterceptor;
|
private HttpLoggingInterceptor loggingInterceptor;
|
||||||
|
|
||||||
private LWAAuthorizationSigner lwaAuthorizationSigner;
|
private LWAAuthorizationSigner lwaAuthorizationSigner;
|
||||||
private AWSSigV4Signer awsSigV4Signer;
|
|
||||||
private RateLimiter rateLimiter;
|
private RateLimiter rateLimiter;
|
||||||
private RateLimitConfiguration rateLimitConfiguration;
|
private RateLimitConfiguration rateLimitConfiguration;
|
||||||
|
|
||||||
|
@ -496,17 +495,6 @@ public class ApiClient {
|
||||||
this.lwaAuthorizationSigner = lwaAuthorizationSigner;
|
this.lwaAuthorizationSigner = lwaAuthorizationSigner;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the AWSSigV4Signer
|
|
||||||
*
|
|
||||||
* @param awsSigV4Signer AWSSigV4Signer instance
|
|
||||||
* @return Api client
|
|
||||||
*/
|
|
||||||
public ApiClient setAWSSigV4Signer(AWSSigV4Signer awsSigV4Signer) {
|
|
||||||
this.awsSigV4Signer = awsSigV4Signer;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the RateLimiter
|
* Sets the RateLimiter
|
||||||
|
@ -985,8 +973,9 @@ public class ApiClient {
|
||||||
* @param progressRequestListener Progress request listener
|
* @param progressRequestListener Progress request listener
|
||||||
* @return The HTTP call
|
* @return The HTTP call
|
||||||
* @throws ApiException If fail to serialize the request body object
|
* @throws ApiException If fail to serialize the request body object
|
||||||
|
* @throws LWAException If calls to fetch LWA access token fails
|
||||||
*/
|
*/
|
||||||
public Call buildCall(String path, String method, List<Pair> queryParams, List<Pair> collectionQueryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
|
public Call buildCall(String path, String method, List<Pair> queryParams, List<Pair> collectionQueryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException, LWAException {
|
||||||
Request request = buildRequest(path, method, queryParams, collectionQueryParams, body, headerParams, formParams, authNames, progressRequestListener);
|
Request request = buildRequest(path, method, queryParams, collectionQueryParams, body, headerParams, formParams, authNames, progressRequestListener);
|
||||||
|
|
||||||
return httpClient.newCall(request);
|
return httpClient.newCall(request);
|
||||||
|
@ -1006,8 +995,9 @@ public class ApiClient {
|
||||||
* @param progressRequestListener Progress request listener
|
* @param progressRequestListener Progress request listener
|
||||||
* @return The HTTP request
|
* @return The HTTP request
|
||||||
* @throws ApiException If fail to serialize the request body object
|
* @throws ApiException If fail to serialize the request body object
|
||||||
|
* @throws LWAException If calls to fetch LWA access token fails
|
||||||
*/
|
*/
|
||||||
public Request buildRequest(String path, String method, List<Pair> queryParams, List<Pair> collectionQueryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
|
public Request buildRequest(String path, String method, List<Pair> queryParams, List<Pair> collectionQueryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException, LWAException {
|
||||||
updateParamsForAuth(authNames, queryParams, headerParams);
|
updateParamsForAuth(authNames, queryParams, headerParams);
|
||||||
|
|
||||||
final String url = buildUrl(path, queryParams, collectionQueryParams);
|
final String url = buildUrl(path, queryParams, collectionQueryParams);
|
||||||
|
@ -1049,7 +1039,6 @@ public class ApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
request = lwaAuthorizationSigner.sign(request);
|
request = lwaAuthorizationSigner.sign(request);
|
||||||
request = awsSigV4Signer.sign(request);
|
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,15 +43,12 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
{{/fullJavaUtil}}
|
{{/fullJavaUtil}}
|
||||||
|
|
||||||
import com.amazon.SellingPartnerAPIAA.AWSAuthenticationCredentials;
|
|
||||||
import com.amazon.SellingPartnerAPIAA.AWSAuthenticationCredentialsProvider;
|
|
||||||
import com.amazon.SellingPartnerAPIAA.AWSAuthenticationCustomCredentialsProvider;
|
|
||||||
import com.amazon.SellingPartnerAPIAA.AWSSigV4Signer;
|
|
||||||
import com.amazon.SellingPartnerAPIAA.LWAAccessTokenCache;
|
import com.amazon.SellingPartnerAPIAA.LWAAccessTokenCache;
|
||||||
import com.amazon.SellingPartnerAPIAA.LWAAccessTokenCacheImpl;
|
import com.amazon.SellingPartnerAPIAA.LWAAccessTokenCacheImpl;
|
||||||
import com.amazon.SellingPartnerAPIAA.LWAAuthorizationCredentials;
|
import com.amazon.SellingPartnerAPIAA.LWAAuthorizationCredentials;
|
||||||
import com.amazon.SellingPartnerAPIAA.LWAAuthorizationSigner;
|
import com.amazon.SellingPartnerAPIAA.LWAAuthorizationSigner;
|
||||||
import com.amazon.SellingPartnerAPIAA.RateLimitConfiguration;
|
import com.amazon.SellingPartnerAPIAA.RateLimitConfiguration;
|
||||||
|
import com.amazon.SellingPartnerAPIAA.LWAException;
|
||||||
|
|
||||||
{{#operations}}
|
{{#operations}}
|
||||||
public class {{classname}} {
|
public class {{classname}} {
|
||||||
|
@ -81,6 +78,7 @@ public class {{classname}} {
|
||||||
* @param progressRequestListener Progress request listener
|
* @param progressRequestListener Progress request listener
|
||||||
* @return Call to execute
|
* @return Call to execute
|
||||||
* @throws ApiException If fail to serialize the request body object
|
* @throws ApiException If fail to serialize the request body object
|
||||||
|
* @throws LWAException If calls to fetch LWA access token fails
|
||||||
{{#isDeprecated}}
|
{{#isDeprecated}}
|
||||||
* @deprecated
|
* @deprecated
|
||||||
{{/isDeprecated}}
|
{{/isDeprecated}}
|
||||||
|
@ -92,7 +90,7 @@ public class {{classname}} {
|
||||||
{{#isDeprecated}}
|
{{#isDeprecated}}
|
||||||
@Deprecated
|
@Deprecated
|
||||||
{{/isDeprecated}}
|
{{/isDeprecated}}
|
||||||
public com.squareup.okhttp.Call {{operationId}}Call({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
|
public com.squareup.okhttp.Call {{operationId}}Call({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException, LWAException {
|
||||||
Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
||||||
|
|
||||||
// create path and map variables
|
// create path and map variables
|
||||||
|
@ -144,7 +142,7 @@ public class {{classname}} {
|
||||||
@Deprecated
|
@Deprecated
|
||||||
{{/isDeprecated}}
|
{{/isDeprecated}}
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
private com.squareup.okhttp.Call {{operationId}}ValidateBeforeCall({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
|
private com.squareup.okhttp.Call {{operationId}}ValidateBeforeCall({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException, LWAException {
|
||||||
{{^performBeanValidation}}
|
{{^performBeanValidation}}
|
||||||
{{#allParams}}{{#required}}
|
{{#allParams}}{{#required}}
|
||||||
// verify the required parameter '{{paramName}}' is set
|
// verify the required parameter '{{paramName}}' is set
|
||||||
|
@ -191,6 +189,7 @@ public class {{classname}} {
|
||||||
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}{{#returnType}}
|
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}{{#returnType}}
|
||||||
* @return {{returnType}}{{/returnType}}
|
* @return {{returnType}}{{/returnType}}
|
||||||
* @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
|
* @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
|
||||||
|
* @throws LWAException If calls to fetch LWA access token fails
|
||||||
{{#isDeprecated}}
|
{{#isDeprecated}}
|
||||||
* @deprecated
|
* @deprecated
|
||||||
{{/isDeprecated}}
|
{{/isDeprecated}}
|
||||||
|
@ -202,7 +201,7 @@ public class {{classname}} {
|
||||||
{{#isDeprecated}}
|
{{#isDeprecated}}
|
||||||
@Deprecated
|
@Deprecated
|
||||||
{{/isDeprecated}}
|
{{/isDeprecated}}
|
||||||
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
|
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException,LWAException {
|
||||||
{{#returnType}}ApiResponse<{{{returnType}}}> {{localVariablePrefix}}resp = {{/returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}}
|
{{#returnType}}ApiResponse<{{{returnType}}}> {{localVariablePrefix}}resp = {{/returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}}
|
||||||
return {{localVariablePrefix}}resp.getData();{{/returnType}}
|
return {{localVariablePrefix}}resp.getData();{{/returnType}}
|
||||||
}
|
}
|
||||||
|
@ -213,6 +212,7 @@ public class {{classname}} {
|
||||||
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}
|
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}
|
||||||
* @return ApiResponse<{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Void{{/returnType}}>
|
* @return ApiResponse<{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Void{{/returnType}}>
|
||||||
* @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
|
* @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
|
||||||
|
* @throws LWAException If calls to fetch LWA access token fails
|
||||||
{{#isDeprecated}}
|
{{#isDeprecated}}
|
||||||
* @deprecated
|
* @deprecated
|
||||||
{{/isDeprecated}}
|
{{/isDeprecated}}
|
||||||
|
@ -224,7 +224,7 @@ public class {{classname}} {
|
||||||
{{#isDeprecated}}
|
{{#isDeprecated}}
|
||||||
@Deprecated
|
@Deprecated
|
||||||
{{/isDeprecated}}
|
{{/isDeprecated}}
|
||||||
public ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
|
public ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException,LWAException {
|
||||||
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}ValidateBeforeCall({{#allParams}}{{paramName}}, {{/allParams}}null, null);
|
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}ValidateBeforeCall({{#allParams}}{{paramName}}, {{/allParams}}null, null);
|
||||||
{{#returnType}}Type {{localVariablePrefix}}localVarReturnType = new TypeToken<{{{returnType}}}>(){}.getType();
|
{{#returnType}}Type {{localVariablePrefix}}localVarReturnType = new TypeToken<{{{returnType}}}>(){}.getType();
|
||||||
return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call, {{localVariablePrefix}}localVarReturnType);{{/returnType}}{{^returnType}}return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call);{{/returnType}}
|
return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call, {{localVariablePrefix}}localVarReturnType);{{/returnType}}{{^returnType}}return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call);{{/returnType}}
|
||||||
|
@ -237,6 +237,7 @@ public class {{classname}} {
|
||||||
* @param callback The callback to be executed when the API call finishes
|
* @param callback The callback to be executed when the API call finishes
|
||||||
* @return The request call
|
* @return The request call
|
||||||
* @throws ApiException If fail to process the API call, e.g. serializing the request body object
|
* @throws ApiException If fail to process the API call, e.g. serializing the request body object
|
||||||
|
* @throws LWAException If calls to fetch LWA access token fails
|
||||||
{{#isDeprecated}}
|
{{#isDeprecated}}
|
||||||
* @deprecated
|
* @deprecated
|
||||||
{{/isDeprecated}}
|
{{/isDeprecated}}
|
||||||
|
@ -248,7 +249,7 @@ public class {{classname}} {
|
||||||
{{#isDeprecated}}
|
{{#isDeprecated}}
|
||||||
@Deprecated
|
@Deprecated
|
||||||
{{/isDeprecated}}
|
{{/isDeprecated}}
|
||||||
public com.squareup.okhttp.Call {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException {
|
public com.squareup.okhttp.Call {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException, LWAException {
|
||||||
|
|
||||||
ProgressResponseBody.ProgressListener progressListener = null;
|
ProgressResponseBody.ProgressListener progressListener = null;
|
||||||
ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
|
ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
|
||||||
|
@ -277,19 +278,12 @@ public class {{classname}} {
|
||||||
{{/operation}}
|
{{/operation}}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private AWSAuthenticationCredentials awsAuthenticationCredentials;
|
|
||||||
private LWAAuthorizationCredentials lwaAuthorizationCredentials;
|
private LWAAuthorizationCredentials lwaAuthorizationCredentials;
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
private LWAAccessTokenCache lwaAccessTokenCache;
|
private LWAAccessTokenCache lwaAccessTokenCache;
|
||||||
private Boolean disableAccessTokenCache = false;
|
private Boolean disableAccessTokenCache = false;
|
||||||
private AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider;
|
|
||||||
private RateLimitConfiguration rateLimitConfiguration;
|
private RateLimitConfiguration rateLimitConfiguration;
|
||||||
private AWSAuthenticationCustomCredentialsProvider awsAuthenticationCustomCredentialsProvider;
|
|
||||||
|
|
||||||
public Builder awsAuthenticationCredentials(AWSAuthenticationCredentials awsAuthenticationCredentials) {
|
|
||||||
this.awsAuthenticationCredentials = awsAuthenticationCredentials;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder lwaAuthorizationCredentials(LWAAuthorizationCredentials lwaAuthorizationCredentials) {
|
public Builder lwaAuthorizationCredentials(LWAAuthorizationCredentials lwaAuthorizationCredentials) {
|
||||||
this.lwaAuthorizationCredentials = lwaAuthorizationCredentials;
|
this.lwaAuthorizationCredentials = lwaAuthorizationCredentials;
|
||||||
|
@ -310,12 +304,7 @@ public class {{classname}} {
|
||||||
this.disableAccessTokenCache = true;
|
this.disableAccessTokenCache = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder awsAuthenticationCredentialsProvider(AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider) {
|
|
||||||
this.awsAuthenticationCredentialsProvider = awsAuthenticationCredentialsProvider;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder rateLimitConfigurationOnRequests(RateLimitConfiguration rateLimitConfiguration){
|
public Builder rateLimitConfigurationOnRequests(RateLimitConfiguration rateLimitConfiguration){
|
||||||
this.rateLimitConfiguration = rateLimitConfiguration;
|
this.rateLimitConfiguration = rateLimitConfiguration;
|
||||||
return this;
|
return this;
|
||||||
|
@ -326,17 +315,7 @@ public class {{classname}} {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder awsAuthenticationCustomCredentialsProvider(AWSAuthenticationCustomCredentialsProvider awsAuthenticationCustomCredentialsProvider) {
|
|
||||||
this.awsAuthenticationCustomCredentialsProvider = awsAuthenticationCustomCredentialsProvider;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public {{classname}} build() {
|
public {{classname}} build() {
|
||||||
if (awsAuthenticationCredentials == null && awsAuthenticationCustomCredentialsProvider == null) {
|
|
||||||
throw new RuntimeException("Neither AWSAuthenticationCredentials or AWSAuthenticationCustomCredentialsProvider are set");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lwaAuthorizationCredentials == null) {
|
if (lwaAuthorizationCredentials == null) {
|
||||||
throw new RuntimeException("LWAAuthorizationCredentials not set");
|
throw new RuntimeException("LWAAuthorizationCredentials not set");
|
||||||
}
|
}
|
||||||
|
@ -344,17 +323,6 @@ public class {{classname}} {
|
||||||
if (StringUtil.isEmpty(endpoint)) {
|
if (StringUtil.isEmpty(endpoint)) {
|
||||||
throw new RuntimeException("Endpoint not set");
|
throw new RuntimeException("Endpoint not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
AWSSigV4Signer awsSigV4Signer;
|
|
||||||
if (awsAuthenticationCustomCredentialsProvider != null ) {
|
|
||||||
awsSigV4Signer = new AWSSigV4Signer(awsAuthenticationCustomCredentialsProvider);
|
|
||||||
}
|
|
||||||
else if (awsAuthenticationCredentialsProvider == null) {
|
|
||||||
awsSigV4Signer = new AWSSigV4Signer(awsAuthenticationCredentials);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
awsSigV4Signer = new AWSSigV4Signer(awsAuthenticationCredentials,awsAuthenticationCredentialsProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
LWAAuthorizationSigner lwaAuthorizationSigner = null;
|
LWAAuthorizationSigner lwaAuthorizationSigner = null;
|
||||||
if (disableAccessTokenCache) {
|
if (disableAccessTokenCache) {
|
||||||
|
@ -368,7 +336,6 @@ public class {{classname}} {
|
||||||
}
|
}
|
||||||
|
|
||||||
return new {{classname}}(new ApiClient()
|
return new {{classname}}(new ApiClient()
|
||||||
.setAWSSigV4Signer(awsSigV4Signer)
|
|
||||||
.setLWAAuthorizationSigner(lwaAuthorizationSigner)
|
.setLWAAuthorizationSigner(lwaAuthorizationSigner)
|
||||||
.setBasePath(endpoint)
|
.setBasePath(endpoint)
|
||||||
.setRateLimiter(rateLimitConfiguration));
|
.setRateLimiter(rateLimitConfiguration));
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
{{>licenseInfo}}
|
||||||
|
|
||||||
|
package {{package}};
|
||||||
|
|
||||||
|
import {{invokerPackage}}.ApiException;
|
||||||
|
{{#imports}}import {{import}};
|
||||||
|
{{/imports}}
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
|
||||||
|
{{^fullJavaUtil}}
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
{{/fullJavaUtil}}
|
||||||
|
import com.amazon.SellingPartnerAPIAA.LWAException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API tests for {{classname}}
|
||||||
|
*/
|
||||||
|
@Ignore
|
||||||
|
public class {{classname}}Test {
|
||||||
|
|
||||||
|
private final {{classname}} api = new {{classname}}();
|
||||||
|
|
||||||
|
{{#operations}}{{#operation}}
|
||||||
|
/**
|
||||||
|
* {{summary}}
|
||||||
|
*
|
||||||
|
* {{notes}}
|
||||||
|
*
|
||||||
|
* @throws ApiException if the Api call fails
|
||||||
|
* @throws LWAException If calls to fetch LWA access token fails
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void {{operationId}}Test() throws ApiException, LWAException {
|
||||||
|
{{#allParams}}
|
||||||
|
{{{dataType}}} {{paramName}} = null;
|
||||||
|
{{/allParams}}
|
||||||
|
{{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||||
|
|
||||||
|
// TODO: test validations
|
||||||
|
}
|
||||||
|
{{/operation}}{{/operations}}
|
||||||
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
package com.amazon.SellingPartnerAPIAA;
|
|
||||||
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NonNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AWSAuthenticationCredentials
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
public class AWSAuthenticationCredentials {
|
|
||||||
/**
|
|
||||||
* AWS IAM User Access Key Id
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
private String accessKeyId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AWS IAM User Secret Key
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
private String secretKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AWS Region
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
private String region;
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package com.amazon.SellingPartnerAPIAA;
|
|
||||||
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AWSAuthenticationCredentialsProvider
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
public class AWSAuthenticationCredentialsProvider {
|
|
||||||
/**
|
|
||||||
* AWS IAM Role ARN
|
|
||||||
*/
|
|
||||||
private String roleArn;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AWS IAM Role Session Name
|
|
||||||
*/
|
|
||||||
private String roleSessionName;
|
|
||||||
|
|
||||||
private String region;
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package com.amazon.SellingPartnerAPIAA;
|
|
||||||
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import com.amazonaws.auth.AWSCredentialsProvider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AWSAuthenticationCustomCredentialsProvider
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
public class AWSAuthenticationCustomCredentialsProvider {
|
|
||||||
/**
|
|
||||||
* AWS Region
|
|
||||||
*/
|
|
||||||
private String region;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AWS Credentials Provider
|
|
||||||
*/
|
|
||||||
private AWSCredentialsProvider awsCredentialsProvider;
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
package com.amazon.SellingPartnerAPIAA;
|
|
||||||
|
|
||||||
import com.amazonaws.SignableRequest;
|
|
||||||
import com.amazonaws.auth.AWS4Signer;
|
|
||||||
import com.amazonaws.auth.AWSCredentials;
|
|
||||||
import com.amazonaws.auth.AWSCredentialsProvider;
|
|
||||||
import com.amazonaws.auth.BasicAWSCredentials;
|
|
||||||
import com.squareup.okhttp.Request;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
|
|
||||||
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
|
|
||||||
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AWS Signature Version 4 Signer
|
|
||||||
*/
|
|
||||||
public class AWSSigV4Signer {
|
|
||||||
private static final String SERVICE_NAME = "execute-api";
|
|
||||||
|
|
||||||
@Setter(AccessLevel.PACKAGE)
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private AWS4Signer aws4Signer;
|
|
||||||
|
|
||||||
private AWSCredentials awsCredentials;
|
|
||||||
|
|
||||||
@Setter(AccessLevel.PACKAGE)
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private AWSCredentialsProvider awsCredentialsProvider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param awsAuthenticationCredentials AWS Developer Account Credentials
|
|
||||||
*/
|
|
||||||
public AWSSigV4Signer(AWSAuthenticationCredentials awsAuthenticationCredentials) {
|
|
||||||
aws4Signer = new AWS4Signer();
|
|
||||||
aws4Signer.setServiceName(SERVICE_NAME);
|
|
||||||
aws4Signer.setRegionName(awsAuthenticationCredentials.getRegion());
|
|
||||||
awsCredentials = new BasicAWSCredentials(awsAuthenticationCredentials.getAccessKeyId(),
|
|
||||||
awsAuthenticationCredentials.getSecretKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param awsAuthenticationCredentials and awsAuthenticationCredentialsProvider AWS Developer Account Credentials
|
|
||||||
*/
|
|
||||||
public AWSSigV4Signer(AWSAuthenticationCredentials awsAuthenticationCredentials,
|
|
||||||
AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider) {
|
|
||||||
aws4Signer = new AWS4Signer();
|
|
||||||
aws4Signer.setServiceName(SERVICE_NAME);
|
|
||||||
|
|
||||||
final String region;
|
|
||||||
AWSSecurityTokenServiceClientBuilder stsClientBuilder = AWSSecurityTokenServiceClientBuilder.standard();
|
|
||||||
|
|
||||||
if (awsAuthenticationCredentials != null) {
|
|
||||||
region = awsAuthenticationCredentials.getRegion();
|
|
||||||
BasicAWSCredentials awsBasicCredentials = new BasicAWSCredentials(
|
|
||||||
awsAuthenticationCredentials.getAccessKeyId(),
|
|
||||||
awsAuthenticationCredentials.getSecretKey()
|
|
||||||
);
|
|
||||||
stsClientBuilder.withCredentials(new AWSStaticCredentialsProvider(awsBasicCredentials));
|
|
||||||
} else {
|
|
||||||
region = awsAuthenticationCredentialsProvider.getRegion();
|
|
||||||
}
|
|
||||||
|
|
||||||
aws4Signer.setRegionName(region);
|
|
||||||
awsCredentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(
|
|
||||||
awsAuthenticationCredentialsProvider.getRoleArn(),
|
|
||||||
awsAuthenticationCredentialsProvider.getRoleSessionName())
|
|
||||||
.withStsClient(stsClientBuilder.withRegion(region).build())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param awsAuthenticationCustomCredentialsProvider AWS Credentials Provider
|
|
||||||
*/
|
|
||||||
public AWSSigV4Signer(AWSAuthenticationCustomCredentialsProvider awsAuthenticationCustomCredentialsProvider) {
|
|
||||||
aws4Signer = new AWS4Signer();
|
|
||||||
aws4Signer.setServiceName(SERVICE_NAME);
|
|
||||||
aws4Signer.setRegionName(awsAuthenticationCustomCredentialsProvider.getRegion());
|
|
||||||
this.awsCredentialsProvider = awsAuthenticationCustomCredentialsProvider.getAwsCredentialsProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param awsAuthenticationCredentialsProvider AWS Credentials Provider containing the role name to be assumed
|
|
||||||
*/
|
|
||||||
public AWSSigV4Signer(AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider) {
|
|
||||||
this(null, awsAuthenticationCredentialsProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signs a Request with AWS Signature Version 4
|
|
||||||
*
|
|
||||||
* @param originalRequest Request to sign (treated as immutable)
|
|
||||||
* @return Copy of originalRequest with AWS Signature
|
|
||||||
*/
|
|
||||||
public Request sign(Request originalRequest) {
|
|
||||||
SignableRequest<Request> signableRequest = new SignableRequestImpl(originalRequest);
|
|
||||||
if (awsCredentialsProvider != null) {
|
|
||||||
aws4Signer.sign(signableRequest, awsCredentialsProvider.getCredentials());
|
|
||||||
} else {
|
|
||||||
aws4Signer.sign(signableRequest, awsCredentials);
|
|
||||||
}
|
|
||||||
return (Request) signableRequest.getOriginalRequestObject();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -64,8 +64,9 @@ public class LWAAuthorizationSigner {
|
||||||
* Signs a Request with an LWA Access Token
|
* Signs a Request with an LWA Access Token
|
||||||
* @param originalRequest Request to sign (treated as immutable)
|
* @param originalRequest Request to sign (treated as immutable)
|
||||||
* @return Copy of originalRequest with LWA signature
|
* @return Copy of originalRequest with LWA signature
|
||||||
|
* @throws LWAException If calls to fetch LWA access token fails
|
||||||
*/
|
*/
|
||||||
public Request sign(Request originalRequest) {
|
public Request sign(Request originalRequest) throws LWAException {
|
||||||
String accessToken = lwaClient.getAccessToken(lwaAccessTokenRequestMeta);
|
String accessToken = lwaClient.getAccessToken(lwaAccessTokenRequestMeta);
|
||||||
|
|
||||||
return originalRequest.newBuilder()
|
return originalRequest.newBuilder()
|
||||||
|
|
|
@ -11,8 +11,7 @@ import com.squareup.okhttp.Response;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.apache.commons.lang3.EnumUtils;
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
class LWAClient {
|
class LWAClient {
|
||||||
private static final String ACCESS_TOKEN_KEY = "access_token";
|
private static final String ACCESS_TOKEN_KEY = "access_token";
|
||||||
|
@ -25,7 +24,9 @@ class LWAClient {
|
||||||
private OkHttpClient okHttpClient;
|
private OkHttpClient okHttpClient;
|
||||||
private LWAAccessTokenCache lwaAccessTokenCache;
|
private LWAAccessTokenCache lwaAccessTokenCache;
|
||||||
|
|
||||||
/** Sets cache to store access token until token is expired */
|
/**
|
||||||
|
* Sets cache to store access token until token is expired
|
||||||
|
*/
|
||||||
public void setLWAAccessTokenCache(LWAAccessTokenCache tokenCache) {
|
public void setLWAAccessTokenCache(LWAAccessTokenCache tokenCache) {
|
||||||
this.lwaAccessTokenCache = tokenCache;
|
this.lwaAccessTokenCache = tokenCache;
|
||||||
}
|
}
|
||||||
|
@ -33,46 +34,54 @@ class LWAClient {
|
||||||
LWAClient(String endpoint) {
|
LWAClient(String endpoint) {
|
||||||
okHttpClient = new OkHttpClient();
|
okHttpClient = new OkHttpClient();
|
||||||
this.endpoint = endpoint;
|
this.endpoint = endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getAccessToken(LWAAccessTokenRequestMeta lwaAccessTokenRequestMeta) {
|
String getAccessToken(LWAAccessTokenRequestMeta lwaAccessTokenRequestMeta) throws LWAException {
|
||||||
if (lwaAccessTokenCache != null) {
|
if (lwaAccessTokenCache != null) {
|
||||||
return getAccessTokenFromCache(lwaAccessTokenRequestMeta);
|
return getAccessTokenFromCache(lwaAccessTokenRequestMeta);
|
||||||
} else {
|
} else {
|
||||||
return getAccessTokenFromEndpoint(lwaAccessTokenRequestMeta);
|
return getAccessTokenFromEndpoint(lwaAccessTokenRequestMeta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getAccessTokenFromCache(LWAAccessTokenRequestMeta lwaAccessTokenRequestMeta) {
|
String getAccessTokenFromCache(LWAAccessTokenRequestMeta lwaAccessTokenRequestMeta) throws LWAException {
|
||||||
String accessTokenCacheData = (String) lwaAccessTokenCache.get(lwaAccessTokenRequestMeta);
|
String accessTokenCacheData = (String) lwaAccessTokenCache.get(lwaAccessTokenRequestMeta);
|
||||||
if (accessTokenCacheData != null) {
|
if (accessTokenCacheData != null) {
|
||||||
return accessTokenCacheData;
|
return accessTokenCacheData;
|
||||||
} else {
|
} else {
|
||||||
return getAccessTokenFromEndpoint(lwaAccessTokenRequestMeta);
|
return getAccessTokenFromEndpoint(lwaAccessTokenRequestMeta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getAccessTokenFromEndpoint(LWAAccessTokenRequestMeta lwaAccessTokenRequestMeta) {
|
String getAccessTokenFromEndpoint(LWAAccessTokenRequestMeta lwaAccessTokenRequestMeta) throws LWAException {
|
||||||
RequestBody requestBody = RequestBody.create(JSON_MEDIA_TYPE, new Gson().toJson(lwaAccessTokenRequestMeta));
|
RequestBody requestBody = RequestBody.create(JSON_MEDIA_TYPE, new Gson().toJson(lwaAccessTokenRequestMeta));
|
||||||
Request accessTokenRequest = new Request.Builder().url(endpoint).post(requestBody).build();
|
Request accessTokenRequest = new Request.Builder().url(endpoint).post(requestBody).build();
|
||||||
|
LWAExceptionErrorCode lwaErrorCode = null;
|
||||||
String accessToken;
|
String accessToken;
|
||||||
try {
|
try {
|
||||||
Response response = okHttpClient.newCall(accessTokenRequest).execute();
|
Response response = okHttpClient.newCall(accessTokenRequest).execute();
|
||||||
if (!response.isSuccessful()) {
|
|
||||||
throw new IOException("Unsuccessful LWA token exchange");
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonObject responseJson = new JsonParser().parse(response.body().string()).getAsJsonObject();
|
JsonObject responseJson = new JsonParser().parse(response.body().string()).getAsJsonObject();
|
||||||
|
if (!response.isSuccessful()) {
|
||||||
|
// Check if response has element error and is a known LWA error code
|
||||||
|
if (responseJson.has("error") &&
|
||||||
|
EnumUtils.isValidEnum(LWAExceptionErrorCode.class, responseJson.get("error").getAsString())) {
|
||||||
|
throw new LWAException(responseJson.get("error").getAsString(),
|
||||||
|
responseJson.get("error_description").getAsString(), "Error getting LWA Token");
|
||||||
|
} else { // else throw other LWA error
|
||||||
|
throw new LWAException(LWAExceptionErrorCode.other.toString(), "Other LWA Exception",
|
||||||
|
"Error getting LWA Token");
|
||||||
|
}
|
||||||
|
}
|
||||||
accessToken = responseJson.get(ACCESS_TOKEN_KEY).getAsString();
|
accessToken = responseJson.get(ACCESS_TOKEN_KEY).getAsString();
|
||||||
if (lwaAccessTokenCache != null) {
|
if (lwaAccessTokenCache != null) {
|
||||||
long timeToTokenexpiry = responseJson.get(ACCESS_TOKEN_EXPIRES_IN).getAsLong();
|
long timeToTokenexpiry = responseJson.get(ACCESS_TOKEN_EXPIRES_IN).getAsLong();
|
||||||
lwaAccessTokenCache.put(lwaAccessTokenRequestMeta, accessToken, timeToTokenexpiry);
|
lwaAccessTokenCache.put(lwaAccessTokenRequestMeta, accessToken, timeToTokenexpiry);
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error getting LWA Access Token", e);
|
|
||||||
}
|
}
|
||||||
return accessToken;
|
} catch (LWAException e) { // throw LWA exception
|
||||||
|
throw new LWAException(e.getErrorCode(), e.getErrorMessage(), e.getMessage());
|
||||||
|
} catch (Exception e) { // throw other runtime exceptions
|
||||||
|
throw new RuntimeException("Error getting LWA Token");
|
||||||
}
|
}
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.amazon.SellingPartnerAPIAA;
|
||||||
|
|
||||||
|
public class LWAException extends Exception {
|
||||||
|
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
private String errorCode;
|
||||||
|
|
||||||
|
LWAException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
LWAException(String errorCode, String errorMessage) {
|
||||||
|
super();
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
LWAException(String errorCode, String errorMessage, String message) {
|
||||||
|
super(message);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
LWAException(String errorCode, String errorMessage, Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
LWAException(String errorCode, String errorMessage, String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorCode() {
|
||||||
|
return this.errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorMessage() {
|
||||||
|
return this.errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.amazon.SellingPartnerAPIAA;
|
||||||
|
|
||||||
|
public enum LWAExceptionErrorCode {
|
||||||
|
access_denied,
|
||||||
|
invalid_grant,
|
||||||
|
invalid_request,
|
||||||
|
invalid_scope,
|
||||||
|
server_error,
|
||||||
|
temporarily_unavailable,
|
||||||
|
unauthorized_client,
|
||||||
|
invalid_client,
|
||||||
|
other;
|
||||||
|
}
|
|
@ -1,148 +0,0 @@
|
||||||
package com.amazon.SellingPartnerAPIAA;
|
|
||||||
|
|
||||||
import com.amazonaws.ReadLimitInfo;
|
|
||||||
import com.amazonaws.SignableRequest;
|
|
||||||
import com.amazonaws.http.HttpMethodName;
|
|
||||||
import com.squareup.okhttp.HttpUrl;
|
|
||||||
import com.squareup.okhttp.MediaType;
|
|
||||||
import com.squareup.okhttp.Request;
|
|
||||||
import okio.Buffer;
|
|
||||||
import org.apache.http.NameValuePair;
|
|
||||||
import org.apache.http.client.utils.URLEncodedUtils;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
class SignableRequestImpl implements SignableRequest<Request> {
|
|
||||||
private static final String CONTENT_TYPE_HEADER_NAME = "Content-Type";
|
|
||||||
private Request originalRequest;
|
|
||||||
private Request.Builder signableRequestBuilder;
|
|
||||||
|
|
||||||
SignableRequestImpl(Request originalRequest) {
|
|
||||||
this.originalRequest = originalRequest;
|
|
||||||
signableRequestBuilder = originalRequest.newBuilder();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addHeader(String name, String value) {
|
|
||||||
signableRequestBuilder.addHeader(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addParameter(String name, String value) {
|
|
||||||
HttpUrl newUrl = signableRequestBuilder.build()
|
|
||||||
.httpUrl()
|
|
||||||
.newBuilder()
|
|
||||||
.addEncodedQueryParameter(name, value)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
signableRequestBuilder.url(newUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContent(InputStream inputStream) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getHeaders() {
|
|
||||||
Map<String, String> headers = new HashMap<>();
|
|
||||||
|
|
||||||
Request requestSnapshot = signableRequestBuilder.build();
|
|
||||||
requestSnapshot.headers()
|
|
||||||
.names()
|
|
||||||
.forEach(headerName -> headers.put(headerName, requestSnapshot.header(headerName)));
|
|
||||||
|
|
||||||
if (requestSnapshot.body() != null) {
|
|
||||||
MediaType contentType = requestSnapshot.body().contentType();
|
|
||||||
if (contentType != null) {
|
|
||||||
headers.put(CONTENT_TYPE_HEADER_NAME, contentType.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getResourcePath() {
|
|
||||||
return originalRequest.url()
|
|
||||||
.getPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<String>> getParameters() {
|
|
||||||
Map<String, List<String>> parameters = new HashMap<>();
|
|
||||||
try {
|
|
||||||
List<NameValuePair> nameValuePairs = URLEncodedUtils.parse(originalRequest.url().toURI(),
|
|
||||||
StandardCharsets.UTF_8);
|
|
||||||
nameValuePairs.forEach(nameValuePair -> parameters.put(nameValuePair.getName(),
|
|
||||||
Collections.singletonList(nameValuePair.getValue())));
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public URI getEndpoint() {
|
|
||||||
URI uri = null;
|
|
||||||
try {
|
|
||||||
uri = originalRequest.url().toURI();
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return URI.create(String.format("%s://%s", uri.getScheme(), uri.getHost()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpMethodName getHttpMethod() {
|
|
||||||
return HttpMethodName.fromValue(originalRequest.method().toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTimeOffset() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getContent() {
|
|
||||||
ByteArrayInputStream inputStream = null;
|
|
||||||
|
|
||||||
if (originalRequest.body() != null) {
|
|
||||||
try {
|
|
||||||
Buffer buffer = new Buffer();
|
|
||||||
originalRequest.body().writeTo(buffer);
|
|
||||||
inputStream = new ByteArrayInputStream(buffer.readByteArray());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Unable to buffer request body", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return inputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getContentUnwrapped() {
|
|
||||||
return getContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReadLimitInfo getReadLimitInfo() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getOriginalRequestObject() {
|
|
||||||
return signableRequestBuilder.build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,148 +0,0 @@
|
||||||
package com.amazon.SellingPartnerAPIAA;
|
|
||||||
|
|
||||||
import com.amazonaws.SignableRequest;
|
|
||||||
import com.amazonaws.auth.AWS4Signer;
|
|
||||||
import com.amazonaws.auth.AWSCredentials;
|
|
||||||
import com.amazonaws.auth.AWSCredentialsProvider;
|
|
||||||
import com.squareup.okhttp.Request;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.doNothing;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class AWSSigV4SignerTest {
|
|
||||||
private static final String TEST_ACCESS_KEY_ID = "aKey";
|
|
||||||
private static final String TEST_SECRET_KEY = "sKey";
|
|
||||||
private static final String TEST_REGION = "us-east";
|
|
||||||
private static final String TEST_ROLE_ARN = "arnrole";
|
|
||||||
private static final String TEST_ROLESESSION_NAME = "test";
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AWS4Signer mockAWS4Signer;
|
|
||||||
@Mock
|
|
||||||
private AWSCredentialsProvider mockAWSCredentialsProvider;
|
|
||||||
@Mock
|
|
||||||
private AWSCredentials mockAWSCredentials;
|
|
||||||
|
|
||||||
private AWSSigV4Signer underTest;
|
|
||||||
private AWSSigV4Signer underTestCredentialsProvider;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() {
|
|
||||||
underTest = new AWSSigV4Signer(AWSAuthenticationCredentials.builder()
|
|
||||||
.accessKeyId(TEST_ACCESS_KEY_ID)
|
|
||||||
.secretKey(TEST_SECRET_KEY)
|
|
||||||
.region(TEST_REGION)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void signRequestUsingProvidedCredentials() {
|
|
||||||
ArgumentCaptor<AWSCredentials> awsCredentialsArgumentCaptor = ArgumentCaptor.forClass(AWSCredentials.class);
|
|
||||||
underTest.setAws4Signer(mockAWS4Signer);
|
|
||||||
|
|
||||||
doNothing()
|
|
||||||
.when(mockAWS4Signer)
|
|
||||||
.sign(any(SignableRequest.class), awsCredentialsArgumentCaptor.capture());
|
|
||||||
|
|
||||||
underTest.sign(new Request.Builder().url("https://api.amazon.com").build());
|
|
||||||
|
|
||||||
AWSCredentials actualAWSCredentials = awsCredentialsArgumentCaptor.getValue();
|
|
||||||
|
|
||||||
assertEquals(TEST_ACCESS_KEY_ID, actualAWSCredentials.getAWSAccessKeyId());
|
|
||||||
assertEquals(TEST_SECRET_KEY, actualAWSCredentials.getAWSSecretKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setSignerRegion() {
|
|
||||||
assertEquals(TEST_REGION, underTest.getAws4Signer().getRegionName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setSignerServiceName() {
|
|
||||||
assertEquals("execute-api", underTest.getAws4Signer().getServiceName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void returnSignedRequest() {
|
|
||||||
ArgumentCaptor<SignableRequest> signableRequestArgumentCaptor = ArgumentCaptor.forClass(SignableRequest.class);
|
|
||||||
underTest.setAws4Signer(mockAWS4Signer);
|
|
||||||
|
|
||||||
Request actualSignedRequest = underTest.sign(new Request.Builder()
|
|
||||||
.url("http://api.amazon.com")
|
|
||||||
.build());
|
|
||||||
|
|
||||||
verify(mockAWS4Signer)
|
|
||||||
.sign(signableRequestArgumentCaptor.capture(), any(AWSCredentials.class));
|
|
||||||
|
|
||||||
SignableRequest actualSignableRequest = signableRequestArgumentCaptor.getValue();
|
|
||||||
|
|
||||||
assertEquals(((Request)actualSignableRequest.getOriginalRequestObject()).url(), actualSignedRequest.url());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void returnSignedRequestWithCredentialProvider() {
|
|
||||||
ArgumentCaptor<SignableRequest> signableRequestArgumentCaptor = ArgumentCaptor.forClass(SignableRequest.class);
|
|
||||||
|
|
||||||
Mockito.when(mockAWSCredentialsProvider.getCredentials()).thenReturn(mockAWSCredentials);
|
|
||||||
|
|
||||||
underTestCredentialsProvider = new AWSSigV4Signer(AWSAuthenticationCredentials.builder()
|
|
||||||
.accessKeyId(TEST_ACCESS_KEY_ID)
|
|
||||||
.secretKey(TEST_SECRET_KEY)
|
|
||||||
.region(TEST_REGION)
|
|
||||||
.build(), AWSAuthenticationCredentialsProvider.builder()
|
|
||||||
.roleArn(TEST_ROLE_ARN)
|
|
||||||
.roleSessionName(TEST_ROLESESSION_NAME)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
underTestCredentialsProvider.setAws4Signer(mockAWS4Signer);
|
|
||||||
underTestCredentialsProvider.setAwsCredentialsProvider(mockAWSCredentialsProvider);
|
|
||||||
|
|
||||||
Request actualSignedRequest = underTestCredentialsProvider.sign(new Request.Builder()
|
|
||||||
.url("http://api.amazon.com")
|
|
||||||
.build());
|
|
||||||
|
|
||||||
verify(mockAWS4Signer)
|
|
||||||
.sign(signableRequestArgumentCaptor.capture(), any(AWSCredentials.class));
|
|
||||||
|
|
||||||
SignableRequest actualSignableRequest = signableRequestArgumentCaptor.getValue();
|
|
||||||
|
|
||||||
assertEquals(((Request)actualSignableRequest.getOriginalRequestObject()).url(), actualSignedRequest.url());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void returnSignedRequestWithCustomCredentialsProvider() {
|
|
||||||
ArgumentCaptor<SignableRequest> signableRequestArgumentCaptor = ArgumentCaptor.forClass(SignableRequest.class);
|
|
||||||
|
|
||||||
Mockito.when(mockAWSCredentialsProvider.getCredentials()).thenReturn(mockAWSCredentials);
|
|
||||||
|
|
||||||
underTestCredentialsProvider = new AWSSigV4Signer(AWSAuthenticationCustomCredentialsProvider.builder()
|
|
||||||
.awsCredentialsProvider(mockAWSCredentialsProvider)
|
|
||||||
.region(TEST_REGION)
|
|
||||||
.build());
|
|
||||||
underTestCredentialsProvider.setAws4Signer(mockAWS4Signer);
|
|
||||||
|
|
||||||
Request actualSignedRequest = underTestCredentialsProvider.sign(new Request.Builder()
|
|
||||||
.url("http://api.amazon.com")
|
|
||||||
.build());
|
|
||||||
|
|
||||||
verify(mockAWS4Signer)
|
|
||||||
.sign(signableRequestArgumentCaptor.capture(), any(AWSCredentials.class));
|
|
||||||
|
|
||||||
SignableRequest actualSignableRequest = signableRequestArgumentCaptor.getValue();
|
|
||||||
|
|
||||||
assertEquals(((Request)actualSignableRequest.getOriginalRequestObject()).url(), actualSignedRequest.url());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -98,7 +98,7 @@ public class LWAAuthorizationSignerTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("lwaAuthSigner")
|
@MethodSource("lwaAuthSigner")
|
||||||
public void requestLWAAccessTokenFromConfiguration(String sellerType, LWAAuthorizationSigner testAuthSigner) {
|
public void requestLWAAccessTokenFromConfiguration(String sellerType, LWAAuthorizationSigner testAuthSigner) throws LWAException {
|
||||||
LWAClient mockLWAClient = mock(LWAClient.class);
|
LWAClient mockLWAClient = mock(LWAClient.class);
|
||||||
ArgumentCaptor<LWAAccessTokenRequestMeta> lwaAccessTokenRequestMetaArgumentCaptor = ArgumentCaptor.forClass(LWAAccessTokenRequestMeta.class);
|
ArgumentCaptor<LWAAccessTokenRequestMeta> lwaAccessTokenRequestMetaArgumentCaptor = ArgumentCaptor.forClass(LWAAccessTokenRequestMeta.class);
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ public class LWAAuthorizationSignerTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("lwaAuthSigner")
|
@MethodSource("lwaAuthSigner")
|
||||||
public void returnSignedRequestWithAccessTokenFromLWAClient(String sellerType, LWAAuthorizationSigner testAuthSigner) {
|
public void returnSignedRequestWithAccessTokenFromLWAClient(String sellerType, LWAAuthorizationSigner testAuthSigner) throws LWAException {
|
||||||
LWAClient mockLWAClient = mock(LWAClient.class);
|
LWAClient mockLWAClient = mock(LWAClient.class);
|
||||||
|
|
||||||
when(mockLWAClient.getAccessToken(any(LWAAccessTokenRequestMeta.class)))
|
when(mockLWAClient.getAccessToken(any(LWAAccessTokenRequestMeta.class)))
|
||||||
|
@ -140,7 +140,7 @@ public class LWAAuthorizationSignerTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("lwaAuthSigner")
|
@MethodSource("lwaAuthSigner")
|
||||||
public void originalRequestIsImmutable(String sellerType, LWAAuthorizationSigner testAuthSigner) {
|
public void originalRequestIsImmutable(String sellerType, LWAAuthorizationSigner testAuthSigner) throws LWAException {
|
||||||
LWAClient mockLWAClient = mock(LWAClient.class);
|
LWAClient mockLWAClient = mock(LWAClient.class);
|
||||||
|
|
||||||
when(mockLWAClient.getAccessToken(any(LWAAccessTokenRequestMeta.class)))
|
when(mockLWAClient.getAccessToken(any(LWAAccessTokenRequestMeta.class)))
|
||||||
|
@ -151,7 +151,7 @@ public class LWAAuthorizationSignerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void returnSignedRequestWithAccessTokenFromLWACache() throws IOException {
|
public void returnSignedRequestWithAccessTokenFromLWACache() throws IOException, LWAException {
|
||||||
LWAClient testLWAClient = new LWAClient(TEST_ENDPOINT);
|
LWAClient testLWAClient = new LWAClient(TEST_ENDPOINT);
|
||||||
testLWAClient.setOkHttpClient(mockOkHttpClient);
|
testLWAClient.setOkHttpClient(mockOkHttpClient);
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,10 @@ public class LWAClientTest {
|
||||||
|
|
||||||
private static final String SELLER_TYPE_SELLER = "seller";
|
private static final String SELLER_TYPE_SELLER = "seller";
|
||||||
private static final String SELLER_TYPE_SELLERLESS = "sellerless";
|
private static final String SELLER_TYPE_SELLERLESS = "sellerless";
|
||||||
|
|
||||||
|
private static final String LWA_EXCEPTION_MSG ="Error getting LWA Token";
|
||||||
|
private static final String LWA_CLIENT_AUTH_MSG ="Client_authentication_failed";
|
||||||
|
private static final String LWA_ACCESS_DENIED_MSG ="Authorization_server_denied_the_request";
|
||||||
@Mock
|
@Mock
|
||||||
private OkHttpClient mockOkHttpClient;
|
private OkHttpClient mockOkHttpClient;
|
||||||
|
|
||||||
|
@ -101,7 +104,7 @@ public class LWAClientTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("lwaClient")
|
@MethodSource("lwaClient")
|
||||||
public void makeRequestFromMeta (String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws IOException {
|
public void makeRequestFromMeta (String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws LWAException,IOException {
|
||||||
ArgumentCaptor<Request> requestArgumentCaptor = ArgumentCaptor.forClass(Request.class);
|
ArgumentCaptor<Request> requestArgumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||||
when(mockOkHttpClient.newCall(requestArgumentCaptor.capture()))
|
when(mockOkHttpClient.newCall(requestArgumentCaptor.capture()))
|
||||||
.thenReturn(mockCall);
|
.thenReturn(mockCall);
|
||||||
|
@ -134,7 +137,7 @@ public class LWAClientTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("lwaClient")
|
@MethodSource("lwaClient")
|
||||||
public void returnAccessTokenFromResponse(String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws IOException {
|
public void returnAccessTokenFromResponse(String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws IOException, LWAException {
|
||||||
when(mockOkHttpClient.newCall(any(Request.class)))
|
when(mockOkHttpClient.newCall(any(Request.class)))
|
||||||
.thenReturn(mockCall);
|
.thenReturn(mockCall);
|
||||||
when(mockCall.execute())
|
when(mockCall.execute())
|
||||||
|
@ -145,20 +148,54 @@ public class LWAClientTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("lwaClient")
|
@MethodSource("lwaClient")
|
||||||
public void unsuccessfulPostThrowsException(String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws IOException {
|
public void unsuccessfulPostThrowsLwaExceptionUnknownErrorCode(String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws IOException, LWAException {
|
||||||
when(mockOkHttpClient.newCall(any(Request.class)))
|
when(mockOkHttpClient.newCall(any(Request.class)))
|
||||||
.thenReturn(mockCall);
|
.thenReturn(mockCall);
|
||||||
when(mockCall.execute())
|
when(mockCall.execute())
|
||||||
.thenReturn(buildResponse(400, "Azta|foo"));
|
.thenReturn(buildResponse(400, "Azta|foo"));
|
||||||
|
|
||||||
Assertions.assertThrows(RuntimeException.class, () -> {
|
Throwable exception = Assertions.assertThrows(LWAException.class, () -> {
|
||||||
underTest.getAccessToken(testLwaAccessTokenRequestMeta);
|
underTest.getAccessToken(testLwaAccessTokenRequestMeta);
|
||||||
});
|
});
|
||||||
|
assertEquals(LWAExceptionErrorCode.other.toString(),((LWAException)exception).getErrorCode());
|
||||||
|
assertEquals(LWA_EXCEPTION_MSG, exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("lwaClient")
|
@MethodSource("lwaClient")
|
||||||
public void missingAccessTokenInResponseThrowsException(String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws IOException {
|
public void unsuccessfulPostThrowsLwaExceptionKnownErrorCode1(String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws IOException, LWAException {
|
||||||
|
when(mockOkHttpClient.newCall(any(Request.class)))
|
||||||
|
.thenReturn(mockCall);
|
||||||
|
when(mockCall.execute())
|
||||||
|
.thenReturn(buildResponse(401, "Azta|foo","invalid_client","Client_authentication_failed"));
|
||||||
|
|
||||||
|
Throwable exception = Assertions.assertThrows(LWAException.class, () -> {
|
||||||
|
underTest.getAccessToken(testLwaAccessTokenRequestMeta);
|
||||||
|
});
|
||||||
|
assertEquals(LWAExceptionErrorCode.invalid_client.toString(),((LWAException)exception).getErrorCode());
|
||||||
|
assertEquals(LWA_EXCEPTION_MSG, exception.getMessage());
|
||||||
|
assertEquals(LWA_CLIENT_AUTH_MSG,((LWAException)exception).getErrorMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("lwaClient")
|
||||||
|
public void unsuccessfulPostThrowsLwaExceptionKnownErrorCode2(String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws IOException, LWAException {
|
||||||
|
when(mockOkHttpClient.newCall(any(Request.class)))
|
||||||
|
.thenReturn(mockCall);
|
||||||
|
when(mockCall.execute())
|
||||||
|
.thenReturn(buildResponse(401, "Azta|foo","access_denied","Authorization_server_denied_the_request"));
|
||||||
|
|
||||||
|
Throwable exception = Assertions.assertThrows(LWAException.class, () -> {
|
||||||
|
underTest.getAccessToken(testLwaAccessTokenRequestMeta);
|
||||||
|
});
|
||||||
|
assertEquals(LWAExceptionErrorCode.access_denied.toString(),((LWAException)exception).getErrorCode());
|
||||||
|
assertEquals(LWA_EXCEPTION_MSG, exception.getMessage());
|
||||||
|
assertEquals(LWA_ACCESS_DENIED_MSG,((LWAException)exception).getErrorMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("lwaClient")
|
||||||
|
public void missingAccessTokenInResponseThrowsException(String sellerType, LWAAccessTokenRequestMeta testLwaAccessTokenRequestMeta) throws IOException, LWAException {
|
||||||
when(mockOkHttpClient.newCall(any(Request.class)))
|
when(mockOkHttpClient.newCall(any(Request.class)))
|
||||||
.thenReturn(mockCall);
|
.thenReturn(mockCall);
|
||||||
when(mockCall.execute())
|
when(mockCall.execute())
|
||||||
|
@ -171,7 +208,7 @@ public class LWAClientTest {
|
||||||
|
|
||||||
//Test for Access Token getting from cache
|
//Test for Access Token getting from cache
|
||||||
@Test
|
@Test
|
||||||
public void returnAccessTokenFromCache() throws IOException, InterruptedException {
|
public void returnAccessTokenFromCache() throws IOException, InterruptedException, LWAException {
|
||||||
|
|
||||||
when(mockOkHttpClient.newCall(any(Request.class)))
|
when(mockOkHttpClient.newCall(any(Request.class)))
|
||||||
.thenReturn(mockCall);
|
.thenReturn(mockCall);
|
||||||
|
@ -187,7 +224,7 @@ public class LWAClientTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void returnAccessTokenFromCacheWithExpiry() throws IOException, InterruptedException {
|
public void returnAccessTokenFromCacheWithExpiry() throws IOException, InterruptedException, LWAException {
|
||||||
LWAClient client = new LWAClient(TEST_ENDPOINT);
|
LWAClient client = new LWAClient(TEST_ENDPOINT);
|
||||||
client.setOkHttpClient(mockOkHttpClient);
|
client.setOkHttpClient(mockOkHttpClient);
|
||||||
when(mockOkHttpClient.newCall(any(Request.class)))
|
when(mockOkHttpClient.newCall(any(Request.class)))
|
||||||
|
@ -202,9 +239,9 @@ public class LWAClientTest {
|
||||||
assertEquals("Azta|foo1", client.getAccessToken(lwaAccessTokenRequestMetaSeller));
|
assertEquals("Azta|foo1", client.getAccessToken(lwaAccessTokenRequestMetaSeller));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Response buildResponse(int code, String accessToken, String expiryInSeconds) {
|
private static Response buildResponse(int code, String accessToken, String expiryInSeconds,String errorCode, String errorMessage) {
|
||||||
ResponseBody responseBody = ResponseBody.create(EXPECTED_MEDIA_TYPE,
|
ResponseBody responseBody = ResponseBody.create(EXPECTED_MEDIA_TYPE,
|
||||||
String.format("{%s:%s,%s:%s}", "access_token", accessToken, "expires_in", expiryInSeconds));
|
String.format("{%s:%s,%s:%s,%s:%s,%s:%s}", "access_token", accessToken, "expires_in", expiryInSeconds, "error", errorCode, "error_description", errorMessage));
|
||||||
|
|
||||||
return new Response.Builder()
|
return new Response.Builder()
|
||||||
.request(new Request.Builder().url(TEST_ENDPOINT).build())
|
.request(new Request.Builder().url(TEST_ENDPOINT).build())
|
||||||
|
@ -215,7 +252,24 @@ public class LWAClientTest {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Response buildResponse(int code, String accessToken,String errorCode, String errorMessage) {
|
||||||
|
return buildResponse(code, accessToken, "3600",errorCode,errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
private static Response buildResponse(int code, String accessToken) {
|
private static Response buildResponse(int code, String accessToken) {
|
||||||
return buildResponse(code, accessToken, "3600");
|
return buildResponse(code, accessToken, "3600");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Response buildResponse(int code, String accessToken,String expiryInSeconds) {
|
||||||
|
ResponseBody responseBody = ResponseBody.create(EXPECTED_MEDIA_TYPE,
|
||||||
|
String.format("{%s:%s,%s:%s}", "access_token", accessToken, "expires_in", expiryInSeconds));
|
||||||
|
|
||||||
|
return new Response.Builder()
|
||||||
|
.request(new Request.Builder().url(TEST_ENDPOINT).build())
|
||||||
|
.code(code)
|
||||||
|
.body(responseBody)
|
||||||
|
.protocol(Protocol.HTTP_1_1)
|
||||||
|
.message("OK")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,247 +0,0 @@
|
||||||
package com.amazon.SellingPartnerAPIAA;
|
|
||||||
|
|
||||||
import com.amazonaws.http.HttpMethodName;
|
|
||||||
import com.squareup.okhttp.HttpUrl;
|
|
||||||
import com.squareup.okhttp.MediaType;
|
|
||||||
import com.squareup.okhttp.Request;
|
|
||||||
import com.squareup.okhttp.RequestBody;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Scanner;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotSame;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class SignableRequestImplTest {
|
|
||||||
private Request testRequest;
|
|
||||||
private SignableRequestImpl underTest;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() {
|
|
||||||
testRequest = new Request.Builder()
|
|
||||||
.url("http://www.amazon.com/request/library?test=true&sky=blue&right=右")
|
|
||||||
.get()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
underTest = new SignableRequestImpl(testRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getHttpMethod() {
|
|
||||||
assertEquals(HttpMethodName.GET, underTest.getHttpMethod());
|
|
||||||
|
|
||||||
underTest = new SignableRequestImpl(new Request.Builder()
|
|
||||||
.url("https://www.amazon.com")
|
|
||||||
.post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), "{\"foo\": \"bar\"}"))
|
|
||||||
.build());
|
|
||||||
|
|
||||||
assertEquals(HttpMethodName.POST, underTest.getHttpMethod());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getOriginalRequestObject() {
|
|
||||||
Request actualRequest = (Request)underTest.getOriginalRequestObject();
|
|
||||||
|
|
||||||
assertNotSame(testRequest, actualRequest);
|
|
||||||
assertEquals(testRequest.method(), actualRequest.method());
|
|
||||||
assertEquals(testRequest.url(), actualRequest.url());
|
|
||||||
assertEquals(testRequest.headers().toMultimap(), actualRequest.headers().toMultimap());
|
|
||||||
assertEquals(testRequest.body(), actualRequest.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getReadLimitInfo() {
|
|
||||||
assertNull(underTest.getReadLimitInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getResourcePath() {
|
|
||||||
assertEquals("/request/library", underTest.getResourcePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getResourcePathWithPoundChar() {
|
|
||||||
testRequest = new Request.Builder()
|
|
||||||
.url("http://www.amazon.com/request/%23library")
|
|
||||||
.get()
|
|
||||||
.build();
|
|
||||||
underTest = new SignableRequestImpl(testRequest);
|
|
||||||
|
|
||||||
assertEquals("/request/%23library", underTest.getResourcePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void noTimeOffset() {
|
|
||||||
assertEquals(0, underTest.getTimeOffset());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getEndpoint() {
|
|
||||||
assertEquals(URI.create("http://www.amazon.com"), underTest.getEndpoint());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headers() {
|
|
||||||
Map<String, String> expectedHeaders = new HashMap<>();
|
|
||||||
|
|
||||||
assertTrue(underTest.getHeaders().isEmpty());
|
|
||||||
|
|
||||||
underTest.addHeader("foo", "bar");
|
|
||||||
expectedHeaders.put("foo", "bar");
|
|
||||||
assertEquals(expectedHeaders, underTest.getHeaders());
|
|
||||||
|
|
||||||
underTest.addHeader("ban", "bop");
|
|
||||||
expectedHeaders.put("ban", "bop");
|
|
||||||
assertEquals(expectedHeaders, underTest.getHeaders());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getParameters() {
|
|
||||||
Map<String, List<String>> expectedParamters = new HashMap<>();
|
|
||||||
expectedParamters.put("test", Collections.singletonList("true"));
|
|
||||||
expectedParamters.put("sky", Collections.singletonList("blue"));
|
|
||||||
expectedParamters.put("right", Collections.singletonList("右"));
|
|
||||||
|
|
||||||
assertEquals(expectedParamters, underTest.getParameters());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getContent() {
|
|
||||||
String expectedContent = "{\"foo\":\"bar\"}";
|
|
||||||
StringBuilder actualContent = new StringBuilder();
|
|
||||||
|
|
||||||
underTest = new SignableRequestImpl(new Request.Builder()
|
|
||||||
.url("https://www.amazon.com")
|
|
||||||
.post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), expectedContent))
|
|
||||||
.build());
|
|
||||||
|
|
||||||
try(Scanner scanner = new Scanner(underTest.getContent())){
|
|
||||||
while(scanner.hasNext()) {
|
|
||||||
actualContent.append(scanner.next());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assertEquals(expectedContent, actualContent.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getUnwrappedContent() {
|
|
||||||
String expectedContent = "{\"ban\":\"bop\"}";
|
|
||||||
StringBuilder actualContent = new StringBuilder();
|
|
||||||
|
|
||||||
underTest = new SignableRequestImpl(new Request.Builder()
|
|
||||||
.url("https://www.amazon.com")
|
|
||||||
.post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), expectedContent))
|
|
||||||
.build());
|
|
||||||
|
|
||||||
try(Scanner scanner = new Scanner(underTest.getContentUnwrapped())){
|
|
||||||
while(scanner.hasNext()) {
|
|
||||||
actualContent.append(scanner.next());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assertEquals(expectedContent, actualContent.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
|
||||||
public void setContentNotSupported() {
|
|
||||||
underTest.setContent(new ByteArrayInputStream("abc".getBytes()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void addParameter() {
|
|
||||||
underTest.addParameter("left", "左");
|
|
||||||
|
|
||||||
HttpUrl actualHttpUrl = ((Request) underTest.getOriginalRequestObject())
|
|
||||||
.httpUrl();
|
|
||||||
|
|
||||||
assertEquals(Collections.singletonList("true"), actualHttpUrl.queryParameterValues("test"));
|
|
||||||
assertEquals(Collections.singletonList("blue"), actualHttpUrl.queryParameterValues("sky"));
|
|
||||||
assertEquals(Collections.singletonList("右"), actualHttpUrl.queryParameterValues("right"));
|
|
||||||
assertEquals(Collections.singletonList("左"), actualHttpUrl.queryParameterValues("left"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void gracefulBlankParametersParse() {
|
|
||||||
testRequest = new Request.Builder()
|
|
||||||
.url("http://www.amazon.com/request/library? ")
|
|
||||||
.get()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
underTest = new SignableRequestImpl(testRequest);
|
|
||||||
|
|
||||||
assertTrue(underTest.getParameters().isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void gracefulIncompleteParameterPairsParse() {
|
|
||||||
testRequest = new Request.Builder()
|
|
||||||
.url("http://www.amazon.com/request/library?isSigned& =false")
|
|
||||||
.get()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Map<String, List<String>> expected = new HashMap<>();
|
|
||||||
expected.put("isSigned", Collections.singletonList(null));
|
|
||||||
expected.put(" ", Collections.singletonList("false"));
|
|
||||||
|
|
||||||
underTest = new SignableRequestImpl(testRequest);
|
|
||||||
|
|
||||||
assertEquals(expected, underTest.getParameters());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getHeadersIncludesContentTypeFromRequestBody() {
|
|
||||||
String expected = "application/json; charset=utf-8";
|
|
||||||
RequestBody requestBody = RequestBody.create(MediaType.parse(expected),
|
|
||||||
"{\"foo\":\"bar\"}");
|
|
||||||
|
|
||||||
testRequest = new Request.Builder()
|
|
||||||
.url("http://www.amazon.com")
|
|
||||||
.post(requestBody)
|
|
||||||
.header("Content-Type", "THIS SHOULD BE OVERRIDDEN WITH REQUEST BODY CONTENT TYPE")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
underTest = new SignableRequestImpl(testRequest);
|
|
||||||
|
|
||||||
assertEquals(expected, underTest.getHeaders().get("Content-Type"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void missingRequestBodyDoesNotOverwriteExistingContentTypeHeader() {
|
|
||||||
String expected = "testContentType";
|
|
||||||
|
|
||||||
testRequest = new Request.Builder()
|
|
||||||
.url("http://www.amazon.com")
|
|
||||||
.get()
|
|
||||||
.header("Content-Type", expected)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
underTest = new SignableRequestImpl(testRequest);
|
|
||||||
|
|
||||||
assertEquals(expected, underTest.getHeaders().get("Content-Type"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void missingRequestBodyContentTypeDoesNotOverwriteExistingContentTypeHeader() {
|
|
||||||
String expected = "testContentType";
|
|
||||||
|
|
||||||
testRequest = new Request.Builder()
|
|
||||||
.url("http://www.amazon.com")
|
|
||||||
.post(RequestBody.create(null, "foo"))
|
|
||||||
.header("Content-Type", expected)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
underTest = new SignableRequestImpl(testRequest);
|
|
||||||
|
|
||||||
assertEquals(expected, underTest.getHeaders().get("Content-Type"));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue