简体   繁体   English

从骆驼属性占位符填充java.util.Properties

[英]Populate java.util.Properties from camel property placeholder

I have just started learning OSGi and camel and I am working on some services that are already implemented. 我刚刚开始学习OSGi和骆驼,并且正在从事一些已经实现的服务。 I have a bundle that is configured to run on Servicemix with the help of OSGi blueprint somewhat like this: 我有一个配置为借助OSGi蓝图在Servicemix上运行的捆绑软件,如下所示:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/blueprint/core"
xsi:schemaLocation="
    http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
    http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
    http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
    http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd">

<camelContext id="ctx1"
    xmlns="http://camel.apache.org/schema/blueprint"
    xsi:schemaLocation="http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
    <propertyPlaceholder location="properties/config.properties"/>
    <routeBuilder ref="..." />
</camelContext>

Currently, the config.properties is located inside the bundle but I am trying to externalize it. 当前, config.properties位于捆绑包内,但我正在尝试将其外部化。

So, I changed my blueprint to: 因此,我将蓝图更改为:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/blueprint/core"
xsi:schemaLocation="
    http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
    http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
    http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
    http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd">

<camelContext id="ctx1"
    xmlns="http://camel.apache.org/schema/blueprint"
    xsi:schemaLocation="http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
    <propertyPlaceholder location="${karaf.home}/etc/config.properties"/>
    <routeBuilder ref="..." />
</camelContext>

... and this configuration works perfectly fine. ...并且此配置工作正常。

The problem I am facing is that this property file is also used in multiple locations via java.util.properties loaded as a simple file within a static code block in a util file. 我面临的问题是,该属性文件还通过java.util.properties在多个位置使用,该java.util.properties作为简单文件加载到util文件中的静态代码块中。

Can I use the properties loaded inside camel context in my Java code (other than camel code)? 我可以在Java代码中使用骆驼上下文中加载的属性(骆驼代码除外)吗?

If that is not possible, then how should I load the property files located in servicemix classpath to be used in both camel context and java code, with minimal code changes in my current implementation. 如果这不可能,那么我应该如何加载位于servicemix类路径中的属性文件以在骆驼上下文和Java代码中使用, 在当前实现中的代码更改最少

I would discourage the use of static access to the Property file in a OSGI environment. 我不建议在OSGI环境中使用对属性文件的静态访问。

For me the best way is to create an OSGI service which expose validation method or the properties themselves (with getter/setter) like this: 对我而言,最好的方法是创建一个OSGI服务,该服务公开验证方法或属性本身(使用getter / setter方法),如下所示:

<service ref="myConfig">
    <interfaces>
        <value>org.osgi.service.cm.ManagedService</value>
        <value>com.mycompany.services.common.api.MyConfig</value>
    </interfaces>
    <service-properties>
        <entry key="service.pid" value="config.properties" />
    </service-properties>
</service>

<bean id="myConfig" class="com.mycompany.services.common.config.MyConfigImpl" />

After in any OSGI bundle which needs to access the property, it can referenced by: 在需要访问该属性的任何OSGI捆绑包之后,可以通过以下方式引用它:

<reference id="myConfig" interface="com.mycompany.services.common.api.MyConfig"
    activation="eager" availability="mandatory" />

Before using this way we had a lot of deadlocks between bundles because the usage of static method and LOCK's. 在使用这种方法之前,由于静态方法和LOCK的使用,我们在束之间存在很多死锁。 Since we use the OSGI service, it work very well without problem when refreshing / deploying the bundles. 由于我们使用OSGI服务,因此在刷新/部署捆绑软件时,它可以很好地正常工作。

I assume you want to access your property file through any other OSGI bundle, not external code form the OSGI context. 我假设您想通过任何其他OSGI捆绑包访问属性文件,而不是通过OSGI上下文的外部代码访问。 If you want to access the property file outside the OSGI context, I suggest to create a (REST) Web-service over the mentioned interface ( <reference> ). 如果要在OSGI上下文之外访问属性文件,建议在上述接口( <reference> )上创建(REST)Web服务。

Implementation example: 实施示例:

public class MyConfigImpl implements MyConfig, ManagedService {

    // This is just the property keys 
    private final static String COLORS = "my.valid.colors";
    private final static String PROP1 = "my.property.1";
    private final static String PROP2 = "my.property.2";
    private final static String PROP3 = "my.property.3";

    // For validating against some properties
    private List<String> colors = new ArrayList<>();

    // For extracting a subset of properties
    private String prop1;
    private String prop2;
    private String prop3;

    // The whole set os properties published as Dictionary (could be transformed in Map as well)
    private Dictionary props;

    @Override // Implements MyConfig.isValidColor(String color)
    public Boolean isValidColor(String color) {
        if (colors.contains(color)) {
            return true;
        } else {
            return false;
        }
    }

    @Override // Implements MyConfig.getPropertyOne()
    public String getPropertyOne(){
        return prop1;
    }

    @Override // Implements MyConfig.getPropertyTwo()
    public String getPropertyTwo(){
        return prop2;
    }

    @Override // Implements MyConfig.getPropertyThree()
    public String getPropertyThree(){
        return prop3;
    }

    @Override // Implements MyConfig.getProperties()
    public Dictionary getProperties(){
        return props;
    }


    // This implements the ManagedService.updated()
    @Override 
    public void updated(@SuppressWarnings("rawtypes") Dictionary properties) throws ConfigurationException {

        log.debug("Reading properties: {}", properties);
        if (properties == null) {
            return;
        }

        updateConfiguration(properties);

    }

    private void updateConfiguration(Dictionary properties) {

        // MyUtil.asListOfString is just a helper to convert comma separated string to list of String
        // This is just an example
        this.colors = MyUtil.asListOfStrings((String) properties.get(COLORS));

        this.prop1 = properties.get(PROP1);
        this.prop2 = properties.get(PROP2);
        this.prop3 = properties.get(PROP3);
        this.props = properties;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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