繁体   English   中英

如何使用声明式服务正确扩展 OSGi 服务?

[英]How to scale an OSGi Service with Declarative Services correctly?

项目描述:

我有一个简单的 OSGi 演示项目。 域是具有多种传感器类型的气象站。 每个传感器将其数据发送到气象站。 通过 API,数据通过 plot 在网站上公开和可视化。

目标:

例如:我目前有三种不同的传感器类型。 一种用于测量风速、温度和湿度。 气象站应该有多个风传感器实例( Cardinality.MULTIPLE )。

现状:

目前我正在通过创建WindSpeedSensorWindSpeedAdvancedSensor服务来解决这个问题。 我已经为 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM