[英]How to scale an OSGi Service with Declarative Services correctly?
项目描述:
我有一个简单的 OSGi 演示项目。 域是具有多种传感器类型的气象站。 每个传感器将其数据发送到气象站。 通过 API,数据通过 plot 在网站上公开和可视化。
目标:
例如:我目前有三种不同的传感器类型。 一种用于测量风速、温度和湿度。 气象站应该有多个风传感器实例( Cardinality.MULTIPLE )。
现状:
目前我正在通过创建WindSpeedSensor和WindSpeedAdvancedSensor服务来解决这个问题。 我已经为 Apache Karaf实现了一个自定义命令,我可以在其中向我的服务发送特定的配置命令。 因此,传感器可以配置为在特定范围内生成测量值。
所需条件:
最佳解决方案是通过Karaf 命令行启动WindSpeedSensor的其他实例。 对于WeatherStation class,不应该需要人工WindSpeedSensors来实现多服务的目标。
问题:
我怎样才能做到这一点? 我是 OSGi 和声明式服务的新手,我很好奇 OSGi 专家如何解决这个问题。 提前感谢您的时间和反馈。
您可以使用出厂配置(请参阅https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-deployment )。 对于工厂 pid 下的每个配置,DS 都会创建一个组件配置。 这允许根据 Configuration Admin 中的工厂配置多次创建一个组件。
我只将 OSGi 与 Karaf 一起使用,因此对于其他环境可能会有所不同。
如果您需要为每个配置文件提供 OSGi 服务,您可以使用声明性服务注释设置此类服务,例如像这样。
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.metatype.annotations.Designate;
import com.example.service.config.ExampleServiceConfig;
@Component(
immediate = true, service = ExampleService.class,
configurationPolicy = ConfigurationPolicy.REQUIRE,
configurationPid = "com.example.service.ExampleService"
)
@Designate(ocd = ExampleServiceConfig.class, factory = true)
public class ExampleService {
@Activate
public void onServiceActivate(BundleContext context, ExampleServiceConfig config){
System.out.println(config.hello_message());
}
}
然后为服务定义类型安全配置,例如:
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@ObjectClassDefinition(name = "ExampleService Configuration")
public @interface ExampleServiceConfig {
String hello_message() default "hello world";
String osgi_jndi_service_name() default "unique.service.name";
}
由于 singleton 配置使用文件名,如<configurationPid>.cfg
工厂配置使用格式<configurationPid>-<InstanceName>.cfg
因此创建上面的ExampleService
的两个实例,您可以创建例如以下配置:
com.example.service.ExampleService-InstanceA.cfg
hello.message=Hello from Instance A
osgi.jdni.service.name=InstanceA
com.example.service.ExampleService-InstanceB.cfg
hello.message=Hello from Instance B
osgi.jdni.service.name=InstanceB
至少在 Karaf 中,这将创建两个 ExampleService 实例和两个具有某种唯一 guid 的配置(而不是实例名称)。 要引用特定的服务实例,您可以使用引用注释中的目标属性。
@Reference(
target = "(osgi.jdni.service.name=InstanceA)"
)
ExampleService exampleService;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.