为单租户 Azure 逻辑应用中的标准逻辑应用创建自定义内置连接器
适用于:Azure 逻辑应用(标准)
如果需要标准逻辑应用工作流中未提供的连接器,可以使用基于服务提供程序的内置连接器(可用于单租户 Azure 逻辑应用中的标准工作流)所用的同一扩展性模型创建自己的内置连接器。 此扩展性模型基于 Azure Functions 扩展性模型。
本文介绍如何创建一个示例性的自定义内置 Azure Cosmos DB 连接器,该连接器有一个基于 Azure Functions 的触发器,但没有任何操作。 将新文档添加到 Azure Cosmos DB 中的租约集合或容器时,该触发器将会触发,然后运行将输入的有效负载用作 Azure Cosmos DB 文档的工作流。
Operation | 操作详细信息 | 说明 |
---|---|---|
触发器 | 收到文档时 | 当在指定的 Azure Cosmos DB 数据库和集合中发生插入操作时,将运行此触发器操作。 |
操作 | 无 | 此连接器不定义任何操作。 |
此示例连接器使用与适用于 Azure Functions 的 Azure Cosmos DB 触发器(基于 Azure Functions 触发器和绑定)相同的功能。 有关完整示例,请查看示例自定义内置 Azure Cosmos DB 连接器 - Azure 逻辑应用连接器扩展。
有关详细信息,请查看以下文档:
先决条件
Azure 帐户和订阅。 如果没有订阅,可以注册 Azure 帐户。
有关单租户 Azure 逻辑应用、标准逻辑应用工作流、连接器以及如何使用 Visual Studio Code 创建基于单个租户的工作流的基本知识。 有关详细信息,请查看以下文档:
安装了 Azure 逻辑应用(标准版)扩展和其他先决条件的 Visual Studio Code。 安装应已包含 Microsoft.Azure.Workflows.WebJobs.Extension 的 NuGet 包。
注意
目前仅可在 Visual Studio Code 中使用此创作功能。
Azure Cosmos DB 帐户、数据库以及容器或集合。 有关详细信息,请参阅快速入门:从 Azure 门户创建 Azure Cosmos DB 帐户、数据库、容器和项。
高级步骤
以下大纲说明了构建示例连接器的概要步骤:
创建类库项目。
在项目中,将 Microsoft.Azure.Workflows.WebJobs.Extension NuGet 包添加为 NuGet 引用。
使用 NuGet 包为内置连接器提供操作,以便为名为 IServiceOperationsProvider 和 IServiceOperationsTriggerProvider 的接口实现方法。
将自定义内置连接器注册到 Azure Functions 运行时扩展。
安装连接器以供使用。
创建类库项目
在 Visual Studio Code 中创建 .NET Core 3.1 类库项目。
在项目中,将名为 Microsoft.Azure.Workflows.WebJobs.Extension 的 NuGet 包添加为 NuGet 引用。
实现服务提供程序接口
若要为示例内置连接器提供操作,请在 Microsoft.Azure.Workflows.WebJobs.Extension NuGet 包中实现以下接口的方法。 下图显示了带有方法实现的接口,Azure 逻辑应用设计器和运行时要求具有基于 Azure Functions 触发器的自定义内置连接器包含这些方法实现:
IServiceOperationsProvider
此接口包括以下方法,这些方法提供操作清单,并在自定义内置连接器中执行服务提供程序的特定任务或实际业务逻辑。 有关详细信息,请查看 IServiceOperationsProvider。
-
Azure 逻辑应用中的设计器需要 GetService() 方法来检索自定义服务的高级元数据,包括服务说明、设计器所需的连接输入参数、功能、品牌颜色、图标 URL 等。
-
Azure 逻辑应用中的设计器需要 GetOperations() 方法来检索自定义服务实现的操作。 操作列表基于 Swagger 架构。 设计器还使用操作元数据来了解特定操作的输入参数,并根据操作的输出架构生成输出作为属性标记。
GetBindingConnectionInformation()
如果触发器是基于 Azure Functions 的触发器类型,则 Azure 逻辑应用中的运行时需要 GetBindingConnectionInformation() 方法为 Azure Functions 触发器绑定提供所需的连接参数信息。
-
如果连接器具有操作,则 Azure 逻辑应用中的运行时需要 InvokeOperation() 方法来调用连接器中在工作流执行期间运行的每个操作。 如果连接器没有操作,则无需实现 InvokeOperation () 方法。
在此示例中,Azure Cosmos DB 自定义内置连接器没有操作。 但是,出于完整性的考虑,该方法包含在此示例中。
有关这些方法及其实现的详细信息,请查看本文中后面的这些方法。
IServiceOperationsTriggerProvider
可以将 Azure Functions 触发器或操作添加或公开为自定义内置连接器中的服务提供程序触发器。 若要使用基于 Azure Functions 的触发器类型和与 Azure 托管连接器触发器相同的 Azure Functions 绑定,请实现以下方法来提供 Azure Functions 所需的连接信息和触发器绑定。 有关详细信息,请查看 IServiceOperationsTriggerProvider。
需要 GetFunctionTriggerType() 方法返回与 Azure Functions 触发器绑定中的 type 参数相同的字符串。
GetFunctionTriggerDefinition() 具有默认实现,因此无需显式实现此方法。 但是,如果要更新触发器的默认行为,例如提供设计器未公开的额外参数,则可以实现此方法并替代默认行为。
要实现的方法
以下部分介绍示例连接器实现的方法。 有关完整示例,请查看 示例 CosmosDbServiceOperationProvider.cs。
重要
当你有敏感信息(例如包含用户名和密码的连接字符串)时,请确保使用可用的最安全身份验证流。 例如,Microsoft 建议你在有支持的情况下使用托管标识验证对 Azure 资源的访问权限,并分配具有最低必需权限的角色。
如果此功能不可用,请务必通过其他措施(例如可与应用设置一起使用的 Azure 密钥保管库)保护连接字符串。 然后,可以直接引用安全字符串,例如连接字符串和密钥。 与 ARM 模板类似,在部署时可以定义环境变量,可以在逻辑应用工作流定义中定义应用设置。 然后,可以捕获动态生成的基础结构值,例如连接终结点、存储字符串等。 有关详细信息,请参阅Microsoft 标识平台的应用程序类型。
GetService()
设计器需要以下方法来获取服务的概要说明:
public ServiceOperationApi GetService()
{
return this.CosmosDBApis.ServiceOperationServiceApi();
}
GetOperations()
设计器需要以下方法来获取服务实现的操作。 此操作列表基于 Swagger 架构。
public IEnumerable<ServiceOperation> GetOperations(bool expandManifest)
{
return expandManifest ? serviceOperationsList : GetApiOperations();
}
GetBindingConnectionInformation()
若要使用基于 Azure Functions 的触发器类型,可以使用以下方法来向 Azure Functions 触发器绑定提供所需的连接参数信息。
public string GetBindingConnectionInformation(string operationId, InsensitiveDictionary<JToken> connectionParameters)
{
return ServiceOperationsProviderUtilities
.GetRequiredParameterValue(
serviceId: ServiceId,
operationId: operationID,
parameterName: "connectionString",
parameters: connectionParameters)?
.ToValue<string>();
}
InvokeOperation()
示例 Azure Cosmos DB 自定义内置连接器没有操作,但出于完整性的考虑,我们包括了以下方法:
public Task<ServiceOperationResponse> InvokeOperation(string operationId, InsensitiveDictionary<JToken> connectionParameters, ServiceOperationRequest serviceOperationRequest)
{
throw new NotImplementedException();
}
GetFunctionTriggerType()
若要将基于 Azure Functions 的触发器用作连接器中的触发器,必须返回与 Azure Functions 触发器绑定中的 type 参数相同的字符串。
以下示例为现成的内置 Azure Cosmos DB 触发器返回了字符串 "type": "cosmosDBTrigger"
:
public string GetFunctionTriggerType()
{
return "CosmosDBTrigger";
}
GetFunctionTriggerDefinition()
此方法具有默认实现,因此无需显式实现此方法。 但是,如果要更新触发器的默认行为,例如提供设计器未公开的额外参数,则可以实现此方法并替代默认行为。
注册连接器
若要在 Azure Functions 运行时启动过程中加载自定义内置连接器扩展,必须将 Azure Functions 扩展注册添加为启动作业,并将连接器注册为服务提供程序列表中的服务提供程序。 根据内置触发器需要用作输入的数据类型,可以选择添加转换器。 此示例将 Azure Cosmos DB 文档的 Document 数据类型转换为 JObject 数组。
以下部分演示如何将自定义内置连接器注册为 Azure Functions 扩展。
创建启动作业
使用名为 [assembly:WebJobsStartup] 的程序集属性创建启动类。
实现 IWebJobsStartup 接口。 在 Configure() 方法中,注册扩展并注入服务提供程序。
例如,以下代码片段显示了示例自定义内置 Azure Cosmos DB 连接器的启动类实现:
using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Hosting; using Microsoft.Extensions.DependencyInjection.Extensions; [assembly: Microsoft.Azure.WebJobs.Hosting.WebJobsStartup(typeof(ServiceProviders.CosmosDb.Extensions.CosmosDbTriggerStartup))] namespace ServiceProviders.CosmosDb.Extensions { public class CosmosDbServiceProviderStartup : IWebJobsStartup { // Initialize the workflow service. public void Configure(IWebJobsBuilder builder) { // Register the extension. builder.AddExtension<CosmosDbServiceProvider>)(); // Use dependency injection (DI) for the trigger service operation provider. builder.Services.TryAddSingleton<CosmosDbTriggerServiceOperationsProvider>(); } } }
有关详细信息,请查看注册服务 - 在 .NET Azure Functions 中使用依赖项注入。
注册服务提供程序
现在,将服务提供程序实现作为 Azure Functions 扩展注册到 Azure 逻辑应用引擎。 此示例使用内置的适用于 Azure Functions 的 Azure Cosmos DB 触发器作为新触发器。 此示例还为现有服务提供程序列表注册新的 Azure Cosmos DB 服务提供程序,该列表已经是 Azure 逻辑应用扩展的一部分。 有关详细信息,请参阅注册 Azure Functions 绑定扩展。
using Microsoft.Azure.Documents;
using Microsoft.Azure.WebJobs.Description;
using Microsoft.Azure.WebJobs.Host.Config;
using Microsoft.Azure.Workflows.ServiceProviders.Abstractions;
using Microsoft.WindowsAzure.ResourceStack.Common.Extensions;
using Microsoft.WindowsAzure.ResourceStack.Common.Json;
using Microsoft.WindowsAzure.ResourceStack.Common.Storage.Cosmos;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace ServiceProviders.CosmosDb.Extensions
{
[Extension("CosmosDbServiceProvider", configurationSection: "CosmosDbServiceProvider")]
public class CosmosDbServiceProvider : IExtensionConfigProvider
{
// Initialize a new instance for the CosmosDbServiceProvider class.
public CosmosDbServiceProvider(ServiceOperationsProvider serviceOperationsProvider, CosmosDbTriggerServiceOperationsProvider operationsProvider)
{
serviceOperationsProvider.RegisterService(serviceName: CosmosDBServiceOperationsProvider.ServiceName, serviceOperationsProviderId: CosmosDBServiceOperationsProvider.ServiceId, serviceOperationsProviderInstance: operationsProvider);
}
// Convert the Azure Cosmos DB Document array to a generic JObject array.
public static JObject[] ConvertDocumentToJObject(IReadOnlyList<Document> data)
{
List<JObject> jobjects = new List<JObject>();
foreach(var doc in data)
{
jobjects.Add((JObject)doc.ToJToken());
}
return jobjects.ToArray();
}
// In the Initialize method, you can add any custom implementation.
public void Initialize(ExtensionConfigContext context)
{
// Convert the Azure Cosmos DB Document list to a JObject array.
context.AddConverter<IReadOnlyList<Document>, JObject[]>(ConvertDocumentToJObject);
}
}
}
添加转换器
Azure 逻辑应用有一种使用 JObject 数组来处理任何 Azure Functions 内置触发器的通用方法。 不过,如果你要将 Azure Cosmos DB 文档的只读列表转换为 JObject 数组,可以添加转换器。 当转换器准备就绪时,将转换器注册为 ExtensionConfigContext 的一部分,如此示例前面所示:
// Convert the Azure Cosmos DB document list to a JObject array.
context.AddConverter<IReadOnlyList<Document>, JObject[]>(ConvertDocumentToJObject);
已实现类的类库关系图
完成后,请查看以下类关系图,其中显示了 Microsoft.Azure.Workflows.ServiceProvider.Extensions.CosmosDB.dll 扩展捆绑包中所有类的实现:
- CosmosDbServiceOperationsProvider
- CosmosDbServiceProvider
- CosmosDbServiceProviderStartup
安装连接器
若要添加上一部分中的 NuGet 引用,请在名为 Microsoft.Azure.Workflows.ServiceProvider.Extensions.CosmosDB.dll 的扩展捆绑包中更新 extensions.json 文件。 有关详细信息,请访问 Azure/logicapps-connector-extensions 存储库,并查看名为 add-extension.ps1 的 PowerShell 脚本。
更新扩展捆绑包以包含自定义内置连接器。
在应已安装了适用于 Visual Studio Code 的 Azure 逻辑应用(标准版)扩展的 Visual Studio Code 中,创建一个逻辑应用项目,并使用以下 PowerShell 命令安装扩展包:
PowerShell
dotnet add package "Microsoft.Azure.Workflows.ServiceProvider.Extensions.CosmosDB" --version 1.0.0 --source $extensionPath
或者,使用 PowerShell 提示符从逻辑应用项目的目录中运行名为 add-extension.ps1 的 PowerShell 脚本:
.\add-extension.ps1 {Cosmos-DB-output-bin-NuGet-folder-path} CosmosDB
Bash
若要改用 Bash,请从逻辑应用项目的目录中使用以下命令运行 PowerShell 脚本:
powershell -file add-extension.ps1 {Cosmos-DB-output-bin-NuGet-folder-path} CosmosDB
如果已成功安装自定义内置连接器的扩展,则会收到类似于以下示例的输出:
C:\Users\{your-user-name}\Desktop\demoproj\cdbproj>powershell - file C:\myrepo\github\logicapps-connector-extensions\src\Common\tools\add-extension.ps1 C:\myrepo\github\logicapps-connector-extensions\src\CosmosDB\bin\Debug\CosmosDB Nuget extension path is C:\myrepo\github\logicapps-connector-extensions\src\CosmosDB\bin\Debug\ Extension dll path is C:\myrepo\github\logicapps-connector-extensions\src\CosmosDB\bin\Debug\netcoreapp3.1\Microsoft.Azure.Workflows.ServiceProvider.Extensions.CosmosDB.dll Extension bundle module path is C:\Users\{your-user-name}\.azure-functions-core-tools\Functions\ExtensionBundles\Microsoft.Azure.Functions.ExtensionBundle.Workflows1.1.9 EXTENSION PATH is C:\Users\{your-user-name}\.azure-functions-core-tools\Functions\ExtensionBundles\Microsoft.Azure.Functions.ExtensionBundle.Workflows\1.1.9\bin\extensions.json and dll Path is C:\myrepo\github\logicapps-connector-extensions\src\CosmosDB\bin\Debug\netcoreapp3.1\Microsoft.Azure.Workflows.ServiceProvider.Extensions.CosmosDB.dll SUCCESS: The process "func.exe" with PID 26692 has been terminated. Determining projects to restore... Writing C:\Users\{your-user-name}\AppData\Local\Temp\tmpD343.tmp`<br /> info : Adding PackageReference for package 'Microsoft.Azure.Workflows.ServiceProvider.Extensions.CosmosDB' into project 'C:\Users\{your-user-name}\Desktop\demoproj\cdbproj.csproj'. info : Restoring packages for C:\Users\{your-user-name}\Desktop\demoproj\cdbproj.csproj... info : Package 'Microsoft.Azure.Workflows.ServiceProvider.Extensions.CosmosDB' is compatible with all the specified frameworks in project 'C:\Users\{your-user-name}\Desktop\demoproj\cdbproj.csproj'. info : PackageReference for package 'Microsoft.Azure.Workflows.ServiceProvider.Extensions.CosmosDB' version '1.0.0' updated in file 'C:\Users\{your-user-name}\Desktop\demoproj\cdbproj.csproj'. info : Committing restore... info : Generating MSBuild file C:\Users\{your-user-name}\Desktop\demoproj\cdbproj\obj\cdbproj.csproj.nuget.g.props. info : Generating MSBuild file C:\Users\{your-user-name}\Desktop\demoproj\cdbproj\obj\cdbproj.csproj.nuget.g.targets. info : Writing assets file to disk. Path: C:\Users\{your-user-name}\Desktop\demoproj\cdbproj\obj\project.assets.json. log : Restored C:\Users\{your-user-name}\Desktop\demoproj\cdbproj\cdbproj.csproj (in 1.5 sec). Extension CosmosDB is successfully added. C:\Users\{your-user-name}\Desktop\demoproj\cdbproj\>
如果正在运行任何 func.exe 进程,请确保在继续执行下一步之前关闭或退出该进程。
测试连接器
在 Visual Studio Code 中,打开设计器中的标准逻辑应用和空白工作流。
在设计器图面上,选择“选择操作”以打开连接器操作选取器。
在操作搜索框下,选择“内置”。 在搜索框中输入“cosmos db”。
操作选取器显示自定义内置连接器和触发器,例如:
从“触发器”列表中选择自定义内置触发器以启动工作流。
在连接窗格中,提供以下属性值来创建连接,例如:
属性 需要 值 说明 连接名称 是 <Azure-Cosmos-DB-connection-name> 要创建的 Azure Cosmos DB 连接的名称 连接字符串 是 <Azure Cosmos DB-DB-connection-string> 要将已收到的新文档添加到的 Azure Cosmos DB 数据库集合或租约集合的连接字符串。 完成操作后,选择“创建”。
在触发器属性窗格中,为触发器提供以下属性值,例如:
属性 需要 值 说明 数据库名称 是 <Azure-Cosmos-DB-database-name> 要使用的 Azure Cosmos DB 数据库的名称 集合名称 是 <Azure-Cosmos-DB-collection-name> 要将每个已收到的新文档添加到其中的 Azure Cosmos DB 集合的名称。 对于此示例,在代码视图中,工作流定义(位于 workflow.json 文件中)有一个类似于以下示例的
triggers
JSON 对象:{ "definition": { "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", "actions": {}, "contentVersion": "1.0.0.0", "outputs": {}, "triggers": { "When_a_document_is_received": { "inputs":{ "parameters": { "collectionName": "States", "databaseName": "SampleCosmosDB" }, "serviceProviderConfiguration": { "connectionName": "cosmosDb", "operationId": "whenADocumentIsReceived", "serviceProviderId": "/serviceProviders/CosmosDb" }, "splitOn": "@triggerOutputs()?['body']", "type": "ServiceProvider" } } } }, "kind": "Stateful" }
连接定义(位于 connections.json 文件中)有一个类似于以下示例的
serviceProviderConnections
JSON 对象:{ "serviceProviderConnections": { "cosmosDb": { "parameterValues": { "connectionString": "@appsetting('cosmosDb_connectionString')" }, "serviceProvider": { "id": "/serviceProviders/CosmosDb" }, "displayName": "myCosmosDbConnection" } }, "managedApiConnections": {} }
在 Visual Studio Code 的“运行”菜单上,选择“开始调试”。 (按 F5)
若要触发工作流,请在 Azure 门户中打开 Azure Cosmos DB 帐户。 在帐户菜单上,选择“数据资源管理器”。 浏览到你在触发器中指定的数据库和集合。 向集合中添加一项。