基于 Spring Cloud Function 的 Azure Function 开发

Notice:

本文章不包含 Azure Function 环境配置等内容

1.1 前提

  • Azure 账户,且有可使用的订阅
  • Azure 支持的 JDK (本教程适用于 JDK 1.8)
  • IntelliJ IDEA 社区版或无限制版均可
  • Maven 3.5+
  • 最新的 Function Core Tools

1.2 创建 Spring Cloud Function Azure 工程

在 Github 仓库: https://github.com/spring-cloud/spring-cloud-function 可以找到 Spring Cloud Function Azure 的实例代码。此处我们使用 v3.X 的最后一个版本 v3.2.11 作为基准项目: https://github.com/spring-cloud/spring-cloud-function/tree/v3.2.11/spring-cloud-function-samples/function-sample-azure

image-20230702192324390

1.3 设置配置信息

您可能需要按照需要,修改默认的 POM 文件配置信息。

  • GroupIdArtifactId

    <groupId>com.example</groupId>
    <artifactId>your-project-name</artifactId>
    
  • 部分 Properties 信息

    <properties>
      <maven.compiler.source>8</maven.compiler.source>
      <maven.compiler.target>8</maven.compiler.target>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    

    <java.version>1.8</java.version>
    <functionAppName>yourFunctionAppName</functionAppName>
    <functionAppRegion>Your APP Region</functionAppRegion>
    <functionResourceGroup>function-resource-group</functionResourceGroup>
    <stagingDirectory>\({project.build.directory}/azure-functions/\){functionAppName}</stagingDirectory>
    <start-class>com.axa.Application</start-class>
    <azure.functions.maven.plugin.version>1.12.0</azure.functions.maven.plugin.version>
    <azure.functions.java.library.version>1.3.0</azure.functions.java.library.version>
    <wrapper.version>1.0.27.RELEASE</wrapper.version>
    </properties>

    为了能够衔接 Azure Function 您需要配置有关 Azure Function 的信息。

    • functionAppName: Function APP 的名称,去要与您 Azure 订阅中的 Function App 名称对应。

    • functionRegion: 您可以在您的 Function Overview 信息中找到,即 Location 信息。

      image-20230702193448371

      例如此处的 functionRegionLocation 信息为: South Central US

    • functionResourceGroup: 其为您 Function APP 订阅所在的资源组信息

1.4 编写 Spring Cloud Function

本版本中使用 Function Invoke 的方式进行集成操作
See Also: https://docs.spring.io/spring-cloud-function/docs/current/reference/html/spring-cloud-function.html#_legacy_functioninvoker_integration_option

在 Azure adapter 即 Azure 适配器中,其引导了 Spring Cloud Function 上下文,并将 Azure 框架的函数调用,引导到用户自定义的 Spring Cloud Function 中。Azure Functions 具有相当独特的、侵入式的编程模型,涉及用户代码中的注释,这些注释都是 Azure 平台独有的。我们需要明确的是,Spring Cloud Function 通过 org.springframework.cloud.function.adapter.azure.FunctionInvoker 这种方式与 Azure Function 进行集成。这种基于注解的方式能简单的去配置您的 Java Function (那些不能被 Azure 所识别的函数) 将其配置为 Azure Function。您只需要创建一个扩展了 FunctionInvoker 的处理函数,定义和配置您的函数处理方法,并对 handleRequest(...) 进行回调。这个处理方法提供了输入和输出类型作为注释的方法参数 (使 Azure 能够创建该类并创建 JSON 绑定)。

public class UppercaseHandler extends FunctionInvoker<Message<String>, String> {
@FunctionName(&quot;uppercase&quot;)
public String execute(@HttpTrigger(name = &quot;req&quot;, methods = {HttpMethod.GET,
		HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage&lt;Optional&lt;String&gt;&gt; request,
	ExecutionContext context) {
	Message&lt;String&gt; message = MessageBuilder.withPayload(request.getBody().get()).copyHeaders(request.getHeaders()).build();
	return handleRequest(message, context);
}

}

需要注意的是,除了通过 Azure 注解提供配置外,我们还在这个处理方法的主体中创建了一个 Message 实例,并对 handlerRequest(...) 进行了回调,返回其结果。

您需要创建的实际的用户函数为:

@Bean
public Function<String, String> uppercase() {
		return payload -> payload.toUpperCase();
}

// OR

@Bean
public Function<Message<String>, String> uppercase() {
return message -> message.getPayload().toUpperCase();
}

此外,在创建 Message 实例时,你可以复制 HTTP 头请求,在必要时进行使用。

org.springframework.cloud.function.adapter.azure.FunctionInvoker 类有两个有用的方法 (handleRequesthandleOutput),你可以将实际的函数调用委托给它们,所以大多数情况下,函数只有一行。

函数名称(定义)将从 Azure 的 ExecutionContext.getFunctionName() 方法中获取,有效地支持应用环境中的多个函数。

1.5 获取 Azure Execution Contex

有些时候需要访问Azure运行时以com.microsoft.azure.function.ExecutionContext的形式提供的目标执行环境。例如,这种需求之一是记录,所以它可以出现在Azure控制台。

为此,AzureFunctionUtil.enhanceInputIfNecessary允许你添加一个ExecutionContext的实例作为消息头,这样你就可以通过executionContext键来检索它。

@FunctionName("ditest")
public String execute(
		@HttpTrigger(name = "req", methods = { HttpMethod.GET,
				HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
		ExecutionContext context) {
Message message = AzureFunctionUtil.enhanceInputIfNecessary(request.getBody().get(), context);

return this.uppercase.apply(message);

}

现在你可以通过 executionContext键来检索它。

@Bean
public Function<Message<String>, String> uppercase(JsonMapper mapper) {
	return message -> {
		String value = message.getPayload();
		ExecutionContext context = (ExecutionContext) message.getHeaders().get("executionContext");
		. . .
	}
}
posted @ 2023-07-03 11:31  ED_Reagan  阅读(43)  评论(0编辑  收藏  举报