Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enrich user-agent with runtime context #630

Merged
merged 12 commits into from
Aug 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,20 @@ public class CosmosClientOptions
private static readonly CosmosSerializer propertiesSerializer = new CosmosJsonSerializerWrapper(new CosmosJsonDotNetSerializer());

private readonly Collection<RequestHandler> customHandlers;
private readonly string currentEnvironmentInformation;

private int gatewayModeMaxConnectionLimit;
private string applicationName;

/// <summary>
/// Creates a new CosmosClientOptions
/// </summary>
public CosmosClientOptions()
{
this.UserAgentContainer = new UserAgentContainer();
EnvironmentInformation environmentInformation = new EnvironmentInformation();
this.currentEnvironmentInformation = environmentInformation.ToString();
this.UserAgentContainer.Suffix = this.currentEnvironmentInformation;
kirankumarkolli marked this conversation as resolved.
Show resolved Hide resolved
this.GatewayModeMaxConnectionLimit = ConnectionPolicy.Default.MaxConnectionLimit;
this.RequestTimeout = ConnectionPolicy.Default.RequestTimeout;
this.ConnectionMode = CosmosClientOptions.DefaultConnectionMode;
Expand All @@ -65,8 +70,12 @@ public CosmosClientOptions()
/// </remarks>
public string ApplicationName
{
get => this.UserAgentContainer.Suffix;
set => this.UserAgentContainer.Suffix = value;
get => this.applicationName;
set
{
this.UserAgentContainer.Suffix = this.currentEnvironmentInformation + EnvironmentInformation.Delimiter + value;
this.applicationName = value;
}
}

/// <summary>
Expand Down
54 changes: 54 additions & 0 deletions Microsoft.Azure.Cosmos/src/EnvironmentInformation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace Microsoft.Azure.Cosmos
{
using System;
using System.Reflection;
using System.Runtime.InteropServices;

internal sealed class EnvironmentInformation
{
internal const string Delimiter = " ";
private static readonly string clientId;
private static readonly string clientSDKVersion;
private static readonly string framework;
private static readonly string architecture;

static EnvironmentInformation()
ealsur marked this conversation as resolved.
Show resolved Hide resolved
{
Version sdkVersion = Assembly.GetAssembly(typeof(CosmosClient)).GetName().Version;
kirankumarkolli marked this conversation as resolved.
Show resolved Hide resolved
EnvironmentInformation.clientSDKVersion = $"{sdkVersion.Major}.{sdkVersion.Minor}.{sdkVersion.Build}";
EnvironmentInformation.framework = RuntimeInformation.FrameworkDescription;
EnvironmentInformation.architecture = RuntimeInformation.ProcessArchitecture.ToString();
EnvironmentInformation.clientId = DateTime.UtcNow.Ticks.ToString();
}

/// <summary>
/// Unique identifier of a client
/// </summary>
public string ClientId => EnvironmentInformation.clientId;

/// <summary>
/// Version of the current client.
/// </summary>
public string ClientVersion => EnvironmentInformation.clientSDKVersion;

/// <summary>
/// Identifier of the Framework.
/// </summary>
/// <seealso cref="RuntimeInformation.FrameworkDescription"/>
public string RuntimeFramework => EnvironmentInformation.framework;

/// <summary>
/// Type of architecture being used.
/// </summary>
/// <seealso cref="RuntimeInformation.ProcessArchitecture"/>
public string ProcessArchitecture => EnvironmentInformation.architecture;

public override string ToString()
{
return $" {this.ClientVersion}-{this.RuntimeFramework} {this.ProcessArchitecture} {this.ClientId}";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
Assert.AreEqual(Protocol.Https, policy.ConnectionProtocol);
Assert.AreEqual(maxConnections, policy.MaxConnectionLimit);
Assert.AreEqual(requestTimeout, policy.RequestTimeout);
Assert.AreEqual(userAgentSuffix, policy.UserAgentSuffix);
Assert.IsTrue(policy.UserAgentSuffix.Contains(userAgentSuffix));
Assert.IsTrue(policy.UseMultipleWriteLocations);
Assert.AreEqual(maxRetryAttemptsOnThrottledRequests, policy.RetryOptions.MaxRetryAttemptsOnThrottledRequests);
Assert.AreEqual((int)maxRetryWaitTime.TotalSeconds, policy.RetryOptions.MaxRetryWaitTimeInSeconds);
Expand All @@ -116,6 +116,23 @@ public void ThrowOnNullEndpoint()
new CosmosClientBuilder(null, "testKey");
}

[TestMethod]
public void UserAgentContainsEnvironmentInformation()
{
var environmentInformation = new EnvironmentInformation();
var expectedValue = environmentInformation.ToString();
CosmosClientOptions cosmosClientOptions = new CosmosClientOptions();
string userAgentSuffix = "testSuffix";
cosmosClientOptions.ApplicationName = userAgentSuffix;

Assert.IsTrue(cosmosClientOptions.UserAgentContainer.Suffix.EndsWith(userAgentSuffix));
Assert.IsTrue(cosmosClientOptions.UserAgentContainer.Suffix.Contains(expectedValue));

ConnectionPolicy connectionPolicy = cosmosClientOptions.GetConnectionPolicy();
Assert.IsTrue(connectionPolicy.UserAgentSuffix.EndsWith(userAgentSuffix));
Assert.IsTrue(connectionPolicy.UserAgentSuffix.Contains(expectedValue));
}

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ThrowOnNullConnectionString()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------

namespace Microsoft.Azure.Cosmos.Tests
{
using System;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class EnvironmentInformationTests
{
[TestMethod]
public void ClientVersionIsNotNull()
{
var envInfo = new EnvironmentInformation();
Assert.IsNotNull(envInfo.ClientVersion);
ealsur marked this conversation as resolved.
Show resolved Hide resolved

Version sdkVersion = Assembly.GetAssembly(typeof(CosmosClient)).GetName().Version;
Assert.AreEqual($"{sdkVersion.Major}.{sdkVersion.Minor}.{sdkVersion.Build}", envInfo.ClientVersion, "Version format differs");
}

[TestMethod]
public void ProcessArchitectureIsNotNull()
{
var envInfo = new EnvironmentInformation();
Assert.IsNotNull(envInfo.ProcessArchitecture);
}

[TestMethod]
public void FrameworkIsNotNull()
{
var envInfo = new EnvironmentInformation();
Assert.IsNotNull(envInfo.RuntimeFramework);
}

[TestMethod]
public void ClientIdIsNotNull()
{
var envInfo = new EnvironmentInformation();
Assert.IsNotNull(envInfo.ClientId);
}

[TestMethod]
public void ToStringContainsAll()
{
var envInfo = new EnvironmentInformation();
var serialization = envInfo.ToString();
Assert.IsTrue(serialization.Contains(envInfo.ClientVersion));
Assert.IsTrue(serialization.Contains(envInfo.ProcessArchitecture));
Assert.IsTrue(serialization.Contains(envInfo.RuntimeFramework));
Assert.IsTrue(serialization.Contains(envInfo.ClientId));
}
}
}
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#614](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/614) Fixed SpatialPath serialization and compatibility with older index versions
- [#626](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/626) FeedResponse<T> status code now return OK for success instead of the invalid status code 0 or Accepted
- [#629](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/629) Fixed CreateContainerIfNotExistsAsync validation to limited to partitionKeyPath only
- [#630](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/630) Fixed User Agent to contain environment and package information

## [3.1.0](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.1.0) - 2019-07-26

Expand Down