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

Implement CosmosDBOptions to allow configuration of the CosmosDB service client via CosmosClientOptions #2483

Merged
merged 9 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
19 changes: 15 additions & 4 deletions extensions/Worker.Extensions.CosmosDB/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,19 @@
- My change description (#PR/#issue)
-->

### Microsoft.Azure.Functions.Worker.Extensions.CosmosDB 4.8.1
### Microsoft.Azure.Functions.Worker.Extensions.CosmosDB 4.9.0

- Updating `Microsoft.Azure.WebJobs.Extensions.CosmosDB` reference to 4.6.1
- Updating `Microsoft.Extensions.Azure` reference to 1.7.3
- Updating `Microsoft.Azure.Cosmos` reference to 3.39.1
- Implement `CosmosDBExtensionOptions` to allow configuration of the CosmosDB service client via `CosmosClientOptions` (#2483)

#### Example Usage

```csharp
.ConfigureFunctionsWorkerDefaults((builder) =>
{
builder.ConfigureCosmosDBExtensionOptions((options) =>
{
options.ClientOptions.ConnectionMode = ConnectionMode.Direct;
options.ClientOptions.ApplicationName = "MyApp";
});
})
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@

namespace Microsoft.Azure.Functions.Worker
{
/// <summary>
/// Internal options for configuring the CosmosDB binding.
/// This class is used internally by the Azure Functions runtime to manage the CosmosDB connection and clients.
/// It is not intended to be used directly in user code.
/// Any public configuration options should be set on the <see cref="CosmosDBExtensionOptions"/> class, which is publicly accessible.
/// </summary>
internal class CosmosDBBindingOptions
{
public string? ConnectionName { get; set; }
Expand All @@ -21,6 +27,8 @@ internal class CosmosDBBindingOptions

public CosmosSerializer? Serializer { get; set; }

public CosmosDBExtensionOptions? CosmosExtensionOptions { get; set; }

internal string BuildCacheKey(string connection, string region) => $"{connection}|{region}";

internal ConcurrentDictionary<string, CosmosClient> ClientCache { get; } = new ConcurrentDictionary<string, CosmosClient>();
Expand All @@ -32,31 +40,33 @@ internal virtual CosmosClient GetClient(string preferredLocations = "")
throw new ArgumentNullException(nameof(ConnectionName));
}

string cacheKey = BuildCacheKey(ConnectionName!, preferredLocations);

CosmosClientOptions cosmosClientOptions = new ()
if (CosmosExtensionOptions is null)
{
ConnectionMode = ConnectionMode.Gateway
};
CosmosExtensionOptions = new CosmosDBExtensionOptions();
}

string cacheKey = BuildCacheKey(ConnectionName!, preferredLocations);

if (!string.IsNullOrEmpty(preferredLocations))
// Do not override if preferred locations is configured via CosmosClientOptions
if (!string.IsNullOrEmpty(preferredLocations) && CosmosExtensionOptions.ClientOptions.ApplicationPreferredRegions is null)
{
cosmosClientOptions.ApplicationPreferredRegions = Utilities.ParsePreferredLocations(preferredLocations);
CosmosExtensionOptions.ClientOptions.ApplicationPreferredRegions = Utilities.ParsePreferredLocations(preferredLocations);
liliankasem marked this conversation as resolved.
Show resolved Hide resolved
}

if (Serializer is not null)
// Do not override if the serializer is configured via CosmosClientOptions
if (Serializer is not null && CosmosExtensionOptions.ClientOptions.Serializer is null)
{
cosmosClientOptions.Serializer = Serializer;
CosmosExtensionOptions.ClientOptions.Serializer = Serializer;
liliankasem marked this conversation as resolved.
Show resolved Hide resolved
}

return ClientCache.GetOrAdd(cacheKey, (c) => CreateService(cosmosClientOptions));
return ClientCache.GetOrAdd(cacheKey, (c) => CreateService());
}

private CosmosClient CreateService(CosmosClientOptions cosmosClientOptions)
private CosmosClient CreateService()
{
return string.IsNullOrEmpty(ConnectionString)
? new CosmosClient(AccountEndpoint, Credential, cosmosClientOptions) // AAD auth
: new CosmosClient(ConnectionString, cosmosClientOptions); // Connection string based auth
? new CosmosClient(AccountEndpoint, Credential, CosmosExtensionOptions?.ClientOptions) // AAD auth
: new CosmosClient(ConnectionString, CosmosExtensionOptions?.ClientOptions); // Connection string based auth
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Functions.Worker.Extensions;
using Microsoft.Azure.Functions.Worker.Extensions.CosmosDB;
using Microsoft.Extensions.Azure;
Expand All @@ -15,12 +16,14 @@ internal class CosmosDBBindingOptionsSetup : IConfigureNamedOptions<CosmosDBBind
private readonly IConfiguration _configuration;
private readonly AzureComponentFactory _componentFactory;
private readonly IOptionsMonitor<WorkerOptions> _workerOptions;
private readonly IOptionsMonitor<CosmosDBExtensionOptions> _cosmosExtensionOptions;

public CosmosDBBindingOptionsSetup(IConfiguration configuration, AzureComponentFactory componentFactory, IOptionsMonitor<WorkerOptions> workerOptions)
public CosmosDBBindingOptionsSetup(IConfiguration configuration, AzureComponentFactory componentFactory, IOptionsMonitor<WorkerOptions> workerOptions, IOptionsMonitor<CosmosDBExtensionOptions> cosmosExtensionOptions)
{
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
_componentFactory = componentFactory ?? throw new ArgumentNullException(nameof(componentFactory));
_workerOptions = workerOptions ?? throw new ArgumentNullException(nameof(workerOptions));
_cosmosExtensionOptions = cosmosExtensionOptions ?? throw new ArgumentNullException(nameof(cosmosExtensionOptions));
}

public void Configure(CosmosDBBindingOptions options)
Expand Down Expand Up @@ -57,6 +60,7 @@ public void Configure(string connectionName, CosmosDBBindingOptions options)
}

options.Serializer = new WorkerCosmosSerializer(_workerOptions.CurrentValue.Serializer);
options.CosmosExtensionOptions = _cosmosExtensionOptions.CurrentValue;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using Microsoft.Azure.Cosmos;

namespace Microsoft.Azure.Functions.Worker
{
public class CosmosDBExtensionOptions
{
/// <summary>
/// Gets or sets the CosmosClientOptions.
/// </summary>
public CosmosClientOptions ClientOptions { get; set; } = new() { ConnectionMode = ConnectionMode.Gateway };
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using Microsoft.Azure.Cosmos;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
Expand Down Expand Up @@ -31,5 +33,17 @@ public static IFunctionsWorkerApplicationBuilder ConfigureCosmosDBExtension(this

return builder;
}

/// <summary>
/// Configures the CosmosDBExtensionOptions for the Functions Worker Cosmos extension.
/// </summary>
/// <param name="builder">The IFunctionsWorkerApplicationBuilder to add the configuration to.</param>
/// <param name="options">An Action to configure the CosmosDBExtensionOptions.</param>
/// <returns>The same instance of the <see cref="IFunctionsWorkerApplicationBuilder"/> for chaining.</returns>
public static IFunctionsWorkerApplicationBuilder ConfigureCosmosDBExtensionOptions(this IFunctionsWorkerApplicationBuilder builder, Action<CosmosDBExtensionOptions> options)
{
builder.Services.Configure(options);
return builder;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Description>Azure Cosmos DB extensions for .NET isolated functions</Description>

<!--Version information-->
<VersionPrefix>4.8.1</VersionPrefix>
<VersionPrefix>4.9.0</VersionPrefix>

<!--Temporarily opting out of documentation. Pending documentation-->
<GenerateDocumentationFile>false</GenerateDocumentationFile>
Expand Down
Loading