我目前正在研究 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 适配器并非如此。
任何想法为什么?