Я работаю в среде Sling с аннотациями OSGi DS.
Предыстория: я работаю с микросервисами. Когда мы отправляем вызовы между ними, мы передаем и регистрируем идентификатор транзакции (который является просто UUID). Таким образом, мы можем легко отслеживать звонки между всеми различными службами. Это означает, что каждый веб-запрос имеет другой UUID. Обычно мы используем Spring Boot, но в данном случае я использую Sling в AEM.
Проблема: я не могу создать свой собственный компонент osgi с областью действия веб-запроса. Я попытался настроить его как область службы прототипа, но он просто не работает. Ниже приведен пример того, что, по моему мнению, должно работать, но это не так, потому что в моем классе обслуживания я получаю другой экземпляр класса RequestInfo, чем когда я получить экземпляр в классе Filter.
Объект области запроса:
@Component(service = RequestInfo.class, scope = ServiceScope.PROTOTYPE)
public class RequestInfo {
private String transactionId;
...
}
Фильтр:
@Component(service = Filter.class, immediate = true, property = { sling.filter.scope=REQUEST })
@ServiceRanking(0)
public class RequestInfoFilter implements Filter {
@Reference(scope = ReferenceScope.PROTOTYPE_REQUIRED)
private RequestInfo requestInfo;
@Override
public void doFilter(ServletRequest baseRequest, ServletResponse baseResponse, FilterChain filterChain) {
HttpServletRequest request = (HttpServletRequest) baseRequest;
HttpServletResponse response = (HttpServletResponse) baseResponse;
requestInfo.setTransactionId(...);
filterChain.doFilter(request, response);
}
...
}
Класс обслуживания:
@Component(service = MyService.class, immediate = true)
public class MyService {
@Reference(scope = ReferenceScope.PROTOTYPE_REQUIRED)
private RequestInfo requestInfo; <--- Does not pick up same instance of RequestInfo that filter had!!! Why??? It's still in the context of the same request!!!
public String callAnotherService {
String transactionID = requestInfo.getTransactionId();
... add ID as header and call another service with httpclient ...
}
}
Другие попытки решения:
- Я попытался сослаться на объект SlingHttpServletRequest внутри компонента, но это просто не сработало, если только я не расширил SlingAllMethodsServlet, что не подходит для класса службы.
- Я попытался настроить SlingModel, которая содержит информацию из запроса, но потом я не могу понять, как вставить экземпляр этой SlingModel в компонент OSGI.
Мое резервное решение, которое мне не нравится:
Я мог бы просто вытащить идентификатор транзакции в своем сервлете и переходить между всеми различными классами/методами, пока не достигну класса службы, но это какая-то хрень.
Кто-нибудь может помочь, пожалуйста?