将 Java 函数连接到 Azure 存储

无需编写自己的集成代码,即可使用 Azure Functions 将 Azure 服务和其他资源连接到函数。 这些绑定表示输入和输出,在函数定义中声明。 绑定中的数据作为参数提供给函数。 触发器是一种特殊类型的输入绑定。 尽管一个函数只有一个触发器,但它可以有多个输入和输出绑定。 有关详细信息,请参阅 Azure Functions 触发器和绑定的概念

本文介绍如何将前一篇快速入门文章中创建的函数与 Azure 存储队列相集成。 添加到此函数的输出绑定会将 HTTP 请求中的数据写入到队列中的消息。

大多数绑定都需要一个存储的连接字符串,函数将使用该字符串来访问绑定的服务。 为便于建立此连接,请使用连同函数应用一起创建的存储帐户。 与此帐户建立的连接已存储在名为 AzureWebJobsStorage 的应用设置中。

先决条件

在开始学习本文之前,请完成 Java 快速入门第 1 部分中的步骤。

下载函数应用设置

你已在 Azure 中创建了一个函数应用以及所需的存储帐户。 此帐户的连接字符串安全存储在 Azure 中的应用设置内。 在本文中,你要将消息写入到同一帐户中的存储队列。 若要在本地运行函数时连接到该存储帐户,必须将应用设置下载到 local.settings.json 文件。

从项目的根目录中,运行以下 Azure Functions Core Tools 命令将设置下载到 local.settings.json,并将 <APP_NAME> 替换为上一篇文章中函数应用的名称:

func azure functionapp fetch-app-settings <APP_NAME>

可能需要登录到 Azure 帐户。

重要

此命令将用 Azure 中函数应用的值覆盖任何现有设置。

由于 local.settings.json 文件包含机密,因此永远不会发布它,应将其从源代码管理中排除。

需要 AzureWebJobsStorage 值,即存储帐户连接字符串。 你将使用此连接来验证输出绑定是否按预期方式工作。

启用扩展捆绑包

安装绑定扩展的最简单方法是启用扩展捆绑包。 启用捆绑包时,会自动安装一组预定义的扩展包。

若要启用扩展捆绑包,请打开 host.json 文件并更新其内容以匹配以下代码:

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[2.*, 3.0.0)"
    }
}

现在,可将存储输出绑定添加到项目。

添加输出绑定

在 Java 项目中,绑定被定义为函数方法上的绑定注释。 然后根据这些注释自动生成 function.json 文件。

浏览到函数代码在 src/main/java 下的位置,打开 Function.java 项目文件,然后将以下参数添加到 run 方法定义:

@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg

msg 参数是 OutputBinding<T> 类型,该类型表示字符串的集合。 当函数完成时,这些字符串作为消息写入到输出绑定。 在这种情况下,输出是名为的 outqueue 存储队列。 存储帐户的连接字符串由 connection 方法设置。 请传递包含存储帐户连接字符串的应用程序设置,而不是传递连接字符串本身。

run 方法定义现在必定如以下示例所示:

@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)  
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") 
        OutputBinding<String> msg, final ExecutionContext context) {
    ...
}

添加使用输出绑定的代码

现在可以使用新的 msg 参数,从函数代码写入到输出绑定。 将以下代码行添加到成功响应之前,以便将 name 的值添加到 msg 输出绑定。

            msg.setValue(name);

使用输出绑定时,无需使用 Azure 存储 SDK 代码进行身份验证、获取队列引用或写入数据。 Functions 运行时和队列输出绑定将为你执行这些任务。

run 方法现在一定如以下示例所示:

    public HttpResponseMessage run(
            @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) 
            HttpRequestMessage<Optional<String>> request, 
            @QueueOutput(name = "msg", queueName = "outqueue", 
            connection = "AzureWebJobsStorage") OutputBinding<String> msg, 
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        // Parse query parameter
        String query = request.getQueryParameters().get("name");
        String name = request.getBody().orElse(query);

        if (name == null) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
            .body("Please pass a name on the query string or in the request body").build();
        } else {
            // Write the name to the message queue. 
            msg.setValue(name);

            return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
        }
    }

更新测试

由于原型还创建一组测试,因此需更新这些测试,以便处理 run 方法签名中的新 msg 参数。

浏览到测试代码在 src/test/java 下的位置,打开 Function.java 项目文件,将 //Invoke 下的代码行替换为以下代码:

        @SuppressWarnings("unchecked")
        final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
        final HttpResponseMessage ret = new Function().run(req, msg, context);

现在可以在本地试用新输出绑定了。

在本地运行函数

如前所述,使用以下命令在本地生成项目并启动 Functions 运行时:

mvn clean package 
mvn azure-functions:run

注意

由于已在 host.json 中启用扩展捆绑包,因此在启动期间已下载并安装存储绑定扩展以及其他 Microsoft 绑定扩展。

如前所述,使用 cURL 在新的终端窗口中从命令行触发函数:

curl -w "\n" http://localhost:7071/api/HttpTrigger-Java --data AzureFunctions

这一次,输出绑定还会在存储帐户中创建名为 outqueue 的队列,并添加包含此字符串的消息。

接下来,使用 Azure CLI 查看新队列,并检查是否已添加了一条消息。 也可以使用 Azure 存储资源管理器Azure 门户查看队列。

设置存储帐户连接

打开 local.settings.json 文件并复制 AzureWebJobsStorage 的值(即存储帐户连接字符串)。 使用以下 Bash 命令将 AZURE_STORAGE_CONNECTION_STRING 环境变量设置为该连接字符串:

AZURE_STORAGE_CONNECTION_STRING="<STORAGE_CONNECTION_STRING>"

AZURE_STORAGE_CONNECTION_STRING 环境变量中设置连接字符串时,无需每次都要提供身份验证,即可访问你的存储帐户。

查询存储队列

可以使用 az storage queue list 命令查看帐户中的存储队列,如以下示例所示:

az storage queue list --output tsv

此命令的输出包含名为 outqueue 的队列,即运行函数时创建的队列。

接下来,使用 az storage message peek 命令查看此队列中的消息,如以下示例所示:

echo `echo $(az storage message peek --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`

返回的字符串应与发送的用于测试函数的消息相同。

注意

以上示例从 base64 解码返回的字符串。 这是因为,队列存储绑定以 base64 字符串的形式写入和读取 Azure 存储。

重新部署项目

若要更新已发布的应用,请再次运行以下命令:

mvn azure-functions:deploy

同样,可以使用 cURL 来测试已部署的函数。 如前所述,将 POST 请求正文中的值 AzureFunctions 传递到 URL,如以下示例所示:

curl -w "\n" https://fabrikam-functions-20190929094703749.chinacloudsites.cn/api/HttpTrigger-Java?code=zYRohsTwBlZ68YF.... --data AzureFunctions

可以再次检查存储队列消息,以验证输出绑定是否按预期在队列中生成新消息。

清理资源

本教程系列中的其他快速入门教程是在本文的基础上制作的。 如果打算继续学习后续的快速入门或相关教程,请不要清理在本快速入门中创建的资源。 如果不打算继续学习,请使用以下命令删除在本快速入门中创建的所有资源:

az group delete --name myResourceGroup

出现提示时选择 y

后续步骤

现已更新 HTTP 触发的函数,使其将数据写入存储队列。 若要详细了解如何使用 Java 开发 Azure Functions,请参阅 Azure Functions Java 开发人员指南Azure Functions 触发器和绑定。 有关 Java 中完整 Function 项目的示例,请参阅 Java Functions 示例

接下来,应为函数应用启用 Application Insights 监视: