Skip to content

Commit

Permalink
Limit to endpoint feature (#814)
Browse files Browse the repository at this point in the history
* Adding property

* seealso

* Adding LimitToEndpoint

* contract update

* Builder test

* changelog

* The serializer was wrong

* Adding remarks
  • Loading branch information
ealsur authored and kirankumarkolli committed Sep 19, 2019
1 parent 4bcfc43 commit 952541a
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 1 deletion.
32 changes: 31 additions & 1 deletion Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,20 @@ public CosmosSerializer Serializer
}
}

/// <summary>
/// Limits the operations to the provided endpoint on the CosmosClient.
/// </summary>
/// <value>
/// Default value is false.
/// </value>
/// <remarks>
/// When the value of this property is false, the SDK will automatically discover write and read regions, and use them when the configured application region is not available.
/// When set to true, availability is limited to the endpoint specified on the CosmosClient constructor.
/// Defining the <see cref="ApplicationRegion"/> is not allowed when setting the value to true.
/// </remarks>
/// <seealso href="https://docs.microsoft.com/azure/cosmos-db/high-availability"/>
public bool LimitToEndpoint { get; set; } = false;

/// <summary>
/// Allows optimistic batching of requests to service. Setting this option might impact the latency of the operations. Hence this option is recommended for non-latency sensitive scenarios only.
/// </summary>
Expand Down Expand Up @@ -499,6 +513,7 @@ internal CosmosClientOptions Clone()
internal ConnectionPolicy GetConnectionPolicy()
{
this.ValidateDirectTCPSettings();
this.ValidateLimitToEndpointSettings();
ConnectionPolicy connectionPolicy = new ConnectionPolicy()
{
MaxConnectionLimit = this.GatewayModeMaxConnectionLimit,
Expand All @@ -510,7 +525,8 @@ internal ConnectionPolicy GetConnectionPolicy()
IdleTcpConnectionTimeout = this.IdleTcpConnectionTimeout,
OpenTcpConnectionTimeout = this.OpenTcpConnectionTimeout,
MaxRequestsPerTcpConnection = this.MaxRequestsPerTcpConnection,
MaxTcpConnectionsPerEndpoint = this.MaxTcpConnectionsPerEndpoint
MaxTcpConnectionsPerEndpoint = this.MaxTcpConnectionsPerEndpoint,
EnableEndpointDiscovery = !this.LimitToEndpoint
};

if (this.ApplicationRegion != null)
Expand Down Expand Up @@ -609,6 +625,14 @@ private static string GetValueFromConnectionString(string connectionString, stri
throw new ArgumentException("The connection string is missing a required property: " + keyName);
}

private void ValidateLimitToEndpointSettings()
{
if (!string.IsNullOrEmpty(this.ApplicationRegion) && this.LimitToEndpoint)
{
throw new ArgumentException($"Cannot specify {nameof(this.ApplicationRegion)} and enable {nameof(this.LimitToEndpoint)}. Only one can be set.");
}
}

private void ValidateDirectTCPSettings()
{
string settingName = string.Empty;
Expand Down Expand Up @@ -666,6 +690,12 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
{
writer.WriteValue(cosmosJsonSerializerWrapper.InternalJsonSerializer.GetType().ToString());
}

CosmosSerializer cosmosSerializer = value as CosmosSerializer;
if (cosmosSerializer is CosmosSerializer)
{
writer.WriteValue(cosmosSerializer.GetType().ToString());
}
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
Expand Down
30 changes: 30 additions & 0 deletions Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,36 @@ public CosmosClientBuilder WithApplicationRegion(string applicationRegion)
return this;
}

/// <summary>
/// Limits the operations to the provided endpoint on the CosmosClientBuilder constructor.
/// </summary>
/// <param name="limitToEndpoint">Whether operations are limited to the endpoint or not.</param>
/// <value>Default value is false.</value>
/// <remarks>
/// When the value of <paramref name="limitToEndpoint"/> is false, the SDK will automatically discover all account write and read regions, and use them when the configured application region is not available.
/// When set to true, availability is limited to the endpoint specified on the CosmosClientBuilder constructor.
/// Using <see cref="WithApplicationRegion(string)"/> is not allowed when the value is true. </remarks>
/// <example>
/// The example below creates a new <see cref="CosmosClientBuilder"/> to limit the endpoint to East US.
/// <code language="c#">
/// <![CDATA[
/// CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder(
/// accountEndpoint: "https://testcosmos-eastus.documents.azure.com:443/",
/// authKeyOrResourceToken: "SuperSecretKey")
/// .WithLimitToEndpoint(true);
/// CosmosClient client = cosmosClientBuilder.Build();
/// ]]>
/// </code>
/// </example>
/// <returns>The current <see cref="CosmosClientBuilder"/>.</returns>
/// <seealso href="https://docs.microsoft.com/azure/cosmos-db/high-availability"/>
/// <seealso cref="CosmosClientOptions.LimitToEndpoint"/>
public CosmosClientBuilder WithLimitToEndpoint(bool limitToEndpoint)
{
this.clientOptions.LimitToEndpoint = limitToEndpoint;
return this;
}

/// <summary>
/// Sets the request timeout in seconds when connecting to the Azure Cosmos DB service.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
Assert.IsNull(clientOptions.SerializerOptions);
Assert.IsNull(clientOptions.Serializer);
Assert.IsNull(clientOptions.WebProxy);
Assert.IsFalse(clientOptions.LimitToEndpoint);

//Verify GetConnectionPolicy returns the correct values for default
ConnectionPolicy policy = clientOptions.GetConnectionPolicy();
Expand All @@ -79,6 +80,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
Assert.IsNull(policy.OpenTcpConnectionTimeout);
Assert.IsNull(policy.MaxRequestsPerTcpConnection);
Assert.IsNull(policy.MaxTcpConnectionsPerEndpoint);
Assert.IsTrue(policy.EnableEndpointDiscovery);

cosmosClientBuilder.WithApplicationRegion(region)
.WithConnectionModeGateway(maxConnections, webProxy)
Expand Down Expand Up @@ -372,6 +374,37 @@ public void VerifyCorrectProtocolIsSet()
Assert.AreEqual(Protocol.Tcp, cosmosClientOptions.ConnectionProtocol);
}

[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void VerifyLimitToEndpointSettings()
{
CosmosClientOptions cosmosClientOptions = new CosmosClientOptions { ApplicationRegion = LocationNames.EastUS, LimitToEndpoint = true };
cosmosClientOptions.GetConnectionPolicy();
}

[TestMethod]
public void WithLimitToEndpointAffectsEndpointDiscovery()
{
CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder(
accountEndpoint: AccountEndpoint,
authKeyOrResourceToken: Guid.NewGuid().ToString());

CosmosClientOptions cosmosClientOptions = cosmosClientBuilder.Build(new MockDocumentClient()).ClientOptions;
Assert.IsFalse(cosmosClientOptions.LimitToEndpoint);

ConnectionPolicy connectionPolicy = cosmosClientOptions.GetConnectionPolicy();
Assert.IsTrue(connectionPolicy.EnableEndpointDiscovery);

cosmosClientBuilder
.WithLimitToEndpoint(true);

cosmosClientOptions = cosmosClientBuilder.Build(new MockDocumentClient()).ClientOptions;
Assert.IsTrue(cosmosClientOptions.LimitToEndpoint);

connectionPolicy = cosmosClientOptions.GetConnectionPolicy();
Assert.IsFalse(connectionPolicy.EnableEndpointDiscovery);
}

private class TestWebProxy : IWebProxy
{
public ICredentials Credentials { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,18 @@
"CosmosClientOptions": {
"Subclasses": {},
"Members": {
"Boolean get_LimitToEndpoint()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": {
"Type": "Method",
"Attributes": [
"CompilerGeneratedAttribute"
],
"MethodInfo": "Boolean get_LimitToEndpoint()"
},
"Boolean LimitToEndpoint": {
"Type": "Property",
"Attributes": [],
"MethodInfo": null
},
"Int32 GatewayModeMaxConnectionLimit": {
"Type": "Property",
"Attributes": [],
Expand Down Expand Up @@ -1454,6 +1466,13 @@
"Attributes": [],
"MethodInfo": "Void set_IdleTcpConnectionTimeout(System.Nullable`1[System.TimeSpan])"
},
"Void set_LimitToEndpoint(Boolean)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": {
"Type": "Method",
"Attributes": [
"CompilerGeneratedAttribute"
],
"MethodInfo": "Void set_LimitToEndpoint(Boolean)"
},
"Void set_MaxRequestsPerTcpConnection(System.Nullable`1[System.Int32])": {
"Type": "Method",
"Attributes": [],
Expand Down Expand Up @@ -2367,6 +2386,11 @@
"Attributes": [],
"MethodInfo": "Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithCustomSerializer(Microsoft.Azure.Cosmos.CosmosSerializer)"
},
"Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithLimitToEndpoint(Boolean)": {
"Type": "Method",
"Attributes": [],
"MethodInfo": "Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithLimitToEndpoint(Boolean)"
},
"Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithRequestTimeout(System.TimeSpan)": {
"Type": "Method",
"Attributes": [],
Expand Down
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- [#814](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/814) Ability to limit to configured endpoint only
- [#822](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/822) GROUP BY query support.

## <a name="3.2.0"/> [3.2.0](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.2.0) - 2019-09-17
Expand Down

0 comments on commit 952541a

Please sign in to comment.