Есть ли простой способ составления списка потребительских компонентов для интерфейса? - PullRequest
1 голос
/ 13 февраля 2020

Товарищи по кодированию,

В настоящее время я пытаюсь найти простой и краткий способ получить список услуг / компонентов, которые используют данный интерфейс. Я использую оболочку gogo работающего сервера Liferay 7.1.x и, похоже, не могу найти простой и прямой способ сделать это.

Мы хотим переопределить ссылки на использованный сервис через OSGI-конфигурацию , но сначала нужно найти все компоненты, использующие его. Поскольку существуют неохотные ссылки на сервисный компонент c, простое предоставление альтернативы с более высоким рейтингом не является жизнеспособным решением.

Вот наборы gogo, которые я использую:

   35|Active     |    6|Apache Felix Gogo Command (1.0.2)|1.0.2
   36|Active     |    6|Apache Felix Gogo Runtime (1.1.0.LIFERAY-PATCHED-2)|1.1.0.LIFERAY-PATCHED-2
   72|Active     |    6|Apache Felix Gogo Shell (1.1.0)|1.1.0
  542|Active     |   10|Liferay Foundation - Liferay Gogo Shell - Impl (1.0.13)|1.0.13
  543|Active     |   10|Liferay Gogo Shell Web (2.0.25)|2.0.25

До сих пор я был в состоянии перечислить всех провайдеров интерфейса через se (interface=com.liferay.saml.runtime.servlet.profile.WebSsoProfile):

{com.liferay.saml.runtime.profile.WebSsoProfile, com.liferay.saml.runtime.servlet.profile.WebSsoProfile}={service.id=6293, service.bundleid=79, service.scope=bundle, component.name=com.liferay.saml.opensaml.integration.internal.servlet.profile.WebSsoProfileImpl, component.id=3963}
  "Registered by bundle:" de.haufe.leong.com.liferay.saml.opensaml.integration [79]
  "Bundles using service"
    com.liferay.saml.web_2.0.11 [82]
    com.liferay.saml.impl_2.0.12 [78]

Просмотреть все требования к пакетам через: inspect cap service:

com.liferay.saml.impl_2.0.12 [78] requires:
...
service; com.liferay.saml.runtime.profile.WebSsoProfile, com.liferay.saml.runtime.servlet.profile.WebSsoProfile provided by:
   de.haufe.leong.com.liferay.saml.opensaml.integration [79]
...

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

Единственное решение, которое я вижу до сих пор, - перечисление всех предоставляемых услуг. из этих пакетов через scr:list bid, а затем проверьте каждую службу с помощью scr:info componentId, чтобы узнать, использует ли она службу WebSsoProfile.

Ребята, знаете ли вы более быстрый способ поиска служб с помощью службы WebSsoProfile?


[РЕДАКТИРОВАТЬ]: мы решили проблему, не предоставляя переопределения конфигурации для всех потребителей службы WebSsoProfile, а скорее гарантировав, что наша реализация используется отключение службы по умолчанию при запуске сервера. Вы можете увидеть подход, описанный здесь .

В любом случае для целей отладки этот вид поиска был бы очень полезен. Поэтому, если кто-то знает способ получения списка всех пользователей интерфейса, пожалуйста, опубликуйте свое решение!

1 Ответ

2 голосов
/ 13 февраля 2020

Стандартное решение - использование команды inspect. Он имеет специальное пространство имен для сервисов. Поскольку регистрация службы - это возможность , вы можете использовать inspect capability service:

g! inspect c service
org.apache.felix.framework [0] provides:
----------------------------------------
service; org.osgi.service.resolver.Resolver with properties:
   service.bundleid = 0
   service.id = 1
   service.scope = singleton
service; org.osgi.service.packageadmin.PackageAdmin with properties:
   service.bundleid = 0
   service.id = 2
   service.scope = singleton
service; org.osgi.service.startlevel.StartLevel with properties:
   service.bundleid = 0
   service.id = 3
   service.scope = singleton

....

Однако я считаю эту команду совершенно бесполезной. Команда негибкая и имеет ужасный результат.

Однако, Gogo намного сильнее, чем люди думают. Например, вы можете использовать все методы в контексте пакета.

g! servicereferences org.osgi.service.startlevel.StartLevel null
000003   0 StartLevel

Если вы хотите увидеть свойства каждого сервиса:

g! each (servicereferences org.osgi.service.startlevel.StartLevel null) { $it properties }
[service.id=3, objectClass=[Ljava.lang.String;@4acd14d7, service.scope=singleton, service.bundleid=0]

Вы можете сделать это встроенным -in функция:

g! srv = { servicereferences $1 null }
servicereferences $1 null
g! srv org.osgi.service.startlevel.StartLevel
000003   0 StartLevel                               

К сожалению, OSGi добавил перегруженный метод в контексте пакета для getServiceReferences(), который выбрасывает NPE при вызове с нулем. Gogo ужасно с перегруженными методами :-(

Однако добавить собственную команду с декларативным компонентом службы тривиально. Вы можете использовать следующее:

@GogoCommand(scope="service", function="srv")
@Component(service=ServiceCommand.class)
public class ServiceCommand {

    @Activate
    BundleContext context;        

    @Descriptor("List all services")
    public ServiceReference<?>[] srv() throws InvalidSyntaxException {
        return context.getAllServiceReferences(null, null);
    }

    @Descriptor("List all services that match the name")
    public ServiceReference<?>[] srv(
            String... names)
            throws InvalidSyntaxException {
        ServiceReference<?>[] allServiceReferences = 
            context.getAllServiceReferences(null,null);
        if ( allServiceReferences==null)
            return new ServiceReference[0];
        return Stream.of(allServiceReferences)
                .filter(r -> {
                    String[] objectClass = (String[]) r.getProperty(Constants.OBJECTCLASS);
                    for (String oc : objectClass) {
                        for (String name : names)
                            if (oc.contains(name))
                                return true;
                    }
                    return names.length == 0;
                }).sorted().toArray(ServiceReference[]::new);
    }
}

Это добавляет команду srv к Gogo:

g! srv Help Basic
000004   1 Basic                                    
000005   1 Inspect   

Обновление Если вы хотите узнать, какие пакеты используют указанную службу c, вы можете используйте:

g! each (srv X) { $it usingbundles }

Убедитесь, что у вас есть следующие зависимости от вашего classpath:

-buildpath: \
    org.osgi.service.component.annotations,\
    org.apache.felix.gogo.runtime, \
    org.osgi.framework
...