Как подписаться на сообщения, используя DAPR, когда Spring Boot настраивает путь контекста сервлета

Вопрос или проблема

Приложение Springboot хочет подписаться на сообщение kakfa через dapr в следующем коде:

@RestController
@RequiredArgsConstructor
public class HelloController {

    @Topic(name = "test", pubsubName = "pubsub")
    @PostMapping(path = "/test", consumes = MediaType.ALL_VALUE)
    public Mono<ResponseEntity> getMes(@RequestBody(required = false) CloudEvent<String> cloudEvent) {
        return Mono.fromSupplier(() -> {
            try {
                log.info("{}",cloudEvent.getData());
                return ResponseEntity.ok("SUCCESS");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }
}

application.properties

server.port=3002
server.servlet.context-path=/service-a

Произойдут ошибки Sidecar

time="2024-10-12T10:55:28.5958885+08:00" level=error msg="неподдерживаемая ошибка, возвращенная от приложения при обработке события pub/sub aa2cc953-98d5-4d13-80fb-37430f9983bc: 
<!doctype html><html lang=\"en\"><head><title>HTTP Status 404 鈥� Not Found</title>
<style type=\"text/css\">
body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head>
<body>
<h1>HTTP Status 404 鈥� Not Found</h1><
/body>
</html>
. код состояния, который был возвращен: 404" app_id=service-a instance=xxx scope=dapr.runtime.processor.pubsub type=log ver=1.13.4

Когда я аннотирую server.servlet.context-path, это будет работать успешно

application.properties

server.port=3002
#server.servlet.context-path=/service-a

Итак, когда springboot настраивает server.servlet.context-path, как я могу добиться, чтобы это успешно работало с dapr, подписываясь на сообщения kafka?

Ответ или решение

Для успешной подписки на сообщения Kafka в приложении Spring Boot с использованием Dapr, когда в конфигурации установлено server.servlet.context-path, необходимо учитывать несколько важных аспектов. Эта проблема связана с конфигурацией пути контекста, что может привести к ошибкам, связанным с недоступностью конечной точки при обработке сообщений. Рассмотрим, как это можно исправить.

Проблема

Когда server.servlet.context-path установлен, все пути API будут сдвинуты на заданный контекстный путь. Например, если ваш контроллер определен с аннотацией @PostMapping(path = "/test"), реальный путь для доступа к этому контроллеру будет выглядеть как /service-a/test. Однако Dapr ожидает, что конечная точка для подписки будет находиться по адресу http://localhost:3002/test, что и вызывает ошибку 404, так как фактически доступ к контроллеру осуществляется по адресу http://localhost:3002/service-a/test.

Решение

Чтобы поправить это, нужно указать Dapr о том, что конечная точка для подписки находится по пути с учетом контекстного пути. Для этого можно воспользоваться следующим подходом:

  1. Убедитесь, что ваш контроллер должным образом настроен.
@RestController
@RequiredArgsConstructor
public class HelloController {

    @Topic(name = "test", pubsubName = "pubsub")
    @PostMapping(path = "/test", consumes = MediaType.ALL_VALUE)
    public Mono<ResponseEntity> getMes(@RequestBody(required = false) CloudEvent<String> cloudEvent) {
        return Mono.fromSupplier(() -> {
            try {
                log.info("{}", cloudEvent.getData());
                return ResponseEntity.ok("SUCCESS");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }
}
  1. В файле application.properties конфигурация остается прежней:
server.port=3002
server.servlet.context-path=/service-a
  1. Теперь необходимо указать Dapr, чтобы он обращался к вашему приложению по правильному контекстному пути. Это можно добиться с помощью конфигурационного файла Dapr или указания как параметра в командной строке при запуске Dapr.

Пример конфигурации для Dapr:

pubsub:
  pubsub:
    allow_insecure: true
    subscriptions:
      - topic: test
        route: /service-a/test
  1. При запуске приложения Dapr, убедитесь, что вы указываете путь контекста:
dapr run --app-id service-a --app-port 3002 --dapr-http-port 3500 -- dotnet run

или

dapr run --app-id service-a --app-port 3002 --dapr-http-port 3500 -- java -jar your-spring-boot-app.jar

Заключение

Следуя этим шагам, вы сможете правильно настроить подписку на сообщения Kafka через Dapr в приложении Spring Boot с установленным context-path. Это позволит избежать ошибок 404 и обеспечит корректное функционирование вашего приложения. Если у вас будут дополнительные вопросы, всегда можно обратиться к документации Dapr или сообществу для получения более конкретной помощи.

Оцените материал
Добавить комментарий

Капча загружается...