如何将服务工厂PID映射到它们的`ObjectClassDefinition`

时间:2018-03-12 15:09:46

标签: osgi

在OSGi R6中,我希望以编程方式验证用户提供的字符串配置属性加上服务工厂PID,以及声明它配置此PID的任何可配置@Component(或ManagedServiceFactory)所支持的内容。 @Component(configurationPid=some.service.factory.pid, ...)。另外,我想以某种方式将有效的String属性转换为适当的属性类型。通过OSGi Compendium看来,Metatype Service似乎正是我所寻找的。

如果这是正确的,请给出以下内容:

  • 适用的组件使用组件属性类型来指定其配置
  • 组件属性类型使用@ObjectClassDefinition
  • 进行注释
  • 组件使用@Designate进行注释,并将其映射到适用的@ObjectClassDefinition

这是将工厂PID映射到ObjectClassDefinition的最直接的方式:

  • 致电BundleContext.getBundles()。对于每个捆绑包,请致电MetaTypeService.getMetaTypeInformation(Bundle)
  • 对于每个返回的MetaTypeInformation来电MetaTypeInformation.getFactoryPids()并过滤我关心的工厂PID。
  • 对于适用的MetaTypeInformation,请使用默认或特定区域设置调用MetaTypeInformation.getObjectClassDefinition(String, String)以获取ObjectClassDefinition

(切向,以上每次执行似乎都很昂贵,因此缓存捆绑包ID,将它们映射到关联的工厂PID,并保持缓存最新以某种方式似乎是合适的。)

或者,是否有其他一些OSGi魔法可以通过服务工厂PID以编程方式查询,返回的内容比上述过程快一些ObjectClassDefinition

更新1

退一步,我为每个可配置组件在ConfigurationAdmin周围编写了一个CRUD包装器。我试图避免createFoodeleteFooupdateFoocreateBar,...我的应用程序恰好适合URI。所以我的工作方法是使用元类型服务,传入解析的URI查询(Map<String, List<String>>),然后利用元类型服务来验证和重建这些值,然后回到OP。 (另一方面,对我来说,这似乎是一个不太好的黑客攻击。)

另一种方法是使用aQute.bnd.annotations.metatype.Configurable.createConfigurable(Class, Map),我更喜欢!直到我看到this bnd GitHub comment

  

bnd元数据类型注释在bnd 3.2中已弃用,将在bnd 4.0中删除。这些注释被OSGi元类型注释取代。

所以如果它很快消失,我就不想依赖它。我查看了费利克斯做了什么,并且不想使用等效的Configurable课程。我全神贯注于不同的方法!

更新2

减少这一点,我希望验证用户提供的可能的键/值配置属性,以确保它们在调用ConfigurationAdmin.createFactoryConfig之前适用于某些配置pid。也许这有点矫枉过正?

1 个答案:

答案 0 :(得分:1)

我曾经创建了一个类,它接受配置类,创建代理,然后使用此代理获取方法的名称和类型。它是用这样的东西:

 ConfigHelper<Config> helper = new ConfigHelper( Config.class, "my.pid");
 int port = helper.get().port(); // get the configuration
 helper.set( helper.get().port(),  1000);
 helper.update();

get获取的代理将在调用其中一个方法时记录该方法。在set方法上,它将使用最后一个调用的代理方法来标识属性。然后它会根据方法的返回值将给定值转换为属性类型。 bnd转换器是理想的,但我认为Felix现在有一个标准的OSGi转换器。 (这是基于bnd转换器的想法。)

然后将方法名称用作属性。必要的名称修改在OSGi规范中定义。这允许您使用下划线,Java关键字和点名。

因此,这将允许您往返配置。不用担心类型,它们会自动落在他们的位置。

已更新在我更好地理解问题

之后会更新

已更新2 https://github.com/aQute-os/biz.aQute.osgi.util/tree/master/biz.aQute.osgi.configuration.util

添加了示例