【问题标题】:Spring Cloud Function expects Flux<String> instead of String, when deploying on Azure Functions在 Azure Functions 上部署时,Spring Cloud Function 需要 Flux<String> 而不是 String
【发布时间】:2019-06-18 18:04:49
【问题描述】:

我目前正在研究 Spring Cloud Function 及其在不同云环境(AWS Lambda 和 Azure Functions)上部署一个函数的可能性。

我的函数看起来是这样的(当然很简化):

@Component
public class EchoFunction implements Function<String, String> {

    @Override
    public String apply(String m) {
        String message = "Received message: " + m;
        return message;
    }
}

在 AWS Lambda 上部署它时,它可以完美运行(可以找到完整的项目 here)。

但是,如果我使用 Azure Functions Core Tools 运行与本地 Azure Functions 部署相同的函数,则在调用该函数时会出现以下异常:

24.01.19 21:58:50] Caused by: java.lang.ClassCastException: reactor.core.publisher.FluxJust cannot be cast to java.lang.String
[24.01.19 21:58:50]     at de.margul.awstutorials.springcloudfunction.function.EchoFunction.apply(EchoFunction.java:9)
[24.01.19 21:58:50]     at org.springframework.cloud.function.adapter.azure.AzureSpringBootRequestHandler.handleRequest(AzureSpringBootRequestHandler.java:56)
[24.01.19 21:58:50]     at de.margul.awstutorials.springcloudfunction.azure.handler.FunctionHandler.execute(FunctionHandler.java:19)
[24.01.19 21:58:50]     ... 16 more 

由于某种原因,该函数似乎期望使用 Flux 而不是 String。 我认为这可能与 [the documentation] (https://cloud.spring.io/spring-cloud-static/spring-cloud-function/2.0.0.RELEASE/single/spring-cloud-function.html#_function_catalog_and_flexible_function_signatures) 所说的有关:

Spring Cloud Function 的主要特性之一是为用户定义的函数适配和支持一系列类型签名,同时提供一致的执行模型。这就是为什么所有用户定义的函数都由 FunctionCatalog 使用 Project Reactor 定义的原语(即 Flux 和 Mono)转换为规范表示。例如,用户可以提供一个 Function 类型的 bean,FunctionCatalog 会将它包装成一个 Function,Flux>。

所以问题可能与此有关:

如果我按以下方式更改功能,它会起作用:

@Component
public class EchoFunction implements Function<String, Flux<String>> {

    @Override
    public Flux<String> apply(String m) {
        String message = "Received message: "+m;
        return Flux.just(message);
    }
}

我的函数处理程序如下所示:

public class FunctionHandler extends AzureSpringBootRequestHandler<String, String> {
    @FunctionName("createEntityFunction")
    public String execute(@HttpTrigger(name = "req", methods = {
        HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<String> entity,
        ExecutionContext context) {
        return handleRequest(entity.getBody(), context);
    }

    @Bean
    public EchoFunction createEntityFunction() {
        return new EchoFunction();
    }
}

对于 AWS 部署,我有以下依赖项:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-function-adapter-aws</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-lambda-java-core</artifactId>
        <version>1.2.0</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-lambda-java-events</artifactId>
        <version>2.2.5</version>
    </dependency>
</dependencies>

对于 Azure 部署,我只有一个依赖项:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-function-adapter-azure</artifactId>
    <version>2.0.0</version>
</dependency>

我已经查看了这两个适配器的源代码: 在 AWS 上,SpringBootRequestHandler 调用目标函数(在第 48 行)。

在 Azure 上,AzureSpringBootRequestHandler 调用目标函数(在第 56 行)。

对我来说,看起来在这两种情况下,都交出了 Flux。 但是,对于 AWS 适配器,对象显然是在两者之间的某个位置展开的。 但 Azure 适配器并非如此。

有什么想法吗?

【问题讨论】:

    标签: spring-boot azure-functions spring-cloud spring-cloud-function


    【解决方案1】:

    @margul 抱歉回复晚了/如果没有新创建的spring-cloud-function 标签,您的问题有点丢失。 我只是看了看它和issue you opened in GH,这似乎是我们这边的一个错误。 基本上,如果我们在目录中找不到函数,我们就回退到 bean 工厂。这种方法的问题是 bean factory 有原始函数 bean(函数尚未流动),因此 ClassCast 异常。

    无论如何,我会在 GH 中解决剩下的问题。

    只是为了关闭它,请参阅this issue

    【讨论】:

      猜你喜欢
      • 2020-11-03
      • 1970-01-01
      • 2020-10-30
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多