Функция Spring Cloud ожидает развертывания Flux <String>вместо String при развертывании в функциях Azure - PullRequest
0 голосов
/ 25 января 2019

В настоящее время я изучаю 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#_function_catalog_and_flexible_function_signatures) говорит об этом:

Одной из основных функций 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).

Для меня, похоже, в обоих случаях Флюс передается. Однако для адаптера AWS Объект развернут где-то посередине, очевидно. Но это не относится к адаптеру Azure.

Есть идеи, почему?

1 Ответ

0 голосов
/ 22 февраля 2019

@ margul Извините за поздний ответ / Без недавно созданного тега spring-cloud-function ваш вопрос был утерян. Я только что посмотрел на него, а также на проблему , которую вы открыли в GH , и это похоже на ошибку с нашей стороны. По сути, кажется, что если мы не можем найти функцию в каталоге, мы возвращаемся к фабрике бобов. Проблема этого подхода заключается в том, что фабрика бинов имеет необработанный компонент функции (функция еще не изменена), следовательно, исключение ClassCast.

Во всяком случае, я обращусь к остальным в GH.

Чтобы закрыть это, смотрите эту проблему

...