Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Commit

Permalink
feat: Adds support for application tags. (#192)
Browse files Browse the repository at this point in the history
**Requirements**

- [x] I have added test coverage for new or changed functionality
- [x] I have followed the repository's [pull request submission
guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests)
- [ ] I have validated my changes against all supported platform
versions

**Related issues**


https://app.shortcut.com/launchdarkly/story/183476/net-client-sdk-add-support-for-tags

**Describe the solution you've provided**

Adds ApplicationInfo support to the ConfigurationBuilder for providing
ApplicationInfo to the SDK. Updated LDClientContext to hold an
environment reporter and also updated HttpProperties creation to utilize
the application info in forming the request headers.
  • Loading branch information
tanderson-ld authored Oct 9, 2023
2 parents a652285 + 6c46cd7 commit b0c539e
Show file tree
Hide file tree
Showing 16 changed files with 318 additions and 169 deletions.
1 change: 0 additions & 1 deletion .circleci/scripts/macos-install-android-sdk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ unzip android-sdk.zip
mv cmdline-tools $ANDROID_HOME/cmdline-tools/latest

sdkmanager_args="platform-tools emulator"
sdkmanager_args="$sdkmanager_args extras;intel;Hardware_Accelerated_Execution_Manager"
sdkmanager_args="$sdkmanager_args build-tools;$ANDROID_BUILD_TOOLS_VERSION"
for apiver in "$@"; do
sdkmanager_args="$sdkmanager_args platforms;android-$apiver"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Thumbs.db
# resharper
*_Resharper.*
*.Resharper
.idea

# dotCover
*.dotCover
Expand Down
9 changes: 9 additions & 0 deletions contract-tests/Representations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class SdkConfigParams
public SdkConfigEventParams Events { get; set; }
public SdkConfigServiceEndpointsParams ServiceEndpoints { get; set; }
public SdkClientSideParams ClientSide { get; set; }
public SdkConfigTagsParams Tags { get; set; }
}

public class SdkConfigStreamParams
Expand Down Expand Up @@ -62,6 +63,14 @@ public class SdkConfigServiceEndpointsParams
public Uri Events { get; set; }
}

public class SdkConfigTagsParams
{
public string ApplicationId { get; set; }
public string ApplicationName { get; set; }
public string ApplicationVersion { get; set; }
public string ApplicationVersionName { get; set; }
}

public class SdkClientSideParams
{
public bool? EvaluationReasons { get; set; }
Expand Down
12 changes: 11 additions & 1 deletion contract-tests/SdkClientEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ string tag
throw new Exception("Client initialization failed");
}
}

public void Close()
{
_client.Dispose();
Expand Down Expand Up @@ -288,6 +288,16 @@ private static Configuration BuildSdkConfig(SdkConfigParams sdkParams, ILogAdapt
}
}

if (sdkParams.Tags != null)
{
var applicationInfo = Components.ApplicationInfo();
applicationInfo.ApplicationId(sdkParams.Tags.ApplicationId);
applicationInfo.ApplicationName(sdkParams.Tags.ApplicationName);
applicationInfo.ApplicationVersion(sdkParams.Tags.ApplicationVersion);
applicationInfo.ApplicationVersionName(sdkParams.Tags.ApplicationVersionName);
builder.ApplicationInfo(applicationInfo);
}

var streamingParams = sdkParams.Streaming;
var pollingParams = sdkParams.Polling;
if (streamingParams != null)
Expand Down
3 changes: 2 additions & 1 deletion contract-tests/TestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public class Webapp
"service-endpoints",
"singleton",
"strongly-typed",
"user-type"
"user-type",
"tags"
};

public readonly Handler Handler;
Expand Down
21 changes: 21 additions & 0 deletions src/LaunchDarkly.ClientSdk/Components.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,27 @@ public static PollingDataSourceBuilder PollingDataSource() =>
/// <returns>a configuration builder</returns>
/// <seealso cref="ConfigurationBuilder.ServiceEndpoints(ServiceEndpointsBuilder)" />
public static ServiceEndpointsBuilder ServiceEndpoints() => new ServiceEndpointsBuilder();

/// <summary>
/// Returns a configurable builder for the SDK's application metadata.
/// </summary>
/// <remarks>
/// <para>
/// Passing this to <see cref="ConfigurationBuilder.ApplicationInfo"/> after setting any desired properties on the builder,
/// applies this configuration to the SDK.
/// </para>
/// </remarks>
/// <example>
/// <code>
/// var config = Configuration.Builder(mobileKey)
/// .ApplicationInfo(
/// Components.ApplicationInfo().ApplicationID("MyApplication").ApplicationVersion("version123abc")
/// )
/// .Build();
/// </code>
/// </example>
/// <returns>a configuration builder</returns>
public static ApplicationInfoBuilder ApplicationInfo() => new ApplicationInfoBuilder();

/// <summary>
/// Returns a configurable factory for using streaming mode to get feature flag data.
Expand Down
7 changes: 6 additions & 1 deletion src/LaunchDarkly.ClientSdk/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ public sealed class Configuration
/// <seealso cref="ConfigurationBuilder.ServiceEndpoints(ServiceEndpointsBuilder)"/>
public ServiceEndpoints ServiceEndpoints { get; }

/// <summary>
/// ApplicationInfo configuration which contains info about the application the SDK is running in.
/// </summary>
public ApplicationInfoBuilder ApplicationInfo { get; }

/// <summary>
/// Creates a configuration with all parameters set to the default.
/// </summary>
Expand Down Expand Up @@ -180,7 +185,7 @@ internal Configuration(ConfigurationBuilder builder)
Offline = builder._offline;
PersistenceConfigurationBuilder = builder._persistenceConfigurationBuilder;
ServiceEndpoints = (builder._serviceEndpointsBuilder ?? Components.ServiceEndpoints()).Build();

ApplicationInfo = builder._applicationInfo;
BackgroundModeManager = builder._backgroundModeManager;
ConnectivityStateManager = builder._connectivityStateManager;
}
Expand Down
15 changes: 15 additions & 0 deletions src/LaunchDarkly.ClientSdk/ConfigurationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public sealed class ConfigurationBuilder
// will replace it with a platform-specific implementation.
internal static readonly HttpMessageHandler DefaultHttpMessageHandlerInstance = new HttpClientHandler();

internal ApplicationInfoBuilder _applicationInfo;
internal IComponentConfigurer<IDataSource> _dataSource = null;
internal bool _diagnosticOptOut = false;
internal bool _enableBackgroundUpdating = true;
Expand Down Expand Up @@ -65,6 +66,7 @@ internal ConfigurationBuilder(Configuration copyFrom)
_offline = copyFrom.Offline;
_persistenceConfigurationBuilder = copyFrom.PersistenceConfigurationBuilder;
_serviceEndpointsBuilder = new ServiceEndpointsBuilder(copyFrom.ServiceEndpoints);
_applicationInfo = copyFrom.ApplicationInfo;
}

/// <summary>
Expand All @@ -76,6 +78,19 @@ public Configuration Build()
{
return new Configuration(this);
}

/// <summary>
/// Sets the SDK's application metadata, which may be used in the LaunchDarkly analytics or other product
/// features. This object is normally a configuration builder obtained from <see cref="Components.ApplicationInfo"/>,
/// which has methods for setting individual metadata properties.
/// </summary>
/// <param name="applicationInfo">builder for <see cref="ApplicationInfo"/></param>
/// <returns>the same builder</returns>
public ConfigurationBuilder ApplicationInfo(ApplicationInfoBuilder applicationInfo)
{
_applicationInfo = applicationInfo;
return this;
}

/// <summary>
/// Sets the implementation of the component that receives feature flag data from LaunchDarkly,
Expand Down
25 changes: 14 additions & 11 deletions src/LaunchDarkly.ClientSdk/Integrations/HttpConfigurationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using LaunchDarkly.Sdk.Client.Internal;
using LaunchDarkly.Sdk.Internal;
using LaunchDarkly.Sdk.Internal.Http;
using LaunchDarkly.Sdk.Client.Subsystems;
Expand Down Expand Up @@ -136,14 +137,14 @@ public HttpConfigurationBuilder MessageHandler(HttpMessageHandler messageHandler
/// <example>
/// <code>
/// // Example of using an HTTP proxy with basic authentication
///
///
/// var proxyUri = new Uri("http://my-proxy-host:8080");
/// var proxy = new System.Net.WebProxy(proxyUri);
/// var credentials = new System.Net.CredentialCache();
/// credentials.Add(proxyUri, "Basic",
/// new System.Net.NetworkCredential("username", "password"));
/// proxy.Credentials = credentials;
///
///
/// var config = Configuration.Builder("my-sdk-key")
/// .Http(
/// Components.HttpConfiguration().Proxy(proxy)
Expand Down Expand Up @@ -233,11 +234,12 @@ public HttpConfigurationBuilder Wrapper(string wrapperName, string wrapperVersio
/// Called internally by the SDK to create an implementation instance. Applications do not need
/// to call this method.
/// </summary>
/// <param name="context">provides SDK configuration data</param>
/// <param name="authKey">Key for authenticating with LD service</param>
/// <param name="applicationInfo">Application Info for this application environment</param>
/// <returns>an <see cref="HttpConfiguration"/></returns>
public HttpConfiguration CreateHttpConfiguration(LdClientContext context) =>
public HttpConfiguration CreateHttpConfiguration(string authKey, ApplicationInfo applicationInfo) =>
new HttpConfiguration(
MakeHttpProperties(context),
MakeHttpProperties(authKey, applicationInfo),
_messageHandler,
_responseStartTimeout,
_useReport
Expand All @@ -246,14 +248,14 @@ public HttpConfiguration CreateHttpConfiguration(LdClientContext context) =>
/// <inheritdoc/>
public LdValue DescribeConfiguration(LdClientContext context) =>
LdValue.BuildObject()
.WithHttpProperties(MakeHttpProperties(context))
.WithHttpProperties(MakeHttpProperties(context.MobileKey, context.EnvironmentReporter.ApplicationInfo))
.Add("useReport", _useReport)
.Set("socketTimeoutMillis", _responseStartTimeout.TotalMilliseconds)
// WithHttpProperties normally sets socketTimeoutMillis to the ReadTimeout value,
// which is more correct, but we can't really set ReadTimeout in this SDK
// WithHttpProperties normally sets socketTimeoutMillis to the ReadTimeout value,
// which is more correct, but we can't really set ReadTimeout in this SDK
.Build();

private HttpProperties MakeHttpProperties(LdClientContext context)
private HttpProperties MakeHttpProperties(string authToken, ApplicationInfo applicationInfo)
{
Func<HttpProperties, HttpMessageHandler> handlerFn;
if (_messageHandler is null)
Expand All @@ -266,11 +268,12 @@ private HttpProperties MakeHttpProperties(LdClientContext context)
}

var httpProperties = HttpProperties.Default
.WithAuthorizationKey(context.MobileKey)
.WithAuthorizationKey(authToken)
.WithConnectTimeout(_connectTimeout)
.WithHttpMessageHandlerFactory(handlerFn)
.WithProxy(_proxy)
.WithUserAgent("XamarinClient/" + AssemblyVersions.GetAssemblyVersionStringForType(typeof(LdClient)))
.WithUserAgent(SdkPackage.UserAgent)
.WithApplicationTags(applicationInfo)
.WithWrapper(_wrapperName, _wrapperVersion);

foreach (var kv in _customHeaders)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using LaunchDarkly.Sdk.Client.Subsystems;
using LaunchDarkly.Sdk.Internal.Events;
using LaunchDarkly.Sdk.Internal.Http;
using LaunchDarkly.Sdk.Client.Subsystems;

using static LaunchDarkly.Sdk.Internal.Events.DiagnosticConfigProperties;

namespace LaunchDarkly.Sdk.Client.Internal.Events
{
Expand All @@ -15,7 +13,7 @@ internal class ClientDiagnosticStore : DiagnosticStoreBase
private readonly TimeSpan _startWaitTime;

protected override string SdkKeyOrMobileKey => _context.MobileKey;
protected override string SdkName => "dotnet-client-sdk";
protected override string SdkName => SdkPackage.Name;
protected override IEnumerable<LdValue> ConfigProperties => GetConfigProperties();
protected override string DotNetTargetFramework => GetDotNetTargetFramework();
protected override HttpProperties HttpProperties => _context.Http.HttpProperties;
Expand Down
34 changes: 34 additions & 0 deletions src/LaunchDarkly.ClientSdk/Internal/SdkPackage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using LaunchDarkly.Sdk.Internal;

namespace LaunchDarkly.Sdk.Client.Internal
{

/// <summary>
/// Defines common information about the SDK itself for usage
/// in various components.
/// </summary>
internal static class SdkPackage
{
/// <summary>
/// The canonical name of this SDK, following the convention of (technology)-(server|client)-sdk.
/// </summary>
internal const string Name = "dotnet-client-sdk";

/// <summary>
/// The prefix for the User-Agent header, omitting the version string. This may be different than the Name
/// due to historical reasons.
/// </summary>
private const string UserAgentPrefix = "XamarinClient";

/// <summary>
/// Version of the SDK.
/// </summary>
internal static string Version => AssemblyVersions.GetAssemblyVersionStringForType(typeof(LdClient));

/// <summary>
/// User-Agent suitable for usage in HTTP requests.
/// </summary>
internal static string UserAgent => $"{UserAgentPrefix}/{Version}";

}
}
6 changes: 3 additions & 3 deletions src/LaunchDarkly.ClientSdk/LaunchDarkly.ClientSdk.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<RootNamespace>LaunchDarkly.Sdk.Client</RootNamespace>

<!-- fail if XML comments are missing or invalid -->
<WarningsAsErrors>1570,1571,1572,1573,1574,1580,1581,1584,1591,1710,1711,1712</WarningsAsErrors>
</PropertyGroup>
Expand All @@ -37,9 +37,9 @@
<Folder Include="Properties\" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Include="System.Text.Json" Version="6.0.0" />
<PackageReference Include="LaunchDarkly.CommonSdk" Version="6.0.1" />
<PackageReference Include="LaunchDarkly.CommonSdk" Version="6.1.0-alpha.2" />
<PackageReference Include="LaunchDarkly.EventSource" Version="5.0.1" />
<PackageReference Include="LaunchDarkly.InternalSdk" Version="3.1.1" />
<PackageReference Include="LaunchDarkly.InternalSdk" Version="3.2.0-alpha.2" />
<PackageReference Include="LaunchDarkly.Logging" Version="2.0.0" />
<Compile Include="**\*.cs" Exclude="PlatformSpecific\*.cs;bin\**\*.cs;obj\**\*.cs" />
<Compile Include="PlatformSpecific\*.shared.cs" />
Expand Down
Loading

0 comments on commit b0c539e

Please sign in to comment.