Проблема с объектом области запроса Sling/OSGi. Как я могу получить доступ к одному и тому же экземпляру объекта в фильтре и классе обслуживания (в том же контексте запроса)?

Я работаю в среде 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.

Мое резервное решение, которое мне не нравится:
Я мог бы просто вытащить идентификатор транзакции в своем сервлете и переходить между всеми различными классами/методами, пока не достигну класса службы, но это какая-то хрень.

Кто-нибудь может помочь, пожалуйста?


person Shea    schedule 09.04.2021    source источник


Ответы (1)


Возможно, это поможет вам http://blog.vogella.com/2017/02/13/control-osgi-ds-component-instances/

Установка для компонента службы значения PROTOTYPE не означает, что каждый потребитель автоматически получает отдельный экземпляр службы. По умолчанию результат будет таким же, как и при использовании области BUNDLE. Так что если вы запустите приложение с обновленным сервисом Hitman, вы получите тот же результат, что и раньше. Причиной этого является область ссылок, которая также была введена в DS 1.3. Он настраивается на стороне потребителя через @Reference и указывает, как должна быть разрешена ссылка на службу. Возможны три значения:

BUNDLE Все экземпляры компонентов в комплекте будут использовать один и тот же объект службы. (по умолчанию) PROTOTYPE Каждый экземпляр компонента в комплекте может использовать отдельный объект службы. PROTOTYPE_REQUIRED Каждый экземпляр компонента в комплекте должен использовать отдельный объект службы.

person mkovacek    schedule 08.05.2021