如何使用不同的属性占位符多次部署camel / blueprint服务

时间:2017-04-03 10:11:40

标签: apache-camel apache-karaf jbossfuse blueprint-osgi

通常我们会一次部署基于驼峰/蓝图的服务。每个服务都有自己的属性占位符,并且绑定了camel-context:

<cm:property-placeholder id="service-name.placeholder" persistent-id="service-name.blueprint">
    <cm:default-properties>
        ...
    </cm:default-properties>
</cm:property-placeholder>
...
<camelContext id="service-name-service-camel" xmlns="http://camel.apache.org/schema/blueprint"
    useMDCLogging="true">
    <propertyPlaceholder id="properties" location="blueprint:service-name.placeholder" />
    <routeBuilder ref="mainRoute"/>
</camelContext>

现在我们创建了一个我们想要多次部署的服务。每个实例都应使用自己的一组属性值。 我看到的唯一方法是在编译时设置属性占位符名称(maven过滤器),但这会导致不同的工件 - 坏。

有没有办法设置在运行时或开始时使用的属性占位符?

1 个答案:

答案 0 :(得分:1)

您可以使用ManagedServiceFactory和几行代码来完成。

为Factory定义一个bean,并注入BundleContext。选择Pid以便以后识别和配置此工厂:

<bean id="myServiceFactory" class="org.my.MyServiceFactory" init-method="init" destroy-method="destroy">
    <property name="bundleContext" ref="blueprintBundleContext"/>
    <property name="configurationPid" value="org.my.pid"/>
</bean>

实施服务工厂(不是工作代码,只是为了给你一个想法):

public class MyServiceFactory implements ManagedServiceFactory {

    private BundleContext bundleContext;

    private String configurationPid;

    public void setConfigurationPid(String configurationPid) {
       this.configurationPid = configurationPid;
    }

    public void setBundleContext(BundleContext bundleContext) {
       this.bundleContext = bundleContext;
    }

    public void init() {
        // your setup goes here
    }

    public void destroy() {
        // your shutdown logic goes here
    }

    @Override
    public String getName() {
        return configurationPid;
    }

    @Override
    public void updated(String pid, Dictionary dict) throws ConfigurationException { 
        // Instantiate each service with its own properties
        MyServiceImpl service = new MyServiceImpl(dict);
        Dictionary servProps = new Properties();
        servProps.put("custom.service.property", "an id or someting")
        bundleContext.registerService(MyServiceImpl.class.getName(), service, servProps);
        // save your servicereferences to unregister, eg in a map
        // you can customize your service by giving some property to later retrieve it
    }

    @Override
    public void deleted(String pid) {
        // get the ServiceReference from some map
        servicereference.unregister();
    }

}

ManagedServiceFactory有一个方法init()来设置所有必需的资源,一个destroy()方法来清理(例如通过取消注册所有服务)。

etc/org.my.pid-*.cfg中的每个配置文件创建一个新服务实例,例如创建3个服务实例:

etc/org.my.pid-serviceinstance1.cfg
etc/org.my.pid-serviceinstance2.cfg
etc/org.my.pid-whatever.cfg

要获取服务的特定实例,请使用某些自定义属性(例如我的示例中的custom.service.property)注册它们。然后在消费者包中请求MyService的实例custom.service.property = serviceinstance2 并且您已完成。

您甚至可以通过这种方式创建新的CamelContexts。 PacktPub网站上有完整的教程。

修改etc/org.my.pid-*中编写新文件时,将调用updated()方法并部署新服务。删除文件后,将调用deleted()方法,您必须销毁和取消注册该服务。当然,您可以使用JBoss / Karaf运行:-)添加/删除/修改文件,而无需停止主包。