[csharp][generichost] Do not assume api keys are interchangeable (#17185)

* allow multiple auth methods of same type

* allow multiple auth methods of same type

* allow multiple headers to have api keys

* removed commneted code

* fixed all but standard

* fixed standard
This commit is contained in:
devhl-labs
2023-11-27 21:54:34 -05:00
committed by GitHub
parent 8669646d99
commit fb429f7e94
43 changed files with 456 additions and 373 deletions

View File

@@ -15,14 +15,21 @@ namespace {{packageName}}.{{clientPackage}}
{
private string _raw;
/// <summary>
/// The header that this token will be used with.
/// </summary>
public string Header { get; }
/// <summary>
/// Constructs an ApiKeyToken object.
/// </summary>
/// <param name="value"></param>
/// <param name="header"></param>
/// <param name="prefix"></param>
/// <param name="timeout"></param>
public ApiKeyToken(string value, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
public ApiKeyToken(string value, string header, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
{
Header = header;
_raw = $"{ prefix }{ value }";
}
@@ -30,22 +37,20 @@ namespace {{packageName}}.{{clientPackage}}
/// Places the token in the header.
/// </summary>
/// <param name="request"></param>
/// <param name="headerName"></param>
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request, string headerName)
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request)
{
request.Headers.Add(headerName, _raw);
request.Headers.Add(Header, _raw);
}
/// <summary>
/// Places the token in the query.
/// </summary>
/// <param name="request"></param>
/// <param name="uriBuilder"></param>
/// <param name="parseQueryString"></param>
/// <param name="parameterName"></param>
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString, string parameterName)
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString)
{
parseQueryString[parameterName] = Uri.EscapeDataString(_raw).ToString(){{nrt!}};
parseQueryString[Header] = Uri.EscapeDataString(_raw).ToString(){{nrt!}};
}
}
}

View File

@@ -4,14 +4,17 @@
#nullable enable
{{/nrt}}
using System;{{^netStandard}}
using System.Threading.Channels;{{/netStandard}}{{#netStandard}}
using System.Collections.Concurrent;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;{{/netStandard}}
{{^netStandard}}
using System.Threading.Channels;
{{/netStandard}}
{{#netStandard}}
using System.Threading.Channels;
{{/netStandard}}
namespace {{packageName}}.{{clientPackage}} {{^netStandard}}
namespace {{packageName}}.{{clientPackage}}
{
/// <summary>
/// Provides a token to the api clients. Tokens will be rate limited based on the provided TimeSpan.
@@ -19,7 +22,7 @@ namespace {{packageName}}.{{clientPackage}} {{^netStandard}}
/// <typeparam name="TTokenBase"></typeparam>
{{>visibility}} class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal Channel<TTokenBase> AvailableTokens { get; }
internal Dictionary<string, Channel<TTokenBase>> AvailableTokens { get; } = new{{^net70OrLater}} Dictionary<string, Channel<TTokenBase>>{{/net70OrLater}}();
/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
@@ -30,78 +33,49 @@ namespace {{packageName}}.{{clientPackage}} {{^netStandard}}
foreach(TTokenBase token in _tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
{{#lambda.copy}}
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens = Channel.CreateBounded<TTokenBase>(options);
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => AvailableTokens.Writer.TryWrite((TTokenBase) sender));
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default{{^netstandard20OrLater}}(System.Threading.CancellationToken){{/netstandard20OrLater}})
=> await AvailableTokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
} {{/netStandard}}{{#netStandard}}
{
/// <summary>
/// Provides a token to the api clients. Tokens will be rate limited based on the provided TimeSpan.
/// </summary>
/// <typeparam name="TTokenBase"></typeparam>
public class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal ConcurrentDictionary<TTokenBase, TTokenBase> AvailableTokens = new ConcurrentDictionary<TTokenBase, TTokenBase>();
private SemaphoreSlim _semaphore;
/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
/// </summary>
/// <param name="container"></param>
public RateLimitProvider(TokenContainer<TTokenBase> container) : base(container.Tokens)
{
_semaphore = new SemaphoreSlim(1, 1);
foreach(TTokenBase token in _tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));
for (int i = 0; i < _tokens.Length; i++)
AvailableTokens.Add(string.Empty, Channel.CreateBounded<TTokenBase>(options));
{{/lambda.copy}}
{{#hasApiKeyMethods}}
if (container is TokenContainer<ApiKeyToken> apiKeyTokenContainer)
{
_tokens[i].TokenBecameAvailable += ((sender) =>
string[] headers = apiKeyTokenContainer.Tokens.Select(t => t.Header).Distinct().ToArray();
foreach (string header in headers)
{
TTokenBase token = (TTokenBase)sender;
BoundedChannelOptions options = new BoundedChannelOptions(apiKeyTokenContainer.Tokens.Count(t => t.Header.Equals(header)))
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens.TryAdd(token, token);
});
}
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default{{^netstandard20OrLater}}(System.Threading.CancellationToken){{/netstandard20OrLater}})
{
await _semaphore.WaitAsync().ConfigureAwait(false);
try
{
TTokenBase result = null;
while (result == null)
{
TTokenBase tokenToRemove = AvailableTokens.FirstOrDefault().Value;
if (tokenToRemove != null && AvailableTokens.TryRemove(tokenToRemove, out result))
return result;
await Task.Delay(40).ConfigureAwait(false);
tokenToRemove = AvailableTokens.FirstOrDefault().Value;
AvailableTokens.Add(header, Channel.CreateBounded<TTokenBase>(options));
}
return result;
}
finally
else
{
_semaphore.Release();
{{#lambda.indent1}}{{#lambda.pasteLine}}{{/lambda.pasteLine}}{{/lambda.indent1}}
}
{{/hasApiKeyMethods}}
{{^hasApiKeyMethods}}
{{#lambda.pasteLine}}{{/lambda.pasteLine}}
{{/hasApiKeyMethods}}
foreach(Channel<TTokenBase> tokens in AvailableTokens.Values)
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => tokens.Writer.TryWrite((TTokenBase) sender));
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default{{^netstandard20OrLater}}(System.Threading.CancellationToken){{/netstandard20OrLater}})
{
if (!AvailableTokens.TryGetValue(header, out Channel<TTokenBase>{{nrt?}} tokens))
throw new KeyNotFoundException($"Could not locate a token for header '{header}'.");
return await tokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
}
}{{/netStandard}}
}

View File

@@ -21,7 +21,7 @@ namespace {{packageName}}
/// </summary>
protected TTokenBase[] _tokens;
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default{{^netstandard20OrLater}}(System.Threading.CancellationToken){{/netstandard20OrLater}});
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default{{^netstandard20OrLater}}(System.Threading.CancellationToken){{/netstandard20OrLater}});
/// <summary>
/// Instantiates a TokenProvider.

View File

@@ -497,28 +497,26 @@ namespace {{packageName}}.{{apiPackage}}
{{/-first}}
{{#isApiKey}}
{{^isKeyInCookie}}
ApiKeyToken apiKeyTokenLocalVar{{-index}} = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar{{-index}} = (ApiKeyToken) await ApiKeyProvider.GetAsync("{{keyParamName}}", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar{{-index}});
{{#isKeyInHeader}}
apiKeyTokenLocalVar{{-index}}.UseInHeader(httpRequestMessageLocalVar, "{{keyParamName}}");
apiKeyTokenLocalVar{{-index}}.UseInHeader(httpRequestMessageLocalVar);
{{/isKeyInHeader}}
{{/isKeyInCookie}}
{{#isKeyInQuery}}
apiKeyTokenLocalVar{{-index}}.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar, "{{keyParamName}}");
apiKeyTokenLocalVar{{-index}}.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar);
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
{{/isKeyInQuery}}
{{/isApiKey}}
{{/authMethods}}
{{! below line must be after any UseInQuery calls, but before using the HttpSignatureToken}}
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
{{#authMethods}}
{{#isBasicBasic}}
BasicToken basicTokenLocalVar{{-index}} = (BasicToken) await BasicTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BasicToken basicTokenLocalVar{{-index}} = (BasicToken) await BasicTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(basicTokenLocalVar{{-index}});
@@ -526,7 +524,7 @@ namespace {{packageName}}.{{apiPackage}}
{{/isBasicBasic}}
{{#isBasicBearer}}
BearerToken bearerTokenLocalVar{{-index}} = (BearerToken) await BearerTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BearerToken bearerTokenLocalVar{{-index}} = (BearerToken) await BearerTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(bearerTokenLocalVar{{-index}});
@@ -534,7 +532,7 @@ namespace {{packageName}}.{{apiPackage}}
{{/isBasicBearer}}
{{#isOAuth}}
OAuthToken oauthTokenLocalVar{{-index}} = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar{{-index}} = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar{{-index}});
@@ -542,7 +540,7 @@ namespace {{packageName}}.{{apiPackage}}
{{/isOAuth}}
{{#isHttpSignature}}
HttpSignatureToken httpSignatureTokenLocalVar{{-index}} = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar{{-index}} = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar{{-index}});

View File

@@ -43,6 +43,9 @@
{{#net80OrLater}}
<PackageReference Include="Microsoft.Net.Http.Headers" Version="8.0.0" />
{{/net80OrLater}}
{{#netStandard}}
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
{{/netStandard}}
{{/useGenericHost}}
{{^useGenericHost}}
{{#supportsRetry}}

View File

@@ -22,7 +22,7 @@ public class UnitTest1
IHostBuilder hostBuild = Host.CreateDefaultBuilder(Array.Empty<string>()).ConfigureApi((context, services, options) =>
{
string apiKeyTokenValue = context.Configuration["<token>"] ?? "Token not found.";
ApiKeyToken apiKeyToken = new(apiKeyTokenValue, timeout: TimeSpan.FromSeconds(1));
ApiKeyToken apiKeyToken = new(apiKeyTokenValue, "session", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(apiKeyToken);
string bearerTokenValue = context.Configuration["<token>"] ?? "Token not found.";

View File

@@ -18,7 +18,7 @@ namespace OpenAPIClient_generichost_manual_tests
IHostBuilder hostBuild = Host.CreateDefaultBuilder(Array.Empty<string>()).ConfigureApi((context, services, options) =>
{
string apiKeyTokenValue = context.Configuration["<token>"] ?? "Token not found.";
ApiKeyToken apiKeyToken = new(apiKeyTokenValue, timeout: TimeSpan.FromSeconds(1));
ApiKeyToken apiKeyToken = new(apiKeyTokenValue, "session", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(apiKeyToken);
string bearerTokenValue = context.Configuration["<token>"] ?? "Token not found.";

View File

@@ -3245,10 +3245,9 @@ namespace UseSourceGeneration.Api
formParameterLocalVars.Add(new KeyValuePair<string?, string?>("dateTime", ClientUtils.ParameterToString(dateTime.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
BasicToken basicTokenLocalVar1 = (BasicToken) await BasicTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BasicToken basicTokenLocalVar1 = (BasicToken) await BasicTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(basicTokenLocalVar1);
@@ -3770,10 +3769,9 @@ namespace UseSourceGeneration.Api
httpRequestMessageLocalVar.Headers.Add("boolean_group", ClientUtils.ParameterToString(booleanGroup.Value));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
BearerToken bearerTokenLocalVar1 = (BearerToken) await BearerTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BearerToken bearerTokenLocalVar1 = (BearerToken) await BearerTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(bearerTokenLocalVar1);

View File

@@ -280,13 +280,12 @@ namespace UseSourceGeneration.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(modelClient, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key_query", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar, "api_key_query");
apiKeyTokenLocalVar1.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar);
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
string[] contentTypes = new string[] {

View File

@@ -768,16 +768,15 @@ namespace UseSourceGeneration.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(pet, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -986,10 +985,9 @@ namespace UseSourceGeneration.Api
httpRequestMessageLocalVar.Headers.Add("api_key", ClientUtils.ParameterToString(apiKey.Value));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -1180,16 +1178,15 @@ namespace UseSourceGeneration.Api
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -1432,16 +1429,15 @@ namespace UseSourceGeneration.Api
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -1668,17 +1664,16 @@ namespace UseSourceGeneration.Api
System.Collections.Specialized.NameValueCollection parseQueryStringLocalVar = System.Web.HttpUtility.ParseQueryString(string.Empty);
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "api_key");
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar);
ApiKeyToken apiKeyTokenLocalVar2 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar2 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key_query", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar2);
apiKeyTokenLocalVar2.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar, "api_key_query");
apiKeyTokenLocalVar2.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar);
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
string[] acceptLocalVars = new string[] {
@@ -1918,16 +1913,15 @@ namespace UseSourceGeneration.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(pet, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -2167,10 +2161,9 @@ namespace UseSourceGeneration.Api
formParameterLocalVars.Add(new KeyValuePair<string?, string?>("status", ClientUtils.ParameterToString(status.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -2393,10 +2386,9 @@ namespace UseSourceGeneration.Api
formParameterLocalVars.Add(new KeyValuePair<string?, string?>("additionalMetadata", ClientUtils.ParameterToString(additionalMetadata.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -2659,10 +2651,9 @@ namespace UseSourceGeneration.Api
formParameterLocalVars.Add(new KeyValuePair<string?, string?>("additionalMetadata", ClientUtils.ParameterToString(additionalMetadata.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);

View File

@@ -621,9 +621,9 @@ namespace UseSourceGeneration.Api
uriBuilderLocalVar.Path = ClientUtils.CONTEXT_PATH + "/store/inventory";
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "api_key");
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar);
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;

View File

@@ -13,14 +13,21 @@ namespace UseSourceGeneration.Client
{
private string _raw;
/// <summary>
/// The header that this token will be used with.
/// </summary>
public string Header { get; }
/// <summary>
/// Constructs an ApiKeyToken object.
/// </summary>
/// <param name="value"></param>
/// <param name="header"></param>
/// <param name="prefix"></param>
/// <param name="timeout"></param>
public ApiKeyToken(string value, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
public ApiKeyToken(string value, string header, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
{
Header = header;
_raw = $"{ prefix }{ value }";
}
@@ -28,22 +35,20 @@ namespace UseSourceGeneration.Client
/// Places the token in the header.
/// </summary>
/// <param name="request"></param>
/// <param name="headerName"></param>
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request, string headerName)
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request)
{
request.Headers.Add(headerName, _raw);
request.Headers.Add(Header, _raw);
}
/// <summary>
/// Places the token in the query.
/// </summary>
/// <param name="request"></param>
/// <param name="uriBuilder"></param>
/// <param name="parseQueryString"></param>
/// <param name="parameterName"></param>
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString, string parameterName)
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString)
{
parseQueryString[parameterName] = Uri.EscapeDataString(_raw).ToString()!;
parseQueryString[Header] = Uri.EscapeDataString(_raw).ToString()!;
}
}
}

View File

@@ -11,9 +11,11 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Channels;
namespace UseSourceGeneration.Client
namespace UseSourceGeneration.Client
{
/// <summary>
/// Provides a token to the api clients. Tokens will be rate limited based on the provided TimeSpan.
@@ -21,7 +23,7 @@ namespace UseSourceGeneration.Client
/// <typeparam name="TTokenBase"></typeparam>
public class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal Channel<TTokenBase> AvailableTokens { get; }
internal Dictionary<string, Channel<TTokenBase>> AvailableTokens { get; } = new();
/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
@@ -32,17 +34,41 @@ namespace UseSourceGeneration.Client
foreach(TTokenBase token in _tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
if (container is TokenContainer<ApiKeyToken> apiKeyTokenContainer)
{
string[] headers = apiKeyTokenContainer.Tokens.Select(t => t.Header).Distinct().ToArray();
AvailableTokens = Channel.CreateBounded<TTokenBase>(options);
foreach (string header in headers)
{
BoundedChannelOptions options = new BoundedChannelOptions(apiKeyTokenContainer.Tokens.Count(t => t.Header.Equals(header)))
{
FullMode = BoundedChannelFullMode.DropWrite
};
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => AvailableTokens.Writer.TryWrite((TTokenBase) sender));
AvailableTokens.Add(header, Channel.CreateBounded<TTokenBase>(options));
}
}
else
{
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens.Add(string.Empty, Channel.CreateBounded<TTokenBase>(options));
}
foreach(Channel<TTokenBase> tokens in AvailableTokens.Values)
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => tokens.Writer.TryWrite((TTokenBase) sender));
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default)
{
if (!AvailableTokens.TryGetValue(header, out Channel<TTokenBase>? tokens))
throw new KeyNotFoundException($"Could not locate a token for header '{header}'.");
return await tokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default)
=> await AvailableTokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
}
}

View File

@@ -27,7 +27,7 @@ namespace UseSourceGeneration
/// </summary>
protected TTokenBase[] _tokens;
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default);
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default);
/// <summary>
/// Instantiates a TokenProvider.

View File

@@ -3245,10 +3245,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string?, string?>("dateTime", ClientUtils.ParameterToString(dateTime.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
BasicToken basicTokenLocalVar1 = (BasicToken) await BasicTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BasicToken basicTokenLocalVar1 = (BasicToken) await BasicTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(basicTokenLocalVar1);
@@ -3770,10 +3769,9 @@ namespace Org.OpenAPITools.Api
httpRequestMessageLocalVar.Headers.Add("boolean_group", ClientUtils.ParameterToString(booleanGroup.Value));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
BearerToken bearerTokenLocalVar1 = (BearerToken) await BearerTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BearerToken bearerTokenLocalVar1 = (BearerToken) await BearerTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(bearerTokenLocalVar1);

View File

@@ -280,13 +280,12 @@ namespace Org.OpenAPITools.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(modelClient, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key_query", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar, "api_key_query");
apiKeyTokenLocalVar1.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar);
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
string[] contentTypes = new string[] {

View File

@@ -768,16 +768,15 @@ namespace Org.OpenAPITools.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(pet, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -986,10 +985,9 @@ namespace Org.OpenAPITools.Api
httpRequestMessageLocalVar.Headers.Add("api_key", ClientUtils.ParameterToString(apiKey.Value));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -1180,16 +1178,15 @@ namespace Org.OpenAPITools.Api
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -1432,16 +1429,15 @@ namespace Org.OpenAPITools.Api
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -1668,17 +1664,16 @@ namespace Org.OpenAPITools.Api
System.Collections.Specialized.NameValueCollection parseQueryStringLocalVar = System.Web.HttpUtility.ParseQueryString(string.Empty);
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "api_key");
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar);
ApiKeyToken apiKeyTokenLocalVar2 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar2 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key_query", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar2);
apiKeyTokenLocalVar2.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar, "api_key_query");
apiKeyTokenLocalVar2.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar);
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
string[] acceptLocalVars = new string[] {
@@ -1918,16 +1913,15 @@ namespace Org.OpenAPITools.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(pet, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -2167,10 +2161,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string?, string?>("status", ClientUtils.ParameterToString(status.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -2393,10 +2386,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string?, string?>("additionalMetadata", ClientUtils.ParameterToString(additionalMetadata.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -2659,10 +2651,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string?, string?>("additionalMetadata", ClientUtils.ParameterToString(additionalMetadata.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);

View File

@@ -621,9 +621,9 @@ namespace Org.OpenAPITools.Api
uriBuilderLocalVar.Path = ClientUtils.CONTEXT_PATH + "/store/inventory";
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "api_key");
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar);
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;

View File

@@ -13,14 +13,21 @@ namespace Org.OpenAPITools.Client
{
private string _raw;
/// <summary>
/// The header that this token will be used with.
/// </summary>
public string Header { get; }
/// <summary>
/// Constructs an ApiKeyToken object.
/// </summary>
/// <param name="value"></param>
/// <param name="header"></param>
/// <param name="prefix"></param>
/// <param name="timeout"></param>
public ApiKeyToken(string value, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
public ApiKeyToken(string value, string header, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
{
Header = header;
_raw = $"{ prefix }{ value }";
}
@@ -28,22 +35,20 @@ namespace Org.OpenAPITools.Client
/// Places the token in the header.
/// </summary>
/// <param name="request"></param>
/// <param name="headerName"></param>
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request, string headerName)
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request)
{
request.Headers.Add(headerName, _raw);
request.Headers.Add(Header, _raw);
}
/// <summary>
/// Places the token in the query.
/// </summary>
/// <param name="request"></param>
/// <param name="uriBuilder"></param>
/// <param name="parseQueryString"></param>
/// <param name="parameterName"></param>
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString, string parameterName)
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString)
{
parseQueryString[parameterName] = Uri.EscapeDataString(_raw).ToString()!;
parseQueryString[Header] = Uri.EscapeDataString(_raw).ToString()!;
}
}
}

View File

@@ -11,9 +11,11 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Channels;
namespace Org.OpenAPITools.Client
namespace Org.OpenAPITools.Client
{
/// <summary>
/// Provides a token to the api clients. Tokens will be rate limited based on the provided TimeSpan.
@@ -21,7 +23,7 @@ namespace Org.OpenAPITools.Client
/// <typeparam name="TTokenBase"></typeparam>
public class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal Channel<TTokenBase> AvailableTokens { get; }
internal Dictionary<string, Channel<TTokenBase>> AvailableTokens { get; } = new();
/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
@@ -32,17 +34,41 @@ namespace Org.OpenAPITools.Client
foreach(TTokenBase token in _tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
if (container is TokenContainer<ApiKeyToken> apiKeyTokenContainer)
{
string[] headers = apiKeyTokenContainer.Tokens.Select(t => t.Header).Distinct().ToArray();
AvailableTokens = Channel.CreateBounded<TTokenBase>(options);
foreach (string header in headers)
{
BoundedChannelOptions options = new BoundedChannelOptions(apiKeyTokenContainer.Tokens.Count(t => t.Header.Equals(header)))
{
FullMode = BoundedChannelFullMode.DropWrite
};
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => AvailableTokens.Writer.TryWrite((TTokenBase) sender));
AvailableTokens.Add(header, Channel.CreateBounded<TTokenBase>(options));
}
}
else
{
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens.Add(string.Empty, Channel.CreateBounded<TTokenBase>(options));
}
foreach(Channel<TTokenBase> tokens in AvailableTokens.Values)
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => tokens.Writer.TryWrite((TTokenBase) sender));
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default)
{
if (!AvailableTokens.TryGetValue(header, out Channel<TTokenBase>? tokens))
throw new KeyNotFoundException($"Could not locate a token for header '{header}'.");
return await tokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default)
=> await AvailableTokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
}
}

View File

@@ -27,7 +27,7 @@ namespace Org.OpenAPITools
/// </summary>
protected TTokenBase[] _tokens;
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default);
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default);
/// <summary>
/// Instantiates a TokenProvider.

View File

@@ -3243,10 +3243,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string, string>("dateTime", ClientUtils.ParameterToString(dateTime.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
BasicToken basicTokenLocalVar1 = (BasicToken) await BasicTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BasicToken basicTokenLocalVar1 = (BasicToken) await BasicTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(basicTokenLocalVar1);
@@ -3768,10 +3767,9 @@ namespace Org.OpenAPITools.Api
httpRequestMessageLocalVar.Headers.Add("boolean_group", ClientUtils.ParameterToString(booleanGroup.Value));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
BearerToken bearerTokenLocalVar1 = (BearerToken) await BearerTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BearerToken bearerTokenLocalVar1 = (BearerToken) await BearerTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(bearerTokenLocalVar1);

View File

@@ -278,13 +278,12 @@ namespace Org.OpenAPITools.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(modelClient, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key_query", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar, "api_key_query");
apiKeyTokenLocalVar1.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar);
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
string[] contentTypes = new string[] {

View File

@@ -766,16 +766,15 @@ namespace Org.OpenAPITools.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(pet, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -984,10 +983,9 @@ namespace Org.OpenAPITools.Api
httpRequestMessageLocalVar.Headers.Add("api_key", ClientUtils.ParameterToString(apiKey.Value));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -1178,16 +1176,15 @@ namespace Org.OpenAPITools.Api
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -1430,16 +1427,15 @@ namespace Org.OpenAPITools.Api
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -1666,17 +1662,16 @@ namespace Org.OpenAPITools.Api
System.Collections.Specialized.NameValueCollection parseQueryStringLocalVar = System.Web.HttpUtility.ParseQueryString(string.Empty);
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "api_key");
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar);
ApiKeyToken apiKeyTokenLocalVar2 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar2 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key_query", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar2);
apiKeyTokenLocalVar2.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar, "api_key_query");
apiKeyTokenLocalVar2.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar);
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
string[] acceptLocalVars = new string[] {
@@ -1916,16 +1911,15 @@ namespace Org.OpenAPITools.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(pet, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -2165,10 +2159,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string, string>("status", ClientUtils.ParameterToString(status.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -2391,10 +2384,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string, string>("additionalMetadata", ClientUtils.ParameterToString(additionalMetadata.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -2657,10 +2649,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string, string>("additionalMetadata", ClientUtils.ParameterToString(additionalMetadata.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);

View File

@@ -619,9 +619,9 @@ namespace Org.OpenAPITools.Api
uriBuilderLocalVar.Path = ClientUtils.CONTEXT_PATH + "/store/inventory";
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "api_key");
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar);
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;

View File

@@ -11,14 +11,21 @@ namespace Org.OpenAPITools.Client
{
private string _raw;
/// <summary>
/// The header that this token will be used with.
/// </summary>
public string Header { get; }
/// <summary>
/// Constructs an ApiKeyToken object.
/// </summary>
/// <param name="value"></param>
/// <param name="header"></param>
/// <param name="prefix"></param>
/// <param name="timeout"></param>
public ApiKeyToken(string value, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
public ApiKeyToken(string value, string header, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
{
Header = header;
_raw = $"{ prefix }{ value }";
}
@@ -26,22 +33,20 @@ namespace Org.OpenAPITools.Client
/// Places the token in the header.
/// </summary>
/// <param name="request"></param>
/// <param name="headerName"></param>
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request, string headerName)
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request)
{
request.Headers.Add(headerName, _raw);
request.Headers.Add(Header, _raw);
}
/// <summary>
/// Places the token in the query.
/// </summary>
/// <param name="request"></param>
/// <param name="uriBuilder"></param>
/// <param name="parseQueryString"></param>
/// <param name="parameterName"></param>
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString, string parameterName)
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString)
{
parseQueryString[parameterName] = Uri.EscapeDataString(_raw).ToString();
parseQueryString[Header] = Uri.EscapeDataString(_raw).ToString();
}
}
}

View File

@@ -9,9 +9,11 @@
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Channels;
namespace Org.OpenAPITools.Client
namespace Org.OpenAPITools.Client
{
/// <summary>
/// Provides a token to the api clients. Tokens will be rate limited based on the provided TimeSpan.
@@ -19,7 +21,7 @@ namespace Org.OpenAPITools.Client
/// <typeparam name="TTokenBase"></typeparam>
public class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal Channel<TTokenBase> AvailableTokens { get; }
internal Dictionary<string, Channel<TTokenBase>> AvailableTokens { get; } = new();
/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
@@ -30,17 +32,41 @@ namespace Org.OpenAPITools.Client
foreach(TTokenBase token in _tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
if (container is TokenContainer<ApiKeyToken> apiKeyTokenContainer)
{
string[] headers = apiKeyTokenContainer.Tokens.Select(t => t.Header).Distinct().ToArray();
AvailableTokens = Channel.CreateBounded<TTokenBase>(options);
foreach (string header in headers)
{
BoundedChannelOptions options = new BoundedChannelOptions(apiKeyTokenContainer.Tokens.Count(t => t.Header.Equals(header)))
{
FullMode = BoundedChannelFullMode.DropWrite
};
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => AvailableTokens.Writer.TryWrite((TTokenBase) sender));
AvailableTokens.Add(header, Channel.CreateBounded<TTokenBase>(options));
}
}
else
{
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens.Add(string.Empty, Channel.CreateBounded<TTokenBase>(options));
}
foreach(Channel<TTokenBase> tokens in AvailableTokens.Values)
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => tokens.Writer.TryWrite((TTokenBase) sender));
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default)
{
if (!AvailableTokens.TryGetValue(header, out Channel<TTokenBase> tokens))
throw new KeyNotFoundException($"Could not locate a token for header '{header}'.");
return await tokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default)
=> await AvailableTokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
}
}

View File

@@ -25,7 +25,7 @@ namespace Org.OpenAPITools
/// </summary>
protected TTokenBase[] _tokens;
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default);
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default);
/// <summary>
/// Instantiates a TokenProvider.

View File

@@ -11,9 +11,11 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Channels;
namespace Org.OpenAPITools.Client
namespace Org.OpenAPITools.Client
{
/// <summary>
/// Provides a token to the api clients. Tokens will be rate limited based on the provided TimeSpan.
@@ -21,7 +23,7 @@ namespace Org.OpenAPITools.Client
/// <typeparam name="TTokenBase"></typeparam>
public class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal Channel<TTokenBase> AvailableTokens { get; }
internal Dictionary<string, Channel<TTokenBase>> AvailableTokens { get; } = new();
/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
@@ -32,17 +34,24 @@ namespace Org.OpenAPITools.Client
foreach(TTokenBase token in _tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens = Channel.CreateBounded<TTokenBase>(options);
AvailableTokens.Add(string.Empty, Channel.CreateBounded<TTokenBase>(options));
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => AvailableTokens.Writer.TryWrite((TTokenBase) sender));
foreach(Channel<TTokenBase> tokens in AvailableTokens.Values)
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => tokens.Writer.TryWrite((TTokenBase) sender));
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default)
{
if (!AvailableTokens.TryGetValue(header, out Channel<TTokenBase>? tokens))
throw new KeyNotFoundException($"Could not locate a token for header '{header}'.");
return await tokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default)
=> await AvailableTokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
}
}

View File

@@ -27,7 +27,7 @@ namespace Org.OpenAPITools
/// </summary>
protected TTokenBase[] _tokens;
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default);
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default);
/// <summary>
/// Instantiates a TokenProvider.

View File

@@ -11,9 +11,11 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Channels;
namespace Org.OpenAPITools.Client
namespace Org.OpenAPITools.Client
{
/// <summary>
/// Provides a token to the api clients. Tokens will be rate limited based on the provided TimeSpan.
@@ -21,7 +23,7 @@ namespace Org.OpenAPITools.Client
/// <typeparam name="TTokenBase"></typeparam>
public class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal Channel<TTokenBase> AvailableTokens { get; }
internal Dictionary<string, Channel<TTokenBase>> AvailableTokens { get; } = new();
/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
@@ -32,17 +34,24 @@ namespace Org.OpenAPITools.Client
foreach(TTokenBase token in _tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens = Channel.CreateBounded<TTokenBase>(options);
AvailableTokens.Add(string.Empty, Channel.CreateBounded<TTokenBase>(options));
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => AvailableTokens.Writer.TryWrite((TTokenBase) sender));
foreach(Channel<TTokenBase> tokens in AvailableTokens.Values)
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => tokens.Writer.TryWrite((TTokenBase) sender));
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default)
{
if (!AvailableTokens.TryGetValue(header, out Channel<TTokenBase>? tokens))
throw new KeyNotFoundException($"Could not locate a token for header '{header}'.");
return await tokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default)
=> await AvailableTokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
}
}

View File

@@ -27,7 +27,7 @@ namespace Org.OpenAPITools
/// </summary>
protected TTokenBase[] _tokens;
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default);
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default);
/// <summary>
/// Instantiates a TokenProvider.

View File

@@ -11,9 +11,11 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Channels;
namespace Org.OpenAPITools.Client
namespace Org.OpenAPITools.Client
{
/// <summary>
/// Provides a token to the api clients. Tokens will be rate limited based on the provided TimeSpan.
@@ -21,7 +23,7 @@ namespace Org.OpenAPITools.Client
/// <typeparam name="TTokenBase"></typeparam>
public class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal Channel<TTokenBase> AvailableTokens { get; }
internal Dictionary<string, Channel<TTokenBase>> AvailableTokens { get; } = new();
/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
@@ -32,17 +34,24 @@ namespace Org.OpenAPITools.Client
foreach(TTokenBase token in _tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens = Channel.CreateBounded<TTokenBase>(options);
AvailableTokens.Add(string.Empty, Channel.CreateBounded<TTokenBase>(options));
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => AvailableTokens.Writer.TryWrite((TTokenBase) sender));
foreach(Channel<TTokenBase> tokens in AvailableTokens.Values)
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => tokens.Writer.TryWrite((TTokenBase) sender));
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default)
{
if (!AvailableTokens.TryGetValue(header, out Channel<TTokenBase>? tokens))
throw new KeyNotFoundException($"Could not locate a token for header '{header}'.");
return await tokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default)
=> await AvailableTokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
}
}

View File

@@ -27,7 +27,7 @@ namespace Org.OpenAPITools
/// </summary>
protected TTokenBase[] _tokens;
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default);
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default);
/// <summary>
/// Instantiates a TokenProvider.

View File

@@ -3235,10 +3235,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string, string>("dateTime", ClientUtils.ParameterToString(dateTime.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
BasicToken basicTokenLocalVar1 = (BasicToken) await BasicTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BasicToken basicTokenLocalVar1 = (BasicToken) await BasicTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(basicTokenLocalVar1);
@@ -3760,10 +3759,9 @@ namespace Org.OpenAPITools.Api
httpRequestMessageLocalVar.Headers.Add("boolean_group", ClientUtils.ParameterToString(booleanGroup.Value));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
BearerToken bearerTokenLocalVar1 = (BearerToken) await BearerTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
BearerToken bearerTokenLocalVar1 = (BearerToken) await BearerTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(bearerTokenLocalVar1);

View File

@@ -277,13 +277,12 @@ namespace Org.OpenAPITools.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(modelClient, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key_query", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar, "api_key_query");
apiKeyTokenLocalVar1.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar);
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
string[] contentTypes = new string[] {

View File

@@ -765,16 +765,15 @@ namespace Org.OpenAPITools.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(pet, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -983,10 +982,9 @@ namespace Org.OpenAPITools.Api
httpRequestMessageLocalVar.Headers.Add("api_key", ClientUtils.ParameterToString(apiKey.Value));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -1176,16 +1174,15 @@ namespace Org.OpenAPITools.Api
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -1427,16 +1424,15 @@ namespace Org.OpenAPITools.Api
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -1662,17 +1658,16 @@ namespace Org.OpenAPITools.Api
System.Collections.Specialized.NameValueCollection parseQueryStringLocalVar = System.Web.HttpUtility.ParseQueryString(string.Empty);
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "api_key");
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar);
ApiKeyToken apiKeyTokenLocalVar2 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar2 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key_query", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar2);
apiKeyTokenLocalVar2.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar, "api_key_query");
apiKeyTokenLocalVar2.UseInQuery(httpRequestMessageLocalVar, uriBuilderLocalVar, parseQueryStringLocalVar);
uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
string[] acceptLocalVars = new string[] {
@@ -1911,16 +1906,15 @@ namespace Org.OpenAPITools.Api
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(pet, _jsonSerializerOptions));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
@@ -2160,10 +2154,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string, string>("status", ClientUtils.ParameterToString(status.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -2386,10 +2379,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string, string>("additionalMetadata", ClientUtils.ParameterToString(additionalMetadata.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);
@@ -2651,10 +2643,9 @@ namespace Org.OpenAPITools.Api
formParameterLocalVars.Add(new KeyValuePair<string, string>("additionalMetadata", ClientUtils.ParameterToString(additionalMetadata.Value)));
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(oauthTokenLocalVar1);

View File

@@ -617,9 +617,9 @@ namespace Org.OpenAPITools.Api
uriBuilderLocalVar.Path = ClientUtils.CONTEXT_PATH + "/store/inventory";
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync(cancellationToken).ConfigureAwait(false);
ApiKeyToken apiKeyTokenLocalVar1 = (ApiKeyToken) await ApiKeyProvider.GetAsync("api_key", cancellationToken).ConfigureAwait(false);
tokenBaseLocalVars.Add(apiKeyTokenLocalVar1);
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "api_key");
apiKeyTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar);
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;

View File

@@ -11,14 +11,21 @@ namespace Org.OpenAPITools.Client
{
private string _raw;
/// <summary>
/// The header that this token will be used with.
/// </summary>
public string Header { get; }
/// <summary>
/// Constructs an ApiKeyToken object.
/// </summary>
/// <param name="value"></param>
/// <param name="header"></param>
/// <param name="prefix"></param>
/// <param name="timeout"></param>
public ApiKeyToken(string value, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
public ApiKeyToken(string value, string header, string prefix = "Bearer ", TimeSpan? timeout = null) : base(timeout)
{
Header = header;
_raw = $"{ prefix }{ value }";
}
@@ -26,22 +33,20 @@ namespace Org.OpenAPITools.Client
/// Places the token in the header.
/// </summary>
/// <param name="request"></param>
/// <param name="headerName"></param>
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request, string headerName)
public virtual void UseInHeader(System.Net.Http.HttpRequestMessage request)
{
request.Headers.Add(headerName, _raw);
request.Headers.Add(Header, _raw);
}
/// <summary>
/// Places the token in the query.
/// </summary>
/// <param name="request"></param>
/// <param name="uriBuilder"></param>
/// <param name="parseQueryString"></param>
/// <param name="parameterName"></param>
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString, string parameterName)
public virtual void UseInQuery(System.Net.Http.HttpRequestMessage request, UriBuilder uriBuilder, System.Collections.Specialized.NameValueCollection parseQueryString)
{
parseQueryString[parameterName] = Uri.EscapeDataString(_raw).ToString();
parseQueryString[Header] = Uri.EscapeDataString(_raw).ToString();
}
}
}

View File

@@ -9,12 +9,11 @@
*/
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Channels;
namespace Org.OpenAPITools.Client
namespace Org.OpenAPITools.Client
{
/// <summary>
/// Provides a token to the api clients. Tokens will be rate limited based on the provided TimeSpan.
@@ -22,8 +21,7 @@ namespace Org.OpenAPITools.Client
/// <typeparam name="TTokenBase"></typeparam>
public class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal ConcurrentDictionary<TTokenBase, TTokenBase> AvailableTokens = new ConcurrentDictionary<TTokenBase, TTokenBase>();
private SemaphoreSlim _semaphore;
internal Dictionary<string, Channel<TTokenBase>> AvailableTokens { get; } = new Dictionary<string, Channel<TTokenBase>>();
/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
@@ -31,48 +29,44 @@ namespace Org.OpenAPITools.Client
/// <param name="container"></param>
public RateLimitProvider(TokenContainer<TTokenBase> container) : base(container.Tokens)
{
_semaphore = new SemaphoreSlim(1, 1);
foreach(TTokenBase token in _tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));
for (int i = 0; i < _tokens.Length; i++)
if (container is TokenContainer<ApiKeyToken> apiKeyTokenContainer)
{
_tokens[i].TokenBecameAvailable += ((sender) =>
{
TTokenBase token = (TTokenBase)sender;
string[] headers = apiKeyTokenContainer.Tokens.Select(t => t.Header).Distinct().ToArray();
AvailableTokens.TryAdd(token, token);
});
foreach (string header in headers)
{
BoundedChannelOptions options = new BoundedChannelOptions(apiKeyTokenContainer.Tokens.Count(t => t.Header.Equals(header)))
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens.Add(header, Channel.CreateBounded<TTokenBase>(options));
}
}
else
{
BoundedChannelOptions options = new BoundedChannelOptions(_tokens.Length)
{
FullMode = BoundedChannelFullMode.DropWrite
};
AvailableTokens.Add(string.Empty, Channel.CreateBounded<TTokenBase>(options));
}
foreach(Channel<TTokenBase> tokens in AvailableTokens.Values)
for (int i = 0; i < _tokens.Length; i++)
_tokens[i].TokenBecameAvailable += ((sender) => tokens.Writer.TryWrite((TTokenBase) sender));
}
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default)
internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default)
{
await _semaphore.WaitAsync().ConfigureAwait(false);
if (!AvailableTokens.TryGetValue(header, out Channel<TTokenBase> tokens))
throw new KeyNotFoundException($"Could not locate a token for header '{header}'.");
try
{
TTokenBase result = null;
while (result == null)
{
TTokenBase tokenToRemove = AvailableTokens.FirstOrDefault().Value;
if (tokenToRemove != null && AvailableTokens.TryRemove(tokenToRemove, out result))
return result;
await Task.Delay(40).ConfigureAwait(false);
tokenToRemove = AvailableTokens.FirstOrDefault().Value;
}
return result;
}
finally
{
_semaphore.Release();
}
return await tokens.Reader.ReadAsync(cancellation).ConfigureAwait(false);
}
}
}

View File

@@ -25,7 +25,7 @@ namespace Org.OpenAPITools
/// </summary>
protected TTokenBase[] _tokens;
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(System.Threading.CancellationToken cancellation = default);
internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default);
/// <summary>
/// Instantiates a TokenProvider.

View File

@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo> <!-- setting GenerateAssemblyInfo to false causes this bug https://github.com/dotnet/project-system/issues/3934 -->
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Org.OpenAPITools</AssemblyName>
<PackageId>Org.OpenAPITools</PackageId>
<OutputType>Library</OutputType>
<Authors>OpenAPI</Authors>
<Company>OpenAPI</Company>
<AssemblyTitle>OpenAPI Library</AssemblyTitle>
<Description>A library generated from a OpenAPI doc</Description>
<Copyright>No Copyright</Copyright>
<RootNamespace>Org.OpenAPITools</RootNamespace>
<Version>1.0.0</Version>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\Org.OpenAPITools.xml</DocumentationFile>
<RepositoryUrl>https://github.com/GIT_USER_ID/GIT_REPO_ID.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageReleaseNotes>Minor update</PackageReleaseNotes>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CompareNETObjects" Version="4.82.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="5.0.1" />
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>
</Project>

View File

@@ -24,6 +24,7 @@
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="5.0.1" />
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>