Skip to content

Commit

Permalink
Migrating to V3 SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
ealsur committed Apr 6, 2021
1 parent a0fb201 commit 620e83f
Show file tree
Hide file tree
Showing 47 changed files with 1,476 additions and 1,738 deletions.
2 changes: 1 addition & 1 deletion build/common.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- Extensions can have independent versions and only increment when released -->
<Version>3.0.0$(VersionSuffix)</Version>
<ExtensionsVersion>4.0.3$(VersionSuffix)</ExtensionsVersion> <!-- WebJobs.Extensions -->
<CosmosDBVersion>3.0.10$(VersionSuffix)</CosmosDBVersion>
<CosmosDBVersion>4.0.0$(VersionSuffix)</CosmosDBVersion>
<HttpVersion>3.1.0$(VersionSuffix)</HttpVersion>
<MobileAppsVersion>3.0.0$(VersionSuffix)</MobileAppsVersion>
<SendGridVersion>3.0.1$(VersionSuffix)</SendGridVersion>
Expand Down
21 changes: 12 additions & 9 deletions src/ExtensionsSample/Samples/CosmosDBSamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ExtensionsSample.Models;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -73,19 +73,22 @@ public static void QueryDocument(
}

// DocumentClient input binding
//   The binding supplies a DocumentClient directly.
//   The binding supplies a CosmosClient directly.
[Disable]
public static void DocumentClient(
public static async Task CosmosClient(
[TimerTrigger("00:01", RunOnStartup = true)] TimerInfo timer,
[CosmosDB] DocumentClient client,
[CosmosDB] CosmosClient client,
TraceWriter log)
{
var collectionUri = UriFactory.CreateDocumentCollectionUri("ItemDb", "ItemCollection");
var documents = client.CreateDocumentQuery(collectionUri);
var iterator = client.GetContainer("ItemDb", "ItemCollection").GetItemQueryIterator<dynamic>("SELECT * FROM c");

foreach (Document d in documents)
while (iterator.HasMoreResults)
{
log.Info(d.Id);
var documents = await iterator.ReadNextAsync();
foreach (dynamic d in documents)
{
log.Info(d.id);
}
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/ExtensionsSample/Samples/CosmosDBTriggerSamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace ExtensionsSample
Expand Down Expand Up @@ -55,4 +55,10 @@ public static async Task ListenAndCopy(
}
}
}

public class Document
{
[JsonProperty("id")]
public string Id { get; set; }
}
}
29 changes: 10 additions & 19 deletions src/WebJobs.Extensions.CosmosDB/Bindings/CosmosDBAsyncCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Cosmos;
using Newtonsoft.Json.Linq;

namespace Microsoft.Azure.WebJobs.Extensions.CosmosDB
Expand All @@ -22,19 +21,20 @@ public CosmosDBAsyncCollector(CosmosDBContext docDBContext)

public async Task AddAsync(T item, CancellationToken cancellationToken = default(CancellationToken))
{
bool create = false;
try
{
await UpsertDocument(_docDBContext, item);
}
catch (Exception ex)
{
if (CosmosDBUtility.TryGetDocumentClientException(ex, out DocumentClientException de) &&
if (CosmosDBUtility.TryGetCosmosException(ex, out CosmosException de) &&
de.StatusCode == HttpStatusCode.NotFound)
{
if (_docDBContext.ResolvedAttribute.CreateIfNotExists)
{
create = true;
await CosmosDBUtility.CreateDatabaseAndCollectionIfNotExistAsync(_docDBContext);

await UpsertDocument(_docDBContext, item);
}
else
{
Expand All @@ -48,13 +48,6 @@ public CosmosDBAsyncCollector(CosmosDBContext docDBContext)
throw;
}
}

if (create)
{
await CosmosDBUtility.CreateDatabaseAndCollectionIfNotExistAsync(_docDBContext);

await UpsertDocument(_docDBContext, item);
}
}

public Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
Expand All @@ -63,18 +56,16 @@ public CosmosDBAsyncCollector(CosmosDBContext docDBContext)
return Task.FromResult(0);
}

internal static async Task UpsertDocument(CosmosDBContext context, T item)
internal static Task UpsertDocument(CosmosDBContext context, T item)
{
Uri collectionUri = UriFactory.CreateDocumentCollectionUri(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName);

// DocumentClient does not accept strings directly.
object convertedItem = item;
// Support user sending a string
if (item is string)
{
convertedItem = JObject.Parse(item.ToString());
JObject asJObject = JObject.Parse(item.ToString());
return context.Service.GetContainer(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName).UpsertItemAsync(asJObject);
}

await context.Service.UpsertDocumentAsync(collectionUri, convertedItem);
return context.Service.GetContainer(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName).UpsertItemAsync(item);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Cosmos;

namespace Microsoft.Azure.WebJobs.Extensions.CosmosDB.Bindings
{
internal class CosmosDBClientBuilder : IConverter<CosmosDBAttribute, DocumentClient>
internal class CosmosDBClientBuilder : IConverter<CosmosDBAttribute, CosmosClient>
{
private readonly CosmosDBExtensionConfigProvider _configProvider;

Expand All @@ -15,17 +15,17 @@ public CosmosDBClientBuilder(CosmosDBExtensionConfigProvider configProvider)
_configProvider = configProvider;
}

public DocumentClient Convert(CosmosDBAttribute attribute)
public CosmosClient Convert(CosmosDBAttribute attribute)
{
if (attribute == null)
{
throw new ArgumentNullException(nameof(attribute));
}

string resolvedConnectionString = _configProvider.ResolveConnectionString(attribute.ConnectionStringSetting);
ICosmosDBService service = _configProvider.GetService(resolvedConnectionString, attribute.PreferredLocations, attribute.UseMultipleWriteLocations, attribute.UseDefaultJsonSerialization);

return service.GetClient();
return _configProvider.GetService(
connectionString: resolvedConnectionString,
preferredLocations: attribute.PreferredLocations);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
// 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 System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Cosmos;

namespace Microsoft.Azure.WebJobs.Extensions.CosmosDB
{
Expand All @@ -24,28 +22,39 @@ public async Task<IEnumerable<T>> ConvertAsync(CosmosDBAttribute attribute, Canc
{
CosmosDBContext context = _configProvider.CreateContext(attribute);

Uri collectionUri = UriFactory.CreateDocumentCollectionUri(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName);

List<T> finalResults = new List<T>();

string continuation = null;
Container container = context.Service.GetContainer(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName);

SqlQuerySpec sqlSpec = new SqlQuerySpec
QueryDefinition queryDefinition = null;
if (!string.IsNullOrEmpty(attribute.SqlQuery))
{
QueryText = context.ResolvedAttribute.SqlQuery,
Parameters = context.ResolvedAttribute.SqlQueryParameters ?? new SqlParameterCollection()
};
queryDefinition = new QueryDefinition(attribute.SqlQuery);
if (attribute.SqlQueryParameters != null)
{
foreach (var parameter in attribute.SqlQueryParameters)
{
queryDefinition.WithParameter(parameter.Item1, parameter.Item2);
}
}
}

do
QueryRequestOptions queryRequestOptions = new QueryRequestOptions();
if (!string.IsNullOrEmpty(attribute.PartitionKey))
{
DocumentQueryResponse<T> response = await context.Service.ExecuteNextAsync<T>(collectionUri, sqlSpec, continuation);

finalResults.AddRange(response.Results);
continuation = response.ResponseContinuation;
queryRequestOptions.PartitionKey = new PartitionKey(attribute.PartitionKey);
}
while (!string.IsNullOrEmpty(continuation));

return finalResults;
using (FeedIterator<T> iterator = container.GetItemQueryIterator<T>(queryDefinition: queryDefinition, requestOptions: queryRequestOptions))
{
while (iterator.HasMoreResults)
{
FeedResponse<T> response = await iterator.ReadNextAsync(cancellationToken);
finalResults.AddRange(response.Resource);
}

return finalResults;
}
}
}
}
62 changes: 24 additions & 38 deletions src/WebJobs.Extensions.CosmosDB/Bindings/CosmosDBItemValueBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.WebJobs.Host.Bindings;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -41,48 +40,35 @@ public async Task SetValueAsync(object value, CancellationToken cancellationToke

public async Task<object> GetValueAsync()
{
Uri documentUri = UriFactory.CreateDocumentUri(_context.ResolvedAttribute.DatabaseName, _context.ResolvedAttribute.CollectionName, _context.ResolvedAttribute.Id);
RequestOptions options = null;
T document = default(T);

if (!string.IsNullOrEmpty(_context.ResolvedAttribute.PartitionKey))
{
options = new RequestOptions
{
PartitionKey = new PartitionKey(_context.ResolvedAttribute.PartitionKey)
};
}

Document document = null;

try
{
document = await _context.Service.ReadDocumentAsync(documentUri, options);
}
catch (DocumentClientException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
// ignore not found; we'll return null below
}

if (document == null)
{
return document;
}

T item = null;
PartitionKey partitionKey = _context.ResolvedAttribute.PartitionKey == null ? PartitionKey.None : new PartitionKey(_context.ResolvedAttribute.PartitionKey);

// Strings need to be handled differently.
if (typeof(T) == typeof(string))
if (typeof(T) != typeof(string))
{
_originalItem = JObject.FromObject(document);
item = _originalItem.ToString(Formatting.None) as T;
try
{
document = await _context.Service.GetContainer(_context.ResolvedAttribute.DatabaseName, _context.ResolvedAttribute.CollectionName)
.ReadItemAsync<T>(_context.ResolvedAttribute.Id, partitionKey);

_originalItem = JObject.FromObject(document);
}
catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
// ignore not found; we'll return null below
}
}
else
{
item = (T)(dynamic)document;
_originalItem = JObject.FromObject(item);
JObject jObject = await _context.Service.GetContainer(_context.ResolvedAttribute.DatabaseName, _context.ResolvedAttribute.CollectionName)
.ReadItemAsync<JObject>(_context.ResolvedAttribute.Id, partitionKey);
_originalItem = jObject;

document = _originalItem.ToString(Formatting.None) as T;
}

return item;
return document;
}

public string ToInvokeString()
Expand Down Expand Up @@ -111,7 +97,7 @@ internal static async Task SetValueInternalAsync(JObject originalItem, T newItem
// make sure it's not the Id that has changed
if (!string.Equals(originalId, currentId, StringComparison.Ordinal))
{
throw new InvalidOperationException("Cannot update the 'Id' property.");
throw new InvalidOperationException("Cannot update the 'id' property.");
}
}
else
Expand All @@ -121,8 +107,8 @@ internal static async Task SetValueInternalAsync(JObject originalItem, T newItem
throw new InvalidOperationException(string.Format("The document must have an 'id' property."));
}

Uri documentUri = UriFactory.CreateDocumentUri(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName, originalId);
await context.Service.ReplaceDocumentAsync(documentUri, newItem);
Container container = context.Service.GetContainer(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName);
await container.ReplaceItemAsync<T>(newItem, originalId);
}
}

Expand Down
40 changes: 0 additions & 40 deletions src/WebJobs.Extensions.CosmosDB/Config/CosmosDBConnectionString.cs

This file was deleted.

Loading

0 comments on commit 620e83f

Please sign in to comment.