Clientside RateLimit configuration

This commit is contained in:
Parvathi Mallampalli 2021-09-20 13:38:42 -07:00
parent dd129a54cc
commit e5898b4344
7 changed files with 121 additions and 7 deletions

View File

@ -63,6 +63,21 @@ restRequest = new AWSSigV4Signer(awsAuthenticationCredentials)
```
Note the IRestRequest reference is treated as **mutable** when signed.
## RateLimitConfiguration
Interface to set and get rateLimit configurations that are used with RateLimiter. RateLimiter is used on client side to restrict the rate at which requests are made. RateLimiter Configuration takes Permit, rate which requests are made and TimeOut
*Example*
```
RateLimitConfiguration rateLimitConfig = new RateLimitConfigurationOnRequests
{
RateLimitPermit = ..,
WaitTimeOutInMilliSeconds = ...
};
```
## Resources
This package features Mustache templates designed for use with [swagger codegen](https://swagger.io/tools/swagger-codegen/).
When you build Selling Partner API Swagger models with these templates, they help generate a rich SDK with functionality to invoke Selling Partner APIs built in. The templates are located in *resources/swagger-codegen*.
@ -72,7 +87,7 @@ This package is built as a .NET Standard Library via a Visual Studio Solution wi
## Dependencies
All dependencies can be installed via NuGet
- RestSharp - 105.1.0
- RestSharp - 106.12.0
- Newtonsoft.Json 12.0.3
- NETStandard.Library 2.0.3 (platform-specific implementation requirements are documented on the [Microsoft .NET Guide](https://docs.microsoft.com/en-us/dotnet/standard/net-standard))

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Amazon.SellingPartnerAPIAA
{
public interface RateLimitConfiguration
{
int getRateLimitPermit();
int getTimeOut();
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Amazon.SellingPartnerAPIAA
{
public class RateLimitConfigurationOnRequests : RateLimitConfiguration
{
/**
* RateLimiter Permit
*/
public int RateLimitPermit;
/**
* Timeout for RateLimiter
*/
public int WaitTimeOutInMilliSeconds;
public int getRateLimitPermit()
{
return RateLimitPermit;
}
public int getTimeOut()
{
return WaitTimeOutInMilliSeconds;
}
}
}

View File

@ -22,6 +22,8 @@ using RestSharp.Portable.HttpClient;
using RestSharp;
{{/netStandard}}
using Amazon.SellingPartnerAPIAA;
using RateLimiter;
using System.Threading;
namespace {{packageName}}.Client
{
@ -32,7 +34,9 @@ namespace {{packageName}}.Client
{
private LWAAuthorizationSigner lwaAuthorizationSigner;
private AWSSigV4Signer awsSigV4Signer;
private RateLimitConfiguration rateLimitConfig;
private TimeLimiter rateLimiter;
private JsonSerializerSettings serializerSettings = new JsonSerializerSettings
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
@ -71,6 +75,11 @@ namespace {{packageName}}.Client
lwaAuthorizationSigner = new LWAAuthorizationSigner(Configuration.AuthorizationCredentials);
awsSigV4Signer = new AWSSigV4Signer(Configuration.AuthenticationCredentials);
rateLimitConfig = Configuration.RateLimitConfig;
if(rateLimitConfig != null)
{
rateLimiter = TimeLimiter.GetFromMaxCountByInterval(rateLimitConfig.getRateLimitPermit(), TimeSpan.FromSeconds(1));
}
}
/// <summary>
@ -134,7 +143,7 @@ namespace {{packageName}}.Client
{{/netStandard}}
{{^netStandard}}
{{^supportsUWP}}
request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType);
request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentLength, param.Value.ContentType);
{{/supportsUWP}}
{{#supportsUWP}}
byte[] paramWriter = null;
@ -187,6 +196,22 @@ namespace {{packageName}}.Client
RestClient.UserAgent = Configuration.UserAgent;
InterceptRequest(request);
if(rateLimitConfig != null)
{
var cancellationSource = new CancellationTokenSource(rateLimitConfig.getTimeOut());
try
{
var response = rateLimiter.Enqueue<IRestResponse>(() => RestClient.Execute(request), cancellationSource.Token);
InterceptResponse(request, response.Result);
return response.Result;
}
catch (AggregateException e)
{
throw new ApiException(429, "Throttled at client");
}
}
else
{
{{#netStandard}}
var response = RestClient.Execute(request).Result;
{{/netStandard}}
@ -202,6 +227,7 @@ namespace {{packageName}}.Client
InterceptResponse(request, response);
return (Object) response;
}
}
{{#supportsAsync}}
/// <summary>
@ -227,9 +253,19 @@ namespace {{packageName}}.Client
path, method, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, contentType);
InterceptRequest(request);
var response = await RestClient.Execute{{^netStandard}}TaskAsync{{/netStandard}}(request);
InterceptResponse(request, response);
return (Object)response;
if (rateLimitConfig != null)
{
var cancellationSource = new CancellationTokenSource(rateLimitConfig.getTimeOut());
var response = await rateLimiter.Enqueue<IRestResponse>(() => RestClient.ExecuteTaskAsync(request), cancellationSource.Token);
InterceptResponse(request, response);
return response;
}
else
{
var response = await RestClient.Execute{{^netStandard}}TaskAsync{{/netStandard}}(request);
InterceptResponse(request, response);
return (Object)response;
}
}{{/supportsAsync}}
/// <summary>
@ -574,3 +610,4 @@ namespace {{packageName}}.Client
}
}
}

View File

@ -274,6 +274,12 @@ namespace {{packageName}}.Client
/// </summary>
/// <value>The AWSAuthenticationCredentials</value>
public virtual AWSAuthenticationCredentials AuthenticationCredentials { get; set; }
/// <summary>
/// Gets or sets the RateLimitConfiguration for Amazon Selling Partner API Authentication
/// </summary>
/// <value>The RateLimitConfiguration</value>
public virtual RateLimitConfiguration RateLimitConfig { get; set; }
/// <summary>
/// Gets the API key with prefix.

View File

@ -94,5 +94,11 @@ namespace {{packageName}}.Client
/// </summary>
/// <value>AuthenticationCredentials</value>
AWSAuthenticationCredentials AuthenticationCredentials { get; }
/// <summary>
/// Gets the RateLimitConfigurationOnRequests for Amazon Selling Partner API RateLimit
/// </summary>
/// <value>RateLimitConfiguration</value>
RateLimitConfiguration RateLimitConfig { get; }
}
}

View File

@ -436,6 +436,7 @@ namespace {{packageName}}.{{apiPackage}}
{
private LWAAuthorizationCredentials lwaAuthorizationCredentials;
private AWSAuthenticationCredentials awsAuthenticationCredentials;
private RateLimitConfiguration rateLimitConfiguration;
public Builder SetLWAAuthorizationCredentials(LWAAuthorizationCredentials lwaAuthorizationCredentials)
{
@ -448,6 +449,13 @@ namespace {{packageName}}.{{apiPackage}}
this.awsAuthenticationCredentials = awsAuthenticationCredentials;
return this;
}
public Builder SetRateLimitConfiguration(RateLimitConfiguration rateLimitConfiguration)
{
this.rateLimitConfiguration = rateLimitConfiguration;
return this;
}
public {{classname}} Build()
{
@ -464,7 +472,8 @@ namespace {{packageName}}.{{apiPackage}}
{{packageName}}.Client.Configuration configuration = new {{packageName}}.Client.Configuration()
{
AuthorizationCredentials = lwaAuthorizationCredentials,
AuthenticationCredentials = awsAuthenticationCredentials
AuthenticationCredentials = awsAuthenticationCredentials,
RateLimitConfig = rateLimitConfiguration
};
// default HTTP connection timeout (in milliseconds)