Если службы OSGi используют последнюю версию пакета, даже если установлено несколько версий пакета.

avatar
Anders S
1 июля 2021 в 19:35
79
2
1

Я столкнулся с проблемой OSGi, и я недостаточно хорошо разбираюсь в деталях OSGi, чтобы понять, что делать дальше.

Моя проблема такова:

  • У меня есть служба, которая находится за четко определенным интерфейсом и периодически создает файл в определенном месте. Это контролируется администратором конфигурации (через файл конфигурации в Karaf)
  • .
  • Некоторые компоненты предоставляют эту услугу другим через файл функций Karaf, связывая мою службу с определенной версией (1.X.0)
  • Другие компоненты предоставляют эту услугу в более новой версии (1.Y.0, где Y > X), либо через другой файл функций, либо просто добавляя ее в свой файл kar.

Поскольку это лишь незначительные изменения версии, службам-потребителям все равно, с какой службой они взаимодействуют (API тот же).

Моя проблема в том, что оба этих пакета активны в karaf, и существует условие гонки относительно того, кто перезапишет чей выходной файл. Я попытался превратить @Component в синглтон (используя scope = ServiceScope.SINGLETON), и, хотя это могло бы решить проблему каждого потребителя службы, использующего одну и ту же реализацию, проблема с перезаписью файлов сохраняется, поскольку обе службы активны.

В основном, я ищу способ сказать OSGi "не заморачиваться со старыми версиями, новая версия (которая такая же основная, как и другие) подходит для всех потребителей (которые используют по умолчанию [1.X,2[)

Поскольку файл конфигурации похож на "API" для включения моего сервиса, я хотел бы избежать наличия нескольких файлов конфигурации для разных версий.

Если возможно, я хотел бы оставить логику определения местоположения версии вне моей службы. Я предполагаю, что теоретически служба может прослушивать другие версии пакетов, предоставляющих тот же интерфейс службы, и предпринимать соответствующие действия, но мне это кажется очень громоздким. Наверняка есть лучший способ, который меньше влияет на код бизнес-логики (т.е. мой сервис)?

Источник

Ответы (2)

avatar
Christian Schneider
2 июля 2021 в 07:03
1

Для Apache Karaf существует специальный способ реализации первого решения от Питера (Удалить старый пакет).

Установите dependency=true в файле функций для пакета, который предоставляет услугу. Таким образом, Apache Karaf автоматически установит лучший пакет, соответствующий требованиям других ваших пакетов. В этом случае следует установить только поставляемый пакет с самым высоким дополнительным номером версии.

.
avatar
Peter Kriens
2 июля 2021 в 06:47
3

Конечно, простой ответ: зачем возиться со старым комплектом? Просто удалить?

В любом случае, обычный ответ: я не могу по какой-то причине. Некоторые решения в предпочтительном (моем) порядке:

  1. Удалить старый пакет
  2. Сделайте свои компоненты require конфигурацией и настройте соответствующий компонент, другой не запустится. Это в основном шаблон, который дал нам спецификацию Configurator. На самом деле это действительно хорошее решение, которое я использую везде. Это позволяет настроить приложение в мельчайших деталях.
  3. Просто устраните конфликт файлов конфигурации в пакетах.
  4. Используйте начальные уровни, чтобы никогда не запускать более старый пакет. Немного хака.
  5. Зарегистрируйте свойство службы в службе и разрешите фильтрацию ссылок по этому свойству. Кроличья нора.
  6. Используйте Service Hooks, чтобы отфильтровать старый сервис. Это вводит упорядочение, поскольку сервисный хук должен быть зарегистрирован до того, как кто-либо его использует. Поэтому я склонен уклоняться от этого. Вот реализация

Это типичный вариант использования, который, если оглянуться назад, сделал систему намного более сложной, чем ожидалось. Один подобный взлом не кажется таким уж плохим, но эти взломы имеют тенденцию размножаться, как кролики. OSGi — это чистые модули, взаимодействующие с четко определенными службами. Ваше описание кажется, что вы там, но затем неправильное решение проблемы снова приведет вас к большому кому грязи :-(