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

CosmosDB Trigger support #1677

Merged
merged 1 commit into from
Jul 28, 2017
Merged

CosmosDB Trigger support #1677

merged 1 commit into from
Jul 28, 2017

Conversation

ealsur
Copy link
Member

@ealsur ealsur commented Jul 13, 2017

Starting the CosmosDB trigger integration following PR: Azure/azure-webjobs-sdk-extensions#244 to integrate with Azure Functions Script Host.

Working on adding E2E tests.

@dnfclas
Copy link

dnfclas commented Jul 13, 2017

@ealsur,
Thanks for having already signed the Contribution License Agreement. Your agreement was validated by .NET Foundation. We will now review your pull request.
Thanks,
.NET Foundation Pull Request Bot

@fabiocav
Copy link
Member

Thank you! Will take a look ASAP!

I've flagged your PR in the extensions repo so we can get a full CI build. Once that is merged, I'll push the new package to the MyGet feed to allow the CI tests to run as expected here.

@fabiocav fabiocav requested review from brettsam, fabiocav and mamaso July 13, 2017 19:24

if (!string.IsNullOrEmpty(leaseCollectionName))
{
attributeTrigger.LeaseCollectionName = leaseCollectionName;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does this work if not all of these lease properties are set?

Also, it might be preferable to bundle all these lease properties in one object, i.e.

{
  "type": "documentDbTrigger",
  "connection": ...
  "lease": {
    "collection": ...,
    "database": ...,
    "connection": ...,
    "options": { ... }
  }
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mamaso By default, if no lease properties are set, the Lease database is the same as the databaseName attribute, the Lease colletion defaults to "leases" and the connection string is the same as the connection attribute. So it uses the same service, same database but different collection. We are also checking that an infinite loop is not created where both collections are the same.

I will rework the properties of the leases in a nested object in the next commit 😄

Copy link
Member

@fabiocav fabiocav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good! Just a question about the package version, as that may be problematic.

<Reference Include="Microsoft.Azure.Documents.ChangeFeedProcessor, Version=1.14.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.ChangeFeedProcessor.1.0.0\lib\net45\Microsoft.Azure.Documents.ChangeFeedProcessor.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Documents.Client, Version=1.13.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the document client package version update required? This would change the version customers get with the `#r "Microsoft.Azure.Documents.Client" directive

Copy link
Member Author

@ealsur ealsur Jul 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabiocav Yes. The Change Feed API support within the SDK was introduced in version 1.13.1, that's the minimum version required and the one we are using, basically the restriction is >= 1.13.1 for Change Feed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabiocav -- the version change is why we held off on getting this into Extensions in the last release. Ultimately, we'll need to move it forward but need to make sure the redirect is updated. There shouldn't be any breaking changes -- but we'll need to monitor the rollout to see if we get any error spikes.

@ealsur ealsur changed the title DocumentDB Trigger support CosmosDB Trigger support Jul 20, 2017
using System;
public static void Run(IReadOnlyList<Document> input)
{
Console.WriteLine("Documents modified " + input.Count);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Console.WriteLine doesn't work from a function -- add a parameter ILogger logger and do a logger.LogInformation("") instead. That'll send the log to the file logs, App Inisights, etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is TraceWriter ok too?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, either works. ILogger is our newer logger.

<Reference Include="Microsoft.Azure.Documents.ChangeFeedProcessor, Version=1.14.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.ChangeFeedProcessor.1.0.0\lib\net45\Microsoft.Azure.Documents.ChangeFeedProcessor.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Documents.Client, Version=1.13.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabiocav -- the version change is why we held off on getting this into Extensions in the last release. Ultimately, we'll need to move it forward but need to make sure the redirect is updated. There shouldn't be any breaking changes -- but we'll need to monitor the rollout to see if we get any error spikes.

Config.UseDocumentDB();
DocumentDBConfiguration documentDBConfiguration = new DocumentDBConfiguration();

JObject configSection = (JObject)Metadata.GetValue("documentDB", StringComparison.OrdinalIgnoreCase);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're getting into a little of the weirdness of the "CosmosDB" vs "DocumentDB" naming conventions here. This global host.json setting isn't strictly required, is it? The lease options can be set in function.json for each function, if needed. I wonder if we just leave this off to keep things simpler and we can always re-add it in the future.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were talking with Paul to do a renaming sometime in the future to CosmosDB in everything, but it would be a breaking change for current functions.

I could not make the Lease Options work on the function level. Mainly because, even if I parse it correctly, I cannot pass it to the Attribute because it's not a basic Type, so it doesn't work in:

[CosmosDBTrigger("ItemDb", "ItemCollection", LeaseOptions= new LeaseOptions(...))]

That is why I put it on the global host.json level.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah makes sense -- let's go with this.

CosmosDBTriggerAttribute attributeTrigger = new CosmosDBTriggerAttribute(databaseName, collectionName);
attributeTrigger.ConnectionString = connection;

JObject leasesConfiguration = Context.GetMetadataValue<JObject>("lease");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know @mamaso recommended we bundle these into a single object, but I seem to recall that the best approach is to have the properties match 1:1 with the attribute in extensions. Eventually, that'll let you remove this code completely and we'll be able to auto-map them. If you change the shape of the metadata (as compared to the attribute), that mapping is harder.

@MikeStall may have more input here.

{
attribute = new DocumentDBAttribute(databaseName, collectionName);
CosmosDBTriggerAttribute attributeTrigger = new CosmosDBTriggerAttribute(databaseName, collectionName);
attributeTrigger.ConnectionString = connection;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed the difference in this name -- we should change this to ConnectionStringSetting. I think we're a little inconsistent with the naming, but we decided at some point that using Setting here made it more clear that it wasn't an actual connection string, but rather an app setting that points to a connection string.

Same with LeaseConnectionStringSetting (anything with the [AppSetting] attribute, really).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in next commit

attributeTrigger.LeaseConnectionString = leaseConnectionString.Value<string>();
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add support for LeaseOptions here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could not make the Lease Options work on the function level. Mainly because, even if I parse it correctly, I cannot pass it to the Attribute because it's not a basic Type, so it doesn't work in:

[CosmosDBTrigger("ItemDb", "ItemCollection", LeaseOptions= new LeaseOptions(...))]

@@ -159,6 +162,56 @@ public virtual void Dispose()
Host.Stop();
Host.Dispose();
ServiceBusQueueClient.Close();
if (DocumentClient != null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to do DocumentClient?.Dispose() here. Saves a few lines :-)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget sometimes that I can use C# 6 here 😄

@@ -77,6 +78,8 @@ protected EndToEndTestFixture(string rootPath, string testId)

public Microsoft.ServiceBus.Messaging.QueueClient ServiceBusQueueClient { get; private set; }

public Documents.Client.DocumentClient DocumentClient { get; private set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add usings for Microsoft.Documents/Microsoft.Documents.Client so this (and some other lines) is a little shorter?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in next commit

// "AzureWebJobsDocumentDBConnectionString" -- the connection string to the account
await Fixture.InitializeDocumentClient();
bool collectionsCreated = await Fixture.CreateDocumentCollections();
var resultBlob = Fixture.TestOutputContainer.GetBlockBlobReference("completed");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: just to avoid confusion -- can you name this "cosmosdbtriggere2e-completed"? I know we use "completed" for some others, but it's nicer if it's clear.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in next commit

@brettsam brettsam merged commit a7d1ba4 into Azure:dev Jul 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants