在OSGi R6中,我希望以编程方式验证用户提供的字符串配置属性加上服务工厂PID,以及声明它配置此PID的任何可配置@Component
(或ManagedServiceFactory
)所支持的内容。 @Component(configurationPid=some.service.factory.pid, ...)
。另外,我想以某种方式将有效的String属性转换为适当的属性类型。通过OSGi Compendium看来,Metatype Service似乎正是我所寻找的。 p>
如果这是正确的,请给出以下内容:
@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
?
退一步,我为每个可配置组件在ConfigurationAdmin
周围编写了一个CRUD包装器。我试图避免createFoo
,deleteFoo
,updateFoo
,createBar
,...我的应用程序恰好适合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
课程。我全神贯注于不同的方法!
减少这一点,我希望验证用户提供的可能的键/值配置属性,以确保它们在调用ConfigurationAdmin.createFactoryConfig
之前适用于某些配置pid。也许这有点矫枉过正?
答案 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
添加了示例