Skip to content

Commit

Permalink
feat: client identification headers (#271)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tymek authored Jan 29, 2025
1 parent a36507d commit e66372c
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/Unleash/Communication/UnleashApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,21 @@ private static void SetRequestHeaders(HttpRequestMessage requestMessage, Unleash
const string userAgentHeader = "User-Agent";
const string instanceIdHeader = "UNLEASH-INSTANCEID";

const string identifyConnectionHeader = "x-unleash-connection-id";
const string identifyAppNameHeader = "x-unleash-appname";
const string identifySdkHeader = "x-unleash-sdk";

const string supportedSpecVersionHeader = "Unleash-Client-Spec";

requestMessage.Headers.TryAddWithoutValidation(appNameHeader, headers.AppName);
requestMessage.Headers.TryAddWithoutValidation(userAgentHeader, headers.AppName);
requestMessage.Headers.TryAddWithoutValidation(instanceIdHeader, headers.InstanceTag);
requestMessage.Headers.TryAddWithoutValidation(supportedSpecVersionHeader, headers.SupportedSpecVersion);

requestMessage.Headers.TryAddWithoutValidation(identifyConnectionHeader, headers.ConnectionId);
requestMessage.Headers.TryAddWithoutValidation(identifyAppNameHeader, headers.AppName);
requestMessage.Headers.TryAddWithoutValidation(identifySdkHeader, headers.SdkVersion);

SetCustomHeaders(requestMessage, headers.CustomHttpHeaders);
SetCustomHeaders(requestMessage, headers.CustomHttpHeaderProvider?.CustomHeaders);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Unleash/Communication/UnleashApiClientRequestHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ internal class UnleashApiClientRequestHeaders
{
public string AppName { get; set; }
public string InstanceTag { get; set; }
public string ConnectionId { get; internal set; }
public string SdkVersion { get; set; }
public Dictionary<string, string> CustomHttpHeaders { get; set; }
public IUnleashCustomHttpHeaderProvider CustomHttpHeaderProvider { get; set; }
public string SupportedSpecVersion { get; internal set; }
Expand Down
3 changes: 3 additions & 0 deletions src/Unleash/Internal/UnleashServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ internal class UnleashServices : IDisposable
private static readonly ILog Logger = LogProvider.GetLogger(typeof(UnleashServices));
private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
private readonly IUnleashScheduledTaskManager scheduledTaskManager;
private readonly string connectionId = Guid.NewGuid().ToString();

public const string supportedSpecVersion = "5.1.9";

Expand Down Expand Up @@ -84,6 +85,8 @@ public UnleashServices(UnleashSettings settings, EventCallbackConfig eventConfig
{
AppName = settings.AppName,
InstanceTag = settings.InstanceTag,
ConnectionId = connectionId,
SdkVersion = settings.SdkVersion,
CustomHttpHeaders = settings.CustomHttpHeaders,
CustomHttpHeaderProvider = settings.UnleashCustomHttpHeaderProvider,
SupportedSpecVersion = supportedSpecVersion
Expand Down
2 changes: 1 addition & 1 deletion src/Unleash/UnleashSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private static string GetSdkVersion()
var assemblyName = Assembly.GetExecutingAssembly().GetName();
var version = assemblyName.Version.ToString(3);

return $"unleash-client-dotnet:v{version}";
return $"unleash-client-dotnet:{version}";
}

private static string GetDefaultInstanceTag()
Expand Down
28 changes: 28 additions & 0 deletions tests/Unleash.Tests/Communication/CustomHeadersUnitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ private IUnleashApiClient CreateApiClient()
{
AppName = "api-test-client",
InstanceTag = "instance1",
ConnectionId = "00000000-0000-4000-a000-000000000000",
SdkVersion = "unleash-client-mock:0.0.0",
CustomHttpHeaders = httpHeaders,
CustomHttpHeaderProvider = httpHeadersProvider
};
Expand Down Expand Up @@ -133,5 +135,31 @@ public async Task DynamicHttpHeaders()
}
}

[Test]
public async Task IdentificationHttpHeaders()
{
api = CreateApiClient();
var engine = new YggdrasilEngine();

var etag = "";
await api.FetchToggles(etag, CancellationToken.None);
await api.RegisterClient(new Unleash.Metrics.ClientRegistration(), CancellationToken.None);
await api.SendMetrics(engine.GetMetrics(), CancellationToken.None);

messageHandler.calls.Count.Should().Be(3);
foreach (var call in messageHandler.calls)
{
call.Headers.Should().ContainEquivalentOf(
new KeyValuePair<string, IEnumerable<string>>("x-unleash-connection-id", new string[] { "00000000-0000-4000-a000-000000000000" })
);
call.Headers.Should().ContainEquivalentOf(
new KeyValuePair<string, IEnumerable<string>>("x-unleash-appname", new string[] { "api-test-client" })
);
call.Headers.Should().ContainEquivalentOf(
new KeyValuePair<string, IEnumerable<string>>("x-unleash-sdk", new string[] { "unleash-client-mock:0.0.0" })
);
}
}

}
}
2 changes: 2 additions & 0 deletions tests/Unleash.Tests/Communication/MockHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ internal static Tuple<MockHttpMessageHandler, UnleashApiClient> MakeMockClient(s
var requestHeaders = new UnleashApiClientRequestHeaders
{
AppName = "api-test-client",
ConnectionId = "00000000-0000-4000-a000-000000000000",
SdkVersion = "unleash-client-mock:0.0.0",
CustomHttpHeaders = new Dictionary<string, string>()
{
{ "Authorization", "*:default.some-mock-hash" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ private UnleashApiClient NewTestableClient(string project, MockHttpMessageHandle
{
AppName = "api-test-client",
InstanceTag = "instance1",
ConnectionId = "00000000-0000-4000-a000-000000000000",
SdkVersion = "unleash-client-mock:0.0.0",
CustomHttpHeaders = null,
CustomHttpHeaderProvider = null
};
Expand Down
3 changes: 2 additions & 1 deletion tests/Unleash.Tests/UnleashSettingsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public void Should_set_sdk_name()
var settings = new UnleashSettings();

// Assert
settings.SdkVersion.Should().StartWith("unleash-client-dotnet:v");
settings.SdkVersion.Should().StartWith("unleash-client-dotnet:");
settings.SdkVersion.Should().MatchRegex(@":\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$");
}
}
}

0 comments on commit e66372c

Please sign in to comment.