Skip to content

Commit 596e077

Browse files
authored
support custom correlation id provider (#305)
1 parent e6dce91 commit 596e077

File tree

4 files changed

+104
-10
lines changed

4 files changed

+104
-10
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System;
2+
using System.Linq;
3+
using commercetools.Base.Client;
4+
using commercetools.Base.Client.Middlewares;
5+
using commercetools.Sdk.Api;
6+
using commercetools.Sdk.Api.Client;
7+
using commercetools.Sdk.ImportApi;
8+
using Microsoft.Extensions.Configuration;
9+
using Microsoft.Extensions.DependencyInjection;
10+
using Xunit;
11+
12+
namespace commercetools.Api.IntegrationTests;
13+
14+
public class CorrelationIdProviderTest
15+
{
16+
[Fact]
17+
public async void TestCustomCorrelationId()
18+
{
19+
var configuration = new ConfigurationBuilder().
20+
AddJsonFile("appsettings.test.Development.json", true).
21+
AddEnvironmentVariables().
22+
AddUserSecrets<ServiceProviderFixture>().
23+
AddEnvironmentVariables("CTP_").
24+
Build();
25+
26+
var s = new ServiceCollection();
27+
s.UseCommercetoolsApi(configuration, "Client");
28+
s.AddSingleton<ICorrelationIdProvider>(new TestCorrelationIdProvider());
29+
var p = s.BuildServiceProvider();
30+
31+
var apiRoot = p.GetService<ProjectApiRoot>();
32+
33+
var result = await apiRoot.Get().SendAsync();
34+
35+
Assert.StartsWith("TestProvider/", result.HttpHeaders.GetValues(ApiHttpHeaders.X_CORRELATION_ID).First());
36+
}
37+
38+
[Fact]
39+
public async void TestCorrelationId()
40+
{
41+
var configuration = new ConfigurationBuilder().
42+
AddJsonFile("appsettings.test.Development.json", true).
43+
AddEnvironmentVariables().
44+
AddUserSecrets<ServiceProviderFixture>().
45+
AddEnvironmentVariables("CTP_").
46+
Build();
47+
48+
var s = new ServiceCollection();
49+
s.UseCommercetoolsApi(configuration, "Client");
50+
var p = s.BuildServiceProvider();
51+
var clientConfiguration = configuration.GetSection("Client").Get<ClientConfiguration>();
52+
var apiRoot = p.GetService<ProjectApiRoot>();
53+
54+
var result = await apiRoot.Get().SendAsync();
55+
56+
Assert.StartsWith(clientConfiguration.ProjectKey, result.HttpHeaders.GetValues(ApiHttpHeaders.X_CORRELATION_ID).First());
57+
}
58+
59+
[Fact]
60+
public async void TestCorrelationIdPerRequest()
61+
{
62+
var configuration = new ConfigurationBuilder().
63+
AddJsonFile("appsettings.test.Development.json", true).
64+
AddEnvironmentVariables().
65+
AddUserSecrets<ServiceProviderFixture>().
66+
AddEnvironmentVariables("CTP_").
67+
Build();
68+
69+
var s = new ServiceCollection();
70+
s.UseCommercetoolsApi(configuration, "Client");
71+
var p = s.BuildServiceProvider();
72+
73+
var apiRoot = p.GetService<ProjectApiRoot>();
74+
75+
ApiHttpHeaders headers = new ApiHttpHeaders();
76+
headers.AddHeader(ApiHttpHeaders.X_CORRELATION_ID, $"TestRequest/{Guid.NewGuid()}");
77+
var result = await apiRoot.Get().WithHeaders(headers).SendAsync();
78+
79+
Assert.StartsWith("TestRequest/", result.HttpHeaders.GetValues(ApiHttpHeaders.X_CORRELATION_ID).First());
80+
}
81+
82+
private class TestCorrelationIdProvider : ICorrelationIdProvider
83+
{
84+
public string CorrelationId => $"TestProvider/{Guid.NewGuid()}";
85+
public IClientConfiguration ClientConfiguration { get; set; }
86+
}
87+
}

commercetools.Sdk/commercetools.Base.Client/ClientFactory.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,27 @@ public static IClient Create(
1616
IHttpClientFactory factory,
1717
ISerializerService serializerService,
1818
ITokenProvider tokenProvider,
19-
bool readResponseAsStream = false)
19+
bool readResponseAsStream = false,
20+
ICorrelationIdProvider correlationIdProvider = null)
2021
{
2122
Validator.ValidateObject(configuration, new ValidationContext(configuration), true);
2223
if (readResponseAsStream && serializerService is IStreamSerializerService streamSerializer)
2324
{
2425
return new StreamCtpClient(
25-
CreateMiddlewareStack(clientName, configuration, factory, tokenProvider, true),
26+
CreateMiddlewareStack(clientName, configuration, factory, tokenProvider, true, correlationIdProvider),
2627
streamSerializer,
2728
clientName
2829
);
2930
}
3031
return new CtpClient(
31-
CreateMiddlewareStack(clientName, configuration, factory, tokenProvider),
32+
CreateMiddlewareStack(clientName, configuration, factory, tokenProvider, false, correlationIdProvider),
3233
serializerService,
3334
clientName
3435
);
3536
}
3637

3738
public static Middleware CreateMiddlewareStack(string clientName, IClientConfiguration configuration,
38-
IHttpClientFactory factory, ITokenProvider tokenProvider, bool readResponseAsStream = false)
39+
IHttpClientFactory factory, ITokenProvider tokenProvider, bool readResponseAsStream = false, ICorrelationIdProvider correlationIdProvider = null)
3940
{
4041
var httpClient = factory.CreateClient(clientName);
4142
httpClient.BaseAddress = new Uri(configuration.ApiBaseAddress);
@@ -44,7 +45,7 @@ public static Middleware CreateMiddlewareStack(string clientName, IClientConfigu
4445
{
4546
CreateAuthMiddleware(tokenProvider),
4647
CreateCorrelationIdMiddleware(
47-
new DefaultCorrelationIdProvider(configuration)
48+
correlationIdProvider ?? new DefaultCorrelationIdProvider(configuration)
4849
)
4950
};
5051

commercetools.Sdk/commercetools.Base.Client/DependencyInjectionSetup.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,22 @@ private static IDictionary<string, IHttpClientBuilder> UseMultipleClients(this I
4545
{
4646
var builders = new ConcurrentDictionary<string, IHttpClientBuilder>();
4747

48+
4849
clients.ToList().ForEach(clientName =>
4950
{
5051
IClientConfiguration clientConfiguration =
5152
configuration.GetSection(clientName).Get<ClientConfiguration>();
5253
Validator.ValidateObject(clientConfiguration, new ValidationContext(clientConfiguration), true);
53-
54+
5455
builders.TryAdd(clientName, services.SetupClient(clientName, errorResponseTypeMapper, serializerFactory, options));
5556
services.AddSingleton(serviceProvider =>
5657
{
5758
var client = ClientFactory.Create(clientName, clientConfiguration,
5859
serviceProvider.GetService<IHttpClientFactory>(),
5960
serializerFactory(serviceProvider),
6061
tokenProviderSupplier(clientName, configuration, serviceProvider),
61-
options.ReadResponseAsStream);
62+
options.ReadResponseAsStream,
63+
serviceProvider.GetService<ICorrelationIdProvider>());
6264
client.Name = clientName;
6365
return client;
6466
});
@@ -83,7 +85,9 @@ private static IDictionary<string, IHttpClientBuilder> UseSingleClient(this ISer
8385
serviceProvider.GetService<IHttpClientFactory>(),
8486
serializerFactory(serviceProvider),
8587
tokenProviderSupplier(clientName, configuration, serviceProvider),
86-
options.ReadResponseAsStream);
88+
options.ReadResponseAsStream,
89+
serviceProvider.GetService<ICorrelationIdProvider>());
90+
8791
client.Name = clientName;
8892
return client;
8993
});

commercetools.Sdk/commercetools.Base.Client/Middlewares/CorrelationIdMiddleware.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ public CorrelationIdMiddleware(ICorrelationIdProvider correlationIdProvider)
1515

1616
protected internal override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
1717
{
18-
var correlationId = this.correlationIdProvider.CorrelationId;
19-
request.Headers.Add("X-Correlation-ID", correlationId);
18+
if (!request.Headers.Contains(ApiHttpHeaders.X_CORRELATION_ID))
19+
{
20+
request.Headers.Add(ApiHttpHeaders.X_CORRELATION_ID, this.correlationIdProvider.CorrelationId);
21+
}
2022
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
2123
}
2224
}

0 commit comments

Comments
 (0)