Skip to content

Commit

Permalink
Merge pull request #730 from xlegalles/CleanUpCode2
Browse files Browse the repository at this point in the history
style: use file-scope namespace and primary constructor
  • Loading branch information
ChrisKujawa authored Oct 25, 2024
2 parents 4194df7 + 86cf221 commit f46c8de
Show file tree
Hide file tree
Showing 20 changed files with 728 additions and 868 deletions.
168 changes: 83 additions & 85 deletions Client/Impl/Builder/CamundaCloudClientBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,115 +1,113 @@
using System;
using Microsoft.Extensions.Logging;
using Zeebe.Client.Api.Builder;
using Zeebe.Client.Impl.Builder;

namespace Zeebe.Client.Impl.Builder
namespace Zeebe.Client.Impl.Builder;

public class CamundaCloudClientBuilder : ICamundaCloudClientBuilder, ICamundaCloudClientBuilderStep1, ICamundaCloudClientBuilderStep2, ICamundaCloudClientBuilderFinalStep
{
public class CamundaCloudClientBuilder : ICamundaCloudClientBuilder, ICamundaCloudClientBuilderStep1, ICamundaCloudClientBuilderStep2, ICamundaCloudClientBuilderFinalStep
private const string ZeebeAddressEnvVar = "ZEEBE_ADDRESS";
private const string ZeebeClientIdEnvVar = "ZEEBE_CLIENT_ID";
private const string ZeebeClientSecretEnvVar = "ZEEBE_CLIENT_SECRET";
private const string ZeebeAuthServerEnvVar = "ZEEBE_AUTHORIZATION_SERVER_URL";

private readonly CamundaCloudTokenProviderBuilder camundaCloudTokenProviderBuilder;
private string gatewayAddress;
private ILoggerFactory loggerFactory;

private CamundaCloudClientBuilder()
{
private const string ZeebeAddressEnvVar = "ZEEBE_ADDRESS";
private const string ZeebeClientIdEnvVar = "ZEEBE_CLIENT_ID";
private const string ZeebeClientSecretEnvVar = "ZEEBE_CLIENT_SECRET";
private const string ZeebeAuthServerEnvVar = "ZEEBE_AUTHORIZATION_SERVER_URL";
camundaCloudTokenProviderBuilder = CamundaCloudTokenProvider.Builder();
}

private readonly CamundaCloudTokenProviderBuilder camundaCloudTokenProviderBuilder;
private string gatewayAddress;
private ILoggerFactory loggerFactory;
public static ICamundaCloudClientBuilder Builder()
{
return new CamundaCloudClientBuilder();
}

private CamundaCloudClientBuilder()
{
camundaCloudTokenProviderBuilder = CamundaCloudTokenProvider.Builder();
}
public ICamundaCloudClientBuilderStep1 UseClientId(string clientId)
{
camundaCloudTokenProviderBuilder.UseClientId(clientId);
return this;
}

public static ICamundaCloudClientBuilder Builder()
{
return new CamundaCloudClientBuilder();
}
public ICamundaCloudClientBuilderStep2 UseClientSecret(string clientSecret)
{
camundaCloudTokenProviderBuilder.UseClientSecret(clientSecret);
return this;
}

public ICamundaCloudClientBuilderFinalStep UseContactPoint(string contactPoint)
{
_ = contactPoint ?? throw new ArgumentNullException(nameof(contactPoint));

public ICamundaCloudClientBuilderStep1 UseClientId(string clientId)
if (!contactPoint.EndsWith(":443"))
{
camundaCloudTokenProviderBuilder.UseClientId(clientId);
return this;
gatewayAddress = contactPoint + ":443";
camundaCloudTokenProviderBuilder.UseAudience(contactPoint);
}

public ICamundaCloudClientBuilderStep2 UseClientSecret(string clientSecret)
else
{
camundaCloudTokenProviderBuilder.UseClientSecret(clientSecret);
return this;
gatewayAddress = contactPoint;
camundaCloudTokenProviderBuilder.UseAudience(contactPoint.Replace(":443", ""));
}

public ICamundaCloudClientBuilderFinalStep UseContactPoint(string contactPoint)
{
_ = contactPoint ?? throw new ArgumentNullException(nameof(contactPoint));

if (!contactPoint.EndsWith(":443"))
{
gatewayAddress = contactPoint + ":443";
camundaCloudTokenProviderBuilder.UseAudience(contactPoint);
}
else
{
gatewayAddress = contactPoint;
camundaCloudTokenProviderBuilder.UseAudience(contactPoint.Replace(":443", ""));
}
return this;
}

return this;
}
public ICamundaCloudClientBuilderFinalStep UseLoggerFactory(ILoggerFactory loggerFactory)
{
this.loggerFactory = loggerFactory;
camundaCloudTokenProviderBuilder.UseLoggerFactory(this.loggerFactory);
return this;
}

public ICamundaCloudClientBuilderFinalStep UseLoggerFactory(ILoggerFactory loggerFactory)
public ICamundaCloudClientBuilderFinalStep UseAuthServer(string url)
{
if (url is null)
{
this.loggerFactory = loggerFactory;
camundaCloudTokenProviderBuilder.UseLoggerFactory(this.loggerFactory);
// use default
return this;
}

public ICamundaCloudClientBuilderFinalStep UseAuthServer(string url)
{
if (url is null)
{
// use default
return this;
}

camundaCloudTokenProviderBuilder.UseAuthServer(url);
return this;
}
camundaCloudTokenProviderBuilder.UseAuthServer(url);
return this;
}

public ICamundaCloudClientBuilderFinalStep UsePersistedStoragePath(string path)
public ICamundaCloudClientBuilderFinalStep UsePersistedStoragePath(string path)
{
if (path is null)
{
if (path is null)
{
// use default
return this;
}

camundaCloudTokenProviderBuilder.UsePath(path);
// use default
return this;
}

private string GetFromEnv(string key)
{
char[] charsToTrim = { ' ', '\'' };
return Environment.GetEnvironmentVariable(key)?.Trim(charsToTrim);
}
camundaCloudTokenProviderBuilder.UsePath(path);
return this;
}

public ICamundaCloudClientBuilderFinalStep FromEnv()
{
this.UseClientId(GetFromEnv(ZeebeClientIdEnvVar))
.UseClientSecret(GetFromEnv(ZeebeClientSecretEnvVar))
.UseContactPoint(GetFromEnv(ZeebeAddressEnvVar))
.UseAuthServer(GetFromEnv(ZeebeAuthServerEnvVar));
return this;
}
private string GetFromEnv(string key)
{
char[] charsToTrim = [' ', '\''];
return Environment.GetEnvironmentVariable(key)?.Trim(charsToTrim);
}

public IZeebeClient Build()
{
return ZeebeClient.Builder()
.UseLoggerFactory(loggerFactory)
.UseGatewayAddress(gatewayAddress)
.UseTransportEncryption()
.UseAccessTokenSupplier(camundaCloudTokenProviderBuilder.Build())
.Build();
}
public ICamundaCloudClientBuilderFinalStep FromEnv()
{
UseClientId(GetFromEnv(ZeebeClientIdEnvVar))
.UseClientSecret(GetFromEnv(ZeebeClientSecretEnvVar))
.UseContactPoint(GetFromEnv(ZeebeAddressEnvVar))
.UseAuthServer(GetFromEnv(ZeebeAuthServerEnvVar));
return this;
}

public IZeebeClient Build()
{
return ZeebeClient.Builder()
.UseLoggerFactory(loggerFactory)
.UseGatewayAddress(gatewayAddress)
.UseTransportEncryption()
.UseAccessTokenSupplier(camundaCloudTokenProviderBuilder.Build())
.Build();
}
}
175 changes: 87 additions & 88 deletions Client/Impl/Builder/CamundaCloudTokenProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,105 +8,104 @@
using Zeebe.Client.Api.Builder;
using Zeebe.Client.Impl.Misc;

namespace Zeebe.Client.Impl.Builder
namespace Zeebe.Client.Impl.Builder;

public class CamundaCloudTokenProvider : IAccessTokenSupplier, IDisposable
{
public class CamundaCloudTokenProvider : IAccessTokenSupplier, IDisposable
{
private static readonly string ZeebeRootPath =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".zeebe");
private static readonly string ZeebeRootPath =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".zeebe");

private readonly ILogger<CamundaCloudTokenProvider> logger;
private readonly string authServer;
private readonly string clientId;
private readonly string clientSecret;
private readonly string audience;
private HttpClient httpClient;
private HttpMessageHandler httpMessageHandler;
private readonly PersistedAccessTokenCache persistedAccessTokenCache;
private readonly ILogger<CamundaCloudTokenProvider> logger;
private readonly string authServer;
private readonly string clientId;
private readonly string clientSecret;
private readonly string audience;
private HttpClient httpClient;
private HttpMessageHandler httpMessageHandler;
private readonly PersistedAccessTokenCache persistedAccessTokenCache;

internal CamundaCloudTokenProvider(
string authServer,
string clientId,
string clientSecret,
string audience,
string path = null,
ILoggerFactory loggerFactory = null)
{
persistedAccessTokenCache = new PersistedAccessTokenCache(path ?? ZeebeRootPath, FetchAccessToken, loggerFactory?.CreateLogger<PersistedAccessTokenCache>());
this.logger = loggerFactory?.CreateLogger<CamundaCloudTokenProvider>();
this.authServer = authServer;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.audience = audience;
httpClient = new HttpClient(new HttpClientHandler(), disposeHandler: false);
}
internal CamundaCloudTokenProvider(
string authServer,
string clientId,
string clientSecret,
string audience,
string path = null,
ILoggerFactory loggerFactory = null)
{
persistedAccessTokenCache = new PersistedAccessTokenCache(path ?? ZeebeRootPath, FetchAccessToken, loggerFactory?.CreateLogger<PersistedAccessTokenCache>());
logger = loggerFactory?.CreateLogger<CamundaCloudTokenProvider>();
this.authServer = authServer;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.audience = audience;
httpClient = new HttpClient(new HttpClientHandler(), disposeHandler: false);
}

public static CamundaCloudTokenProviderBuilder Builder()
{
return new CamundaCloudTokenProviderBuilder();
}
public static CamundaCloudTokenProviderBuilder Builder()
{
return new CamundaCloudTokenProviderBuilder();
}

internal void SetHttpMessageHandler(HttpMessageHandler handler)
{
httpMessageHandler = handler;
httpClient = new HttpClient(handler);
}
internal void SetHttpMessageHandler(HttpMessageHandler handler)
{
httpMessageHandler = handler;
httpClient = new HttpClient(handler);
}

private async Task<AccessToken> FetchAccessToken()
{
// Requesting the token is similar to this:
// curl -X POST https://login.cloud.ultrawombat.com/oauth/token \
// -H "Content-Type: application/x-www-form-urlencoded" \
// -d "client_id=213131&client_secret=12-23~oU.321&audience=zeebe.ultrawombat.com&grant_type=client_credentials"
//
// alternative is json
// curl --request POST \
// --url https://login.cloud.[ultrawombat.com | camunda.io]/oauth/token \
// --header 'content-type: application/json' \
// --data '{"client_id":"${clientId}","client_secret":"${clientSecret}","audience":"${audience}","grant_type":"client_credentials"}'
private async Task<AccessToken> FetchAccessToken()
{
// Requesting the token is similar to this:
// curl -X POST https://login.cloud.ultrawombat.com/oauth/token \
// -H "Content-Type: application/x-www-form-urlencoded" \
// -d "client_id=213131&client_secret=12-23~oU.321&audience=zeebe.ultrawombat.com&grant_type=client_credentials"
//
// alternative is json
// curl --request POST \
// --url https://login.cloud.[ultrawombat.com | camunda.io]/oauth/token \
// --header 'content-type: application/json' \
// --data '{"client_id":"${clientId}","client_secret":"${clientSecret}","audience":"${audience}","grant_type":"client_credentials"}'

var formContent = BuildRequestAccessTokenContent();
var httpResponseMessage = await httpClient.PostAsync(authServer, formContent);
var formContent = BuildRequestAccessTokenContent();
var httpResponseMessage = await httpClient.PostAsync(authServer, formContent);

// Code expects the following result:
//
// {
// "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
// "token_type":"bearer",
// "expires_in":3600,
// "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
// "scope":"create"
// }
//
// Defined here https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/
var result = await httpResponseMessage.Content.ReadAsStringAsync();
var token = AccessToken.FromJson(result);
logger?.LogDebug("Received access token for {Audience}", audience);
return token;
}
// Code expects the following result:
//
// {
// "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
// "token_type":"bearer",
// "expires_in":3600,
// "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
// "scope":"create"
// }
//
// Defined here https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/
var result = await httpResponseMessage.Content.ReadAsStringAsync();
var token = AccessToken.FromJson(result);
logger?.LogDebug("Received access token for {Audience}", audience);
return token;
}

private FormUrlEncodedContent BuildRequestAccessTokenContent()
private FormUrlEncodedContent BuildRequestAccessTokenContent()
{
var formContent = new FormUrlEncodedContent(new[]
{
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("client_id", clientId),
new KeyValuePair<string, string>("client_secret", clientSecret),
new KeyValuePair<string, string>("audience", audience),
new KeyValuePair<string, string>("grant_type", "client_credentials")
});
return formContent;
}
new KeyValuePair<string, string>("client_id", clientId),
new KeyValuePair<string, string>("client_secret", clientSecret),
new KeyValuePair<string, string>("audience", audience),
new KeyValuePair<string, string>("grant_type", "client_credentials")
});
return formContent;
}

public void Dispose()
{
httpClient.Dispose();
httpMessageHandler.Dispose();
}
public void Dispose()
{
httpClient.Dispose();
httpMessageHandler.Dispose();
}

public async Task<string> GetAccessTokenForRequestAsync(string authUri = null,
CancellationToken cancellationToken = default(CancellationToken))
{
return await persistedAccessTokenCache.Get(audience);
}
public async Task<string> GetAccessTokenForRequestAsync(string authUri = null,
CancellationToken cancellationToken = default(CancellationToken))
{
return await persistedAccessTokenCache.Get(audience);
}
}
Loading

0 comments on commit f46c8de

Please sign in to comment.