Функция Spring Cloud ожидает развертывание Flux<String> вместо String при развертывании в функциях Azure
В настоящее время я изучаю Spring Cloud Function и ее возможности для развертывания одной функции в разных облачных средах (функции AWS Lambda и Azure).
Моя функция выглядит так (конечно, очень упрощенно):
@Component
public class EchoFunction implements Function<String, String> {
@Override
public String apply(String m) {
String message = "Received message: " + m;
return message;
}
}
При его развертывании на AWS Lambda он работает идеально (полный проект можно найти здесь).
Однако если я запускаю ту же функцию, что и локальное развертывание функций Azure с использованием основных инструментов функций Azure, при вызове функции я получаю следующее исключение:
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
По некоторым причинам, функция, кажется, ожидает поток вместо строки. Я думаю, что это может быть связано с тем, что [документация] ( https://cloud.spring.io/spring-cloud-static/spring-cloud-function/2.0.0.RELEASE/single/spring-cloud-function.html) говорит об этом:
Одной из основных функций Spring Cloud Function является адаптация и поддержка диапазона сигнатур типов для пользовательских функций, обеспечивая при этом согласованную модель выполнения. Вот почему все пользовательские функции преобразуются в каноническое представление с помощью FunctionCatalog с использованием примитивов, определенных Project Reactor (т. Е. Flux и Mono). Например, пользователи могут предоставить bean-компонент типа Function, а 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.
Есть идеи почему?
1 ответ
@margul Извините за поздний ответ / Без недавно созданного spring-cloud-function
пометить ваш вопрос был отчасти потерян. Я только что посмотрел на него, а также на проблему, которую вы открыли в GH, и это похоже на ошибку с нашей стороны. По сути, кажется, что если мы не можем найти функцию в каталоге, мы возвращаемся к фабрике бобов. Проблема с этим подходом состоит в том, что фабрика компонентов имеет необработанный компонент функции (функция еще не изменена), следовательно, исключение ClassCast.
В любом случае, я расскажу об остальном в GH.
Просто чтобы закрыть это, пожалуйста, посмотрите эту проблему