У меня есть сервис, который вызывает дюжину других сервисов.Это читает тему Кафки, используя @StreamListener
в классе контроллера.В целях прослеживаемости те же самые заголовки (исходный идентификатор запроса) из сообщения Kafka также необходимо перенаправить во все другие службы
Традиционно, с @PostMapping("/path")
или GetMapping
генерируется контекст запросаи можно получить доступ к заголовкам из любого места, используя RequestContextHolder.currentRequestAttributes()
, и я бы просто передавал объект HttpHeaders
в RequestEntity
всякий раз, когда мне нужно сделать внешний вызов
Однако в StreamListener
нетгенерируется контекст запроса, и попытка доступа к RequestContextHolder
приводит к исключению
Вот пример того, что я пытался сделать, что привело к исключению:
public class Controller {
@Autowired Service1 service1
@Autowired Service2 service2
@StreamListener("stream")
public void processMessage(Model model) {
service1.execute(model);
service2.execute(model);
}
}
public class Service {
RestTemplate restTemplate;
public void execute(Model model){
// Do some stuff
HttpHeaders httpHeaders = RequestContextHolder.currentRequestAttributes().someCodeToGetHttpHeaders();
HttpEntity<Model> request = new HttpEntity(model, httpHeaders);
restTemplate.exchange(url, HttpMethod.POST, request, String.class);
}
}
Мой текущий обходной путьэто изменить StreamListener
на PostMapping
и получить еще один PostMapping
, который вызывает, чтобы можно было сгенерировать контекст запроса.Другой вариант состоял в том, чтобы использовать ThreadLocal
, но он выглядит просто как janky
Я знаю аннотацию @Headers MessageHeaders
для доступа к заголовкам потока, однако, это не легко сделать без передачи заголовков вниздля каждой службы и может повлиять на многие модульные тесты
В идеале мне нужен способ создания собственного контекста запроса (или какой бы то ни было правильной терминологии), чтобы иметь место для хранения объектов области запроса (* 1027)*) или другой потокобезопасный способ передачи заголовков запросов по стеку без добавления аргумента запроса к service.execute