Skip to content

Commit

Permalink
Version 12.0.0 preparation (#360)
Browse files Browse the repository at this point in the history
* Make the client using streams the default. Using strings is not sustainable (#359)

* bump gh upload action

* Update to .NET 6 (#361)

* refactor loggerhandler (#273)

* refactor loggerhandler

* support multipe loglevel for exceptions

* better logger format in CI

* add test for logging

* add test for default logging output

* set defaultrequestversion in DependencyInjectionSetup

* use SocketsHttpHandler

* add NotFoundMiddleware
add ClientBuilder

* remove ClientFactory uses

* refactor errorhandler

* remove HttpVersion from clientbuilder invocations

---------

Co-authored-by: Henrik <[email protected]>
  • Loading branch information
jenschude and Henr1k80 authored Nov 26, 2024
1 parent 4a4893a commit 205c6f9
Show file tree
Hide file tree
Showing 36 changed files with 640 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ public static IHttpClientBuilder UseCommercetoolsScopedClient(this IServiceColle
{
var clientConfiguration = configuration.GetSection(clientName).Get<ClientConfiguration>();
var tokenProvider = serviceProvider.GetService<ITokenProvider>();
var client = ClientFactory.Create(clientName, clientConfiguration,
serviceProvider.GetService<IHttpClientFactory>(),
serviceProvider.GetService<IApiSerializerService>(),
tokenProvider);
client.Name = clientName;
var client = new ClientBuilder()
{
ClientConfiguration = clientConfiguration,
ClientName = clientName,
TokenProvider = tokenProvider,
SerializerService = serviceProvider.GetService<IApiSerializerService>(),
HttpClient = serviceProvider.GetService<IHttpClientFactory>().CreateClient(clientName)
}.Build();
return client;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ public static IHttpClientBuilder UseCommercetoolsScopedClient(this IServiceColle
{
var clientConfiguration = configuration.GetSection(clientName).Get<ClientConfiguration>();
var tokenProvider = serviceProvider.GetService<ITokenProvider>();
var client = ClientFactory.Create(clientName, clientConfiguration,
serviceProvider.GetService<IHttpClientFactory>(),
serviceProvider.GetService<IApiSerializerService>(),
tokenProvider);
client.Name = clientName;
var client = new ClientBuilder()
{
ClientName = clientName,
ClientConfiguration = clientConfiguration,
TokenProvider = tokenProvider,
SerializerService =serviceProvider.GetService<IApiSerializerService>(),
HttpClient = serviceProvider.GetService<IHttpClientFactory>().CreateClient(clientName)
}.Build();
return client;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ public static async Task Main(string[] args)
ProjectKey = ""
};
var clientFactory = serviceProvider.GetService<IHttpClientFactory>();
var client = ClientFactory.Create(
clientName,
config,
clientFactory,
serviceProvider.GetService<IApiSerializerService>(),
TokenProviderFactory.CreateClientCredentialsTokenProvider(config, clientFactory)
);
var client = new ClientBuilder()
{
ClientConfiguration = config,
ClientName = clientName,
TokenProvider = TokenProviderFactory.CreateClientCredentialsTokenProvider(config, clientFactory),
SerializerService = serviceProvider.GetService<IApiSerializerService>(),
HttpClient = clientFactory.CreateClient(clientName)
}.Build();

var project = await new ApiRoot(client)
.WithProjectKey(config.ProjectKey)
.Get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ public static IHttpClientBuilder UseCommercetoolsScopedClient(this IServiceColle
{
var clientConfiguration = configuration.GetSection(clientName).Get<ClientConfiguration>();
var tokenProvider = serviceProvider.GetService<ITokenProvider>();
var client = ClientFactory.Create(clientName, clientConfiguration,
serviceProvider.GetService<IHttpClientFactory>(),
serviceProvider.GetService<IApiSerializerService>(),
tokenProvider);
var client = new ClientBuilder()
{
ClientConfiguration = clientConfiguration,
ClientName = clientName,
TokenProvider = tokenProvider,
SerializerService = serviceProvider.GetService<IApiSerializerService>(),
HttpClient = serviceProvider.GetService<IHttpClientFactory>().CreateClient(clientName)
}.Build();
client.Name = clientName;
return client;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,45 @@ namespace commercetools.Api.IntegrationTests;

public class LoggingTest
{
[Fact]
public async void DefaultLogger()
{
var configuration = new ConfigurationBuilder().
AddJsonFile("appsettings.test.Development.json", true).
AddEnvironmentVariables().
AddUserSecrets<ServiceProviderFixture>().
AddEnvironmentVariables("CTP_").
Build();
var clientConfiguration = configuration.GetSection("Client").Get<ClientConfiguration>();
var loggerClientConf = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>()
{
{ "LoggerClient:ClientId", clientConfiguration.ClientId},
{ "LoggerClient:ClientSecret", clientConfiguration.ClientSecret},
{ "LoggerClient:ProjectKey", clientConfiguration.ProjectKey},
})
.Build();
var logger = new TestLogger();
var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddFilter("System.Net.Http.HttpClient", LogLevel.None) // disable HTTP client default logging
.AddProvider(new TestLoggerProvider(logger));
});
var s = new ServiceCollection();
s.AddSingleton(loggerFactory);
s.UseCommercetoolsApi(loggerClientConf, "LoggerClient");
var p = s.BuildServiceProvider();

var apiRoot = p.GetService<ProjectApiRoot>();

await apiRoot.Get().ExecuteAsync();

var messages = logger.GetLogMessages();
Assert.StartsWith("GET https://api.europe-west1.gcp.commercetools.com/" + clientConfiguration.ProjectKey, messages.TrimEnd());
}


[Fact]
public async void CustomLogger()
{
Expand Down Expand Up @@ -55,7 +94,7 @@ public async void CustomLogger()
var messages = logger.GetLogMessages();
Assert.Equal("GET https://api.europe-west1.gcp.commercetools.com/" + clientConfiguration.ProjectKey, messages.TrimEnd());
}

public class CustomLoggerHandler : DelegatingHandler
{
private readonly ILogger logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,13 @@ private void CreateMeClient()
CustomerServices.CustomerPassword));

//Create MeClient
_meClient = ClientFactory.Create(
"MeClient",
meClientConfig,
httpClientFactory,
serializerService,
passwordTokenProvider);
_meClient = new ClientBuilder {
ClientName = "MeClient",
ClientConfiguration = meClientConfig,
TokenProvider = passwordTokenProvider,
HttpClient = httpClientFactory.CreateClient("MeClient"),
SerializerService = serializerService,
}.Build();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System.Collections.Generic;
using commercetools.Base.Client;
using commercetools.Base.Client.Middlewares;
using commercetools.Sdk.Api;
using commercetools.Sdk.Api.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

namespace commercetools.Api.IntegrationTests;

public class MiddlewareTest
{
[Fact]
public async void not_found_middleware_stream_client()
{
var configuration = new ConfigurationBuilder().
AddJsonFile("appsettings.test.Development.json", true).
AddEnvironmentVariables().
AddUserSecrets<ServiceProviderFixture>().
AddEnvironmentVariables("CTP_").
Build();

var s = new ServiceCollection();
s.UseCommercetoolsApi(configuration, "Client", options: new ClientOptions() { ReadResponseAsStream = true},middlewares: new List<DelegatingMiddleware>()
{
new NotFoundMiddleware()
});
var p = s.BuildServiceProvider();

var apiConfig = configuration.GetSection("Client").Get<ClientConfiguration>();
var apiRoot = p.GetService<ProjectApiRoot>();

Assert.Equal("Client", apiRoot.ClientName);
var category = await apiRoot.Categories().WithKey("unknown-key").Get().ExecuteAsync().ConfigureAwait(false);

Assert.Null(category);
}

[Fact]
public async void not_found_middleware_string_client()
{
var configuration = new ConfigurationBuilder().
AddJsonFile("appsettings.test.Development.json", true).
AddEnvironmentVariables().
AddUserSecrets<ServiceProviderFixture>().
AddEnvironmentVariables("CTP_").
Build();

var s = new ServiceCollection();
s.UseCommercetoolsApi(configuration, "Client", options: new ClientOptions() { ReadResponseAsStream = false},middlewares: new List<DelegatingMiddleware>()
{
new NotFoundMiddleware()
});
var p = s.BuildServiceProvider();

var apiConfig = configuration.GetSection("Client").Get<ClientConfiguration>();
var apiRoot = p.GetService<ProjectApiRoot>();

Assert.Equal("Client", apiRoot.ClientName);
var category = await apiRoot.Categories().WithKey("unknown-key").Get().ExecuteAsync().ConfigureAwait(false);

Assert.Null(category);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Linq;
using commercetools.Api.IntegrationTests;
using commercetools.Base.Client;
using commercetools.Base.Client.Middlewares;
using commercetools.Sdk.Api;
using commercetools.Sdk.Api.Extensions;
using commercetools.Sdk.ImportApi.Extensions;
Expand Down Expand Up @@ -82,6 +84,5 @@ public async void api_and_import_create_root()


}

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using commercetools.Sdk.Api.Models.Errors;
using commercetools.Base.Client;
using commercetools.Base.Client.Error;
using commercetools.Sdk.Api;
using commercetools.Sdk.Api.Serialization;
using Microsoft.Extensions.Configuration;
Expand All @@ -9,7 +11,7 @@

namespace commercetools.Api.IntegrationTests
{
public class ServiceProviderFixture
public sealed class ServiceProviderFixture
{
private readonly ServiceProvider serviceProvider;
private readonly IConfiguration configuration;
Expand All @@ -20,20 +22,44 @@ public ServiceProviderFixture()

//services.AddLogging(configure => configure.AddConsole());
this.configuration = new ConfigurationBuilder().
AddInMemoryCollection(
new Dictionary<string, string>()
{
{ "Logging:LogLevel:commercetoolsLoggerHandler", "Warning"},
{ "Logging:LogLevel:System.Net.Http.HttpClient", "Warning"},
}).
AddJsonFile("appsettings.test.Development.json", true).
AddEnvironmentVariables().
AddUserSecrets<ServiceProviderFixture>().
AddEnvironmentVariables("CTP_").
Build();

var useStreamClient = Enum.Parse<ClientType>(configuration.GetValue("ClientType", "String")) == ClientType.Stream;
var useStreamClient = Enum.Parse<ClientType>(configuration.GetValue("ClientType", "String")) != ClientType.String;
services.UseCommercetoolsApi(configuration, "Client", options: new ClientOptions { ReadResponseAsStream = useStreamClient });
services.AddLogging(c => c.AddConfiguration(configuration.GetSection("Logging")));
services.AddLogging(c => c.AddProvider(new InMemoryLoggerProvider()));
services.AddLogging(c => c.AddSimpleConsole(o =>
{
o.UseUtcTimestamp = true;
o.IncludeScopes = true;
o.TimestampFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFK ";
o.SingleLine = true;
}));
services.SetupClient(
"MeClient",
errorTypeMapper => typeof(ErrorResponse),
s => s.GetService<IApiSerializerService>()
);
services.AddSingleton<ILoggerHandlerOptions>(new LoggerHandlerOptions()
{
ResponseLogEvent = LogLevel.Information,
DefaultExceptionLogEvent = LogLevel.Warning,
ExceptionLogEvents = new Dictionary<System.Type, LogLevel>()
{
{ typeof(NotFoundException), LogLevel.Information },
{ typeof(ConcurrentModificationException), LogLevel.Information}
}
});
this.serviceProvider = services.BuildServiceProvider();

//set default ProjectKey
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace commercetools.GraphQL.Api.IntegrationTests
{
public class ServiceProviderFixture
public sealed class ServiceProviderFixture
{
private readonly ServiceProvider serviceProvider;
private readonly IConfiguration configuration;
Expand All @@ -24,7 +24,7 @@ public ServiceProviderFixture()
AddUserSecrets<ServiceProviderFixture>().
AddEnvironmentVariables("CTP_").
Build();
var useStreamClient = Enum.Parse<ClientType>(configuration.GetValue("ClientType", "String")) == ClientType.Stream;
var useStreamClient = Enum.Parse<ClientType>(configuration.GetValue("ClientType", "String")) != ClientType.String;

services.UseCommercetoolsApi(configuration, "Client", options: new ClientOptions { ReadResponseAsStream = useStreamClient });
services.AddLogging(c => c.AddProvider(new InMemoryLoggerProvider()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace commercetools.ImportApi.IntegrationTests
{
public class ServiceProviderFixture
public sealed class ServiceProviderFixture
{
private readonly ServiceProvider serviceProvider;
private readonly IConfiguration configuration;
Expand All @@ -22,7 +22,7 @@ public ServiceProviderFixture()
AddEnvironmentVariables("CTP_").
Build();

var useStreamClient = Enum.Parse<ClientType>(configuration.GetValue("ClientType", "String")) == ClientType.Stream;
var useStreamClient = Enum.Parse<ClientType>(configuration.GetValue("ClientType", "String")) != ClientType.String;
services.UseCommercetoolsImportApi(configuration, "ImportClient", options: new ClientOptions { ReadResponseAsStream = useStreamClient });
this.serviceProvider = services.BuildServiceProvider();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,47 @@ public void TestUserAgent()
Assert.Equal("commercetools-sdk-dotnet-v2", agent.Product.Name);
}

[Fact]
public void TestClientConfigValidationBuilder()
{
//arrange
var s = new ServiceCollection();
s.UseCommercetoolsApiSerialization();
var p = s.BuildServiceProvider();
var serializerService = p.GetService<IApiSerializerService>();
var clientConfig = new ClientConfiguration
{
ClientId = "ClientId",
ClientSecret = "ClientSecret",
ProjectKey = "test",
ApiBaseAddress = "https://api.europe-west1.gcp.commercetools.com",
AuthorizationBaseAddress = "https://auth.europe-west1.gcp.commercetools.com/"
};

//act
Exception validationEx = null;
try
{
var tokenProvider = TokenProviderFactory
.CreateClientCredentialsTokenProvider(clientConfig, null);

new ClientBuilder {
ClientName = "test",
ClientConfiguration = clientConfig,
HttpClient = null,
SerializerService = serializerService,
TokenProvider = tokenProvider}.Build();
}
catch (Exception e)
{
validationEx = e;
}

//assert
Assert.NotNull(validationEx);
Assert.IsType<ValidationException>(validationEx);
}

[Fact]
public void TestClientConfigValidation()
{
Expand Down
1 change: 0 additions & 1 deletion commercetools.Sdk/commercetools.Base.Client/ApiMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ public virtual HttpRequestMessage Build()
{
var requestPath = new Uri(RequestUrl + ToQueryString(QueryParams), UriKind.Relative);
var request = new HttpRequestMessage();
request.Version = HttpVersion.Version20;
request.Method = this.Method;
request.RequestUri = requestPath;
request.AddHeaders(Headers);
Expand Down
Loading

0 comments on commit 205c6f9

Please sign in to comment.