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

How to map service factory PIDs to their `ObjectClassDefinition`

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

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

这是将工厂 PID 映射到它们的最直接方法吗ObjectClassDefinition:

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

或者,是否有其他一些 OSGi 魔术可以通过服务工厂 PID 以编程方式查询,returns 比上述过程更快 ObjectClassDefinition 的东西?

更新 1

退一步说,我正在为我的每个可配置组件编写一个围绕 ConfigurationAdmin 的 CRUD 包装器。我试图避免 createFoodeleteFooupdateFoocreateBar,...我的应用程序恰好适合 URI。所以我的工作方法是使用 Metatype Service,传入一个解析的 URI 查询(Map<String, List<String>>),然后利用 Metatype Service 来验证和重建这些值,循环回 OP。 (另一方面,对我来说似乎是一个不太漂亮的 hack。)

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

The bnd metatype annotations are deprecated in bnd 3.2 and will be removed in bnd 4.0. These annotations are replaced by the OSGi metatype annotations.

所以我不想依赖那个包,如果它很快就会消失。我查看了 Felix 的做法,不想使用它们的等价物 Configurable class。我全神贯注于不同的方法!

更新 2

进一步减少,我想在调用 ConfigurationAdmin.createFactoryConfig 之前验证潜在的用户提供的 key/values 配置属性,以确保它们适用于某些配置 pid。也许这是矫枉过正?

我曾经创建一个class,它采用配置class,创建一个代理,然后使用这个代理来获取方法的名称和类型。它是这样使用的:

 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 方法上,它将使用最后调用的代理方法来识别 属性。然后它会根据方法的 return 值将给定值转换为 属性 类型。 bnd 转换器非常适合这个,但我认为 Felix 现在有一个标准的 OSGi 转换器。 (这是基于bnd转换器的思想。)

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

所以这将允许您进行往返配置。不用担心类型,它们会自动归位。

已更新这是在我更好地理解问题后更新的

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

添加了示例