Migrate trigger functions to ConnectorTrigger extension attribute#56
Migrate trigger functions to ConnectorTrigger extension attribute#56manvkaur wants to merge 5 commits into
Conversation
Replace HttpTrigger + manual JSON deserialization with ConnectorTrigger attribute from the Functions Worker Extensions Connector package. The extension now handles HTTP plumbing, payload parsing, and error handling automatically. - Add Microsoft.Azure.Functions.Worker.Extensions.Connector 0.2.0-alpha - Add OpenTelemetry, Azure Monitor exporter packages - Add ActivitySource listener for connector SDK tracing in dev mode - Migrate Office365, SharePoint, Teams, OneDrive, AzureBlob, EventGrid, EventHubs, Queues, ServiceBus, Outlook, Wdatp, Yammer trigger functions - Remove ConnectorTriggerMetadataAttribute POC placeholder Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rewrite SharePoint, Teams, Office365 trigger tests for void ConnectorTrigger pattern - Use Mock<ILogger> to verify log output (count of items/messages/emails) - Test valid payload, empty payload, and null payload for each trigger - Remove duplicate OutlookFunctions.cs from test project (upstream merge artifact) - Update test project TFM to net10.0 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0749af4 to
187a4e5
Compare
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
- Update test assertions to match 'Received new email notification' log message (CodeQL autofix removed emailCount from logging) - Update CI workflow dotnet-version from 8.0.x to 10.0.x to match net10.0 TFM Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ip ci] - Update test assertions to match 'Received new email notification' log message (CodeQL autofix removed emailCount from logging) - Update CI workflow dotnet-version from 8.0.x to 10.0.x to match net10.0 TFM Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR migrates multiple “trigger callback” Azure Functions from an explicit HttpTrigger + manual JSON handling approach to the Microsoft.Azure.Functions.Worker.Extensions.Connector [ConnectorTrigger] binding, and updates the sample app’s runtime/telemetry setup to align with the new trigger model.
Changes:
- Replaced several connector trigger callback HTTP endpoints with
[ConnectorTrigger]-bound functions (typed payloads where available;stringotherwise). - Updated/rewrote unit tests for migrated triggers to validate logging behavior with
Moq<ILogger<T>>. - Updated project/CI configuration (TFM upgrade to
net10.0) and added OpenTelemetry/Azure Monitor exporter wiring.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds links to related Azure Functions sample repos using the connector trigger extension. |
| DirectConnector/AzureBlobFunctions.cs | Adds OnBlobUpdated [ConnectorTrigger] function. |
| DirectConnector/AzureEventGridFunctions.cs | Adds OnEventGridResourceEvent [ConnectorTrigger] function (raw string payload). |
| DirectConnector/AzureQueuesFunctions.cs | Adds OnQueueMessagesAvailable [ConnectorTrigger] function (raw string payload). |
| DirectConnector/EventHubsFunctions.cs | Adds OnNewEvents [ConnectorTrigger] function. |
| DirectConnector/Office365Functions.cs | Replaces the HTTP trigger callback with OnNewEmail [ConnectorTrigger] and logs email metadata. |
| DirectConnector/OneDriveFunctions.cs | Removes the prior HTTP trigger callback handler and adds OnNewOneDriveFiles [ConnectorTrigger]. |
| DirectConnector/OutlookFunctions.cs | Adds OnNewOutlookEmail [ConnectorTrigger] function. |
| DirectConnector/Program.cs | Adds conditional OpenTelemetry + Azure Monitor exporter registration. |
| DirectConnector/ServiceBusFunctions.cs | Adds OnQueueMessages [ConnectorTrigger] function. |
| DirectConnector/SharePointFunctions.cs | Replaces the HTTP trigger callback with OnNewSharePointItem [ConnectorTrigger] and logs item counts/properties. |
| DirectConnector/TeamsFunctions.cs | Replaces the HTTP trigger callback with OnNewChannelMessage [ConnectorTrigger] and logs message count. |
| DirectConnector/WdatpFunctions.cs | Adds OnNewRemediationActivity [ConnectorTrigger] function. |
| DirectConnector/YammerFunctions.cs | Adds OnNewYammerMessage [ConnectorTrigger] function (raw string payload). |
| DirectConnector/host.json | Switches telemetry mode to OpenTelemetry and removes Application Insights sampling config. |
| DirectConnector/DirectConnector.csproj | Updates TFM to net10.0 and adds connector trigger + OpenTelemetry-related packages. |
| DirectConnector.Tests/DirectConnector.Tests.csproj | Updates test TFM to net10.0. |
| DirectConnector.Tests/Office365FunctionsTests.cs | Adds tests verifying Office365 trigger logging behavior via Moq. |
| DirectConnector.Tests/SharePointFunctionsTests.cs | Rewrites trigger tests to validate SharePoint trigger logging via Moq. |
| DirectConnector.Tests/TeamsFunctionsTests.cs | Rewrites trigger tests to validate Teams trigger logging via Moq. |
| .github/workflows/ci.yml | Updates CI to use .NET 10.0.x. |
| [Function("OnNewEmail")] | ||
| public void OnNewEmail( | ||
| [ConnectorTrigger] | ||
| Office365OnNewEmailTriggerPayload payload) |
| { | ||
| contentLength = parsedLength; | ||
| } | ||
| this._logger.LogInformation("OnNewEmail: Received new email notification."); |
| [Function("OnNewChannelMessage")] | ||
| public void OnNewChannelMessage( | ||
| [ConnectorTrigger] | ||
| TeamsOnNewChannelMessageTriggerPayload payload) |
| [Function("OnNewSharePointItem")] | ||
| public void OnNewSharePointItem( | ||
| [ConnectorTrigger] | ||
| SharePointOnlineOnNewItemsTriggerPayload payload) |
| [Function("OnNewOneDriveFiles")] | ||
| public void OnNewOneDriveFiles( | ||
| [ConnectorTrigger] | ||
| OneDriveForBusinessOnNewFilesTriggerPayload payload) |
| [Function("OnBlobUpdated")] | ||
| public void OnBlobUpdated( | ||
| [ConnectorTrigger] | ||
| AzureBlobOnUpdatedFilesTriggerPayload payload) |
There was a problem hiding this comment.
We should demonstrate minimum use of the payload such as including metadata in the logged message, e.g. payload size.
| [Function("OnEventGridResourceEvent")] | ||
| public void OnEventGridResourceEvent( | ||
| [ConnectorTrigger] | ||
| string payload) |
| [Function("OnQueueMessagesAvailable")] | ||
| public void OnQueueMessagesAvailable( | ||
| [ConnectorTrigger] | ||
| string payload) |
| [Function("OnNewYammerMessage")] | ||
| public void OnNewYammerMessage( | ||
| [ConnectorTrigger] | ||
| string payload) |
| <PropertyGroup> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| <TargetFramework>net10.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> |
| [HttpTrigger(AuthorizationLevel.Function, "post", Route = "triggerCallback")] HttpRequestData request, | ||
| CancellationToken cancellationToken) | ||
| [Function("OnNewEmail")] | ||
| public void OnNewEmail( |
There was a problem hiding this comment.
Should there be two distinct samples here - one demonstrating the Functions extension already deserialized strong type as you've added
[Function("OnNewEmail")]
public void OnNewEmail(
[ConnectorTrigger]
Office365OnNewEmailTriggerPayload payload)There other preserving the non-Function, any compute demonstration of method attribute based annotation to inform the LSP what payload parsing code needs to be inserted by IntelliSense?
[ConnectorTriggerMetadata(
ConnectorName = ConnectorNames.Office365Outlook,
OperationName = Office365TriggerOperations.OnNewEmail,
Connection = "Connectors:Office365")]
...
// NOTE: Use SDK's per-trigger convenience type for typed deserialization.
// Office365OnNewEmailTriggerPayload is a subclass of TriggerCallbackPayload<GraphClientReceiveMessage>
// that provides discoverability — the developer no longer needs to know the inner type.
// The SDK's TriggerCallbackBodyConverter<T> (fix for issue #149) normalizes both
// single-item and batch shapes so payload.Body.Value is always populated.
var payload = JsonSerializer.Deserialize<Office365OnNewEmailTriggerPayload>(
body,
Office365Functions.JsonOptions);
Description
Migrate all trigger functions from the manual HttpTrigger + JSON deserialization pattern to the
[ConnectorTrigger]extension attribute fromMicrosoft.Azure.Functions.Worker.Extensions.Connector. The extension handles HTTP plumbing, payload parsing, and error responses automatically.Changes
Trigger Migration
OnNewEmail— receivesOffice365OnNewEmailTriggerPayload, logs email count and operational metadata (Id, ReceivedTime, HasAttachments, Importance)OnNewSharePointItem— receivesSharePointOnlineOnNewItemsTriggerPayload, logs item count and additional property countOnNewChannelMessage— receivesTeamsOnNewChannelMessageTriggerPayload, logs message countOnNewOneDriveFiles— receivesOneDriveForBusinessOnNewFilesTriggerPayload, logs file name and sizeOnBlobUpdated— receivesAzureBlobOnUpdatedFilesTriggerPayloadOnNewEvents— receivesEventHubsOnNewEventsTriggerPayloadOnQueueMessages— receivesServicebusOnGetMessagesFromQueueTriggerPayloadOnNewOutlookEmail— receivesOutlookOnNewEmailTriggerPayloadOnNewRemediationActivity— receivesWdatpOnNewRemediationActivityTriggerPayloadOnEventGridResourceEvent— receives rawstringpayloadOnQueueMessagesAvailable— receives rawstringpayloadOnNewYammerMessage— receives rawstringpayloadCurrent Pattern
Trigger functions use
voidreturn type with typed SDK payload binding. The ConnectorTrigger extension deserializes the webhook JSON into the SDK payload type automatically. Functions log payload metadata for observability. Null-safe payload access (payload?.Body?.Value) ensures graceful handling when the extension passes null or incomplete data.Tests
Mock<ILogger<T>>to verify log outputOutlookFunctions.csfrom test project (upstream merge artifact)Infrastructure
Microsoft.Azure.Functions.Worker.Extensions.Connector 0.2.0-alphapackageTest Results
31 tests passed, 0 failed