【问题标题】:How to place bundle configuration/property file in /etc karaf folder如何将捆绑配置/属性文件放在 /etc karaf 文件夹中
【发布时间】:2015-06-29 17:09:49
【问题描述】:

我想部署 karaf 中部署的 bundle 的所有配置文件放在 karaf etc 文件夹中。我希望当捆绑配置文件发生变化时,karaf 会注意到这一点。

我有一个包含几个特性的发行版,一个 XML 特性的例子。我已经尝试了几件事,例如我将 conf 文件添加到如下功能中,但这不起作用。

<feature name="gc-backbone-mqtt" version="${linksmart.gc.version}">
    <feature version="${linksmart.gc.version}">gc-backbone-router</feature>
    <bundle>mvn:org.eclipse.paho/org.eclipse.paho.client.mqttv3/1.0.0</bundle>
    <feature version="${linksmart.gc.version}">gc-type-tunnelled</feature>
    <configfile finalname="/etc/mqttBackboneProtocol.cfg">mvn:eu.linksmart.gc/backbone.mqtt.impl/${linksmart.gc.version}/mqttprotocol.properties</configfile>
    <bundle>mvn:eu.linksmart.gc/backbone.mqtt.impl/${linksmart.gc.version}</bundle>
</feature>

我尝试过的一些事情:

http://karaf.922171.n3.nabble.com/OSGi-bundle-configuration-file-td4025438.html

http://www.liquid-reality.de/display/liquid/2011/09/23/Karaf+Tutorial+Part+2+-+Using+the+Configuration+Admin+Service

我不想复制带有特定路径的文件,如下所示:

有人知道怎么做吗?

更新

为了实现将配置文件部署在etc 文件夹中以便可以在外部重新配置捆绑包,我分三步完成:

构建配置文件:(Works

为了使配置文件可被 Maven 寻址,我在包 pom.xml 中添加了以下部分。这样配置文件就被部署到仓库了:

pom.xml

 <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-artifacts</id>
                        <phase>package</phase>
                        <goals>
                            <goal>attach-artifact</goal>
                        </goals>
                        <configuration>
                            <artifacts>
                                <artifact>
                                    <file>src/main/resources/mqttprotocol.properties</file>
                                    <type>cfg</type>
                                    <classifier>configuration</classifier>
                                </artifact>
                            </artifacts>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

在 karaf etc 中部署文件(Works

为了在 karaf etc文件夹中部署配置文件,我在功能文件中添加了 &lt;configfile&gt;,如下所示:

features.xml

    <feature name="gc-backbone-mqtt" version="${linksmart.gc.version}">
        <feature version="${linksmart.gc.version}">gc-backbone-router</feature>
        <bundle>mvn:org.eclipse.paho/org.eclipse.paho.client.mqttv3/1.0.0</bundle>
        <bundle>mvn:org.apache.felix/org.apache.felix.fileinstall/3.2.8</bundle>
        <configfile finalname="/etc/MQTTBackboneProtocol.cfg">mvn:eu.linksmart.gc/network.backbone.protocol.mqtt.impl/${linksmart.gc.version}/cfg/configuration</configfile>
        <feature version="${linksmart.gc.version}">gc-type-tunnelled</feature>          <bundle>mvn:eu.linksmart.gc/network.backbone.protocol.mqtt.impl/${linksmart.gc.version}</bundle>
    </feature>

捕获配置更改:(不起作用

为了捕获配置文件的更改,我添加了您建议的代码 (@Donald_W)。问题是我只收到文件通知位于deploy 文件夹中,但不在etc 中。我调试了这段代码,我发现etc 中的文件被专门称为这些文件的“侦听器”。那时我不知道如何成为etc中部署的文件的侦听器

【问题讨论】:

    标签: java osgi apache-karaf karaf


    【解决方案1】:

    您可以使用 Karaf 内置的 Felix 文件安装程序,它会在 etc 下的文件更改时为您提供回调。

    一旦您将实现ArtifactInstaller 的服务发布到OSGi 服务注册表中,FileInstallerWhiteboard pattern 将检测到它。

    <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.fileinstall</artifactId>
        <version>3.4.2</version>
        <scope>provided</scope>
    </dependency>
    

    示例代码(使用 iPojo,但 Blueprint / DS 也可以)是:

    package com.example.deployer.internal;
    
    import org.apache.felix.fileinstall.ArtifactInstaller;
    import org.apache.felix.ipojo.annotations.Component;
    import org.apache.felix.ipojo.annotations.Instantiate;
    import org.apache.felix.ipojo.annotations.Provides;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    
    @Instantiate()
    @Component(name = "propsDeployer")
    @Provides(specifications = ArtifactInstaller.class)
    public class PropsDeployer implements ArtifactInstaller {
        Logger logger = LoggerFactory.getLogger(JsonDeployer.class);
    
        @Override
        public void install(File artifact) throws Exception {
            logOutput("Installing",artifact);
        }
    
        @Override
        public void update(File artifact) throws Exception {
            logOutput("Updating",artifact);
        }
    
        @Override
        public void uninstall(File artifact) throws Exception {
            logger.info("Uninstalling artifact: {}", artifact.getName());
        }
    
        @Override
        public boolean canHandle(File artifact) {
            return artifact.getName().endsWith(".props");
        }
    
        private void logOutput(String action, File artifact) throws IOException {
            logger.info(action + " artifact: {}", artifact.getName());
            Properties props = new Properties();
            FileReader in = null;
            try {
                in = new FileReader(artifact.getCanonicalFile());
                props.load(in);
            } finally {
                if (in != null) {
                    in.close();
                }
            }
    
            // Do whatever you want here:
    
            for(Object key: props.keySet()) {
                logger.info(action + " Property received: {} {}",key,props.get(key));
            }
        }
    }
    

    应该给你这样的输出:

    2015-04-27 20:16:53,726 | INFO  | ime/karaf/deploy | PropsDeployer                     | 101 - com.example.scratch.deployer - 1.0.0.SNAPSHOT | Updating artifact: my.json
    2015-04-27 20:16:53,728 | INFO  | ime/karaf/deploy | PropsDeployer                     | 101 - com.example.scratch.deployer - 1.0.0.SNAPSHOT | Updating Property received: myprop myval
    2015-04-27 20:16:53,728 | INFO  | ime/karaf/deploy | PropsDeployer                     | 101 - com.example.scratch.deployer - 1.0.0.SNAPSHOT | Updating Property received: hello world
    

    您需要一个唯一的文件扩展名。 .cfg 将被您说不想使用的 ConfigurationAdmin 服务捕获。

    .props(如上)之类的东西可以解决问题。

    顺便说一句,您真的应该考虑使用ConfigurationAdmin。它非常强大。 karaf 内置了用于管理配置的命令,您所做的任何更改都将保留回.cfg 文件。

    【讨论】:

    • 它还没有工作。但我认为朝着正确的方向前进,我将在这方面努力。谢谢!一旦我让它工作,我就给你这个问题!
    • 我添加了一个清晰的示例,说明您如何实际访问该工件,希望对您有所帮助。
    • 我试过了,但我收到了这个错误信息:2015-04-28 09:37:41,105 | ERROR | ix.fileinstall]) | configadmin | 10 - org.apache.felix.configadmin - 1.6.0 | Cannot use configuration org.apache.felix.fileinstall.26c87fa4-697e-472d-9296-e8c4ab 8a9550 for [org.osgi.service.cm.ManagedServiceFactory, id=445, bundle=120/mvn:org.apache.felix/org.apache.felix.fileinstall/3.4.2]: No visibility to configuration bound to mvn:org.apache.felix/org.apache.felix.filein stall/3.2.8
    • 尝试改变 org.apache.felixorg.apache.felix.fileinstall3.4.2提供 到版本3.2.8。 > list:bundle -t 0 -s 的输出会有所帮助。和 shell:info 一样
    • 我能够按照您的建议进行操作,但它只调用 README 文件。不要将此捆绑包视为我的配置文件的侦听器,我如何能够将我的侦听器添加到正确的文件中?
    【解决方案2】:

    尤里卡!

    正如我在更新中提到的,第 1 步(使用 maven 构建配置文件)和第 2 步(部署 conf 文件 etc)正在工作,但捆绑包和配置文件未连接。显然原因是配置文件安装了另一个 PID 作为注册到它的服务。为了解决这个问题,我将ManageService 注册到部署的配置文件的PID。在我的情况下如下所示:

     Hashtable <String, Object> properties = new Hashtable<String, Object>();
     properties.put(Constants.SERVICE_PID, "MQTTBackboneProtocol");
     context.registerService (ManagedService.class.getName(),this , properties);
    

    其中this是实现ManageService的类,并且PID必须与etc中部署的配置相同,在这种情况下"MQTTBackboneProtocol"由于功能定义将配置文件指示为:

    <configfile finalname="/etc/MQTTBackboneProtocol.cfg">mvn:eu.linksmart.gc/network.backbone.protocol.mqtt.impl/${linksmart.gc.version}/cfg/configuration</configfile>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多