0

我目前正在研究 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 上部署它时,它可以完美运行(可以在此处找到完整的项目)。

但是,如果我使用 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。我认为这可能与[文档]有关(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 适配器并非如此。

任何想法为什么?

4

1 回答 1

0

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

无论如何,我将在 GH 中解决其余的问题。

只是为了关闭它,请看这个问题

于 2019-02-22T07:39:10.413 回答