Java 如何将捆绑包配置/属性文件放置在/etc karaf文件夹中

Java 如何将捆绑包配置/属性文件放置在/etc karaf文件夹中,java,osgi,apache-karaf,karaf,Java,Osgi,Apache Karaf,Karaf,我想将部署在karaf中的捆绑包的所有配置文件都放在karafetc文件夹中。我希望当bundles conf文件被更改时,由karaf通知 我有一个由几个特性组成的发行版,一个XML特性的示例。我已经尝试了一些事情,例如,我将conf文件添加到特性中,如下所示,但这不起作用 <feature name="gc-backbone-mqtt" version="${linksmart.gc.version}"> <feature version="${linksmart.

我想将部署在karaf中的捆绑包的所有配置文件都放在karaf
etc
文件夹中。我希望当bundles conf文件被更改时,由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>
在karaf
etc
中部署文件(工作

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

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

gc骨干路由器
mvn:org.eclipse.paho/org.eclipse.paho.client.mqttv3/1.0.0
mvn:org.apache.felix/org.apache.felix.fileinstall/3.2.8
mvn:eu.linksmart.gc/network.backbone.protocol.mqtt.impl/${linksmart.gc.version}/cfg/configuration
gc类型隧道mvn:eu.linksmart.gc/network.backbone.protocol.mqtt.impl/${linksmart.gc.version}
捕获配置更改:(不工作


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

中的文件的侦听器。您可以使用内置在Karaf中的Felix文件安装程序,当文件在
etc
下更改时,它会给您回叫

一旦将实现了
ArtifactInstaller
的服务发布到OSGi服务注册表中,
FileInstaller
将检测到该服务,即


org.apache.felix
org.apache.felix.fileinstall
3.4.2
假如
示例代码(使用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:53726 | INFO | ime/karaf/deploy | PropsDeployer | 101-com.example.scratch.deployer-1.0.0.SNAPSHOT |更新工件:my.json
2015-04-27 20:16:53728 | INFO | ime/karaf/deploy | props部署程序| 101-com.example.scratch.deployer-1.0.0.SNAPSHOT |收到的更新属性:myprop myval
2015-04-27 20:16:53728 | INFO | ime/karaf/deploy | PropsDeployer | 101-com.example.scratch.deployer-1.0.0.SNAPSHOT |收到更新属性:hello world
您需要一个唯一的文件扩展名。cfg将被您说不想使用的ConfigurationAdmin服务捕获

类似于
.props
(如上所述)的东西可以起到作用

另一方面,您确实应该考虑使用
ConfigurationAdmin
。它非常强大。karaf中内置了用于管理配置的命令,您所做的任何更改都将保留回
.cfg
文件。

Eureka

正如我在更新中提到的,第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);

它还没起作用。但我认为我会朝着正确的方向努力。非常感谢。一旦我成功了,我就给你一个问题!我已经添加了一个清晰的示例,说明如何实际访问工件,我试过了,但收到了以下错误消息:2015-04-28 09:37:41105 |
error | ix.fileinstall])| configadmin | 10-org.apache.felix.configadmin-1.6.0 |无法使用configuration org.apache.felix.fileinstall.26c87fa4-697e-472d-9296-e8c4ab 8a9550[org.osgi.service.cm.ManagedServiceFactory,id=445,bundle=120/mvn:org.apache.felix/org.apache.felix.fileinstall/3.4.2]:无法查看绑定到mvn的配置:org.apache.felix/org.apache.felix.filein stall/3.2.8
尝试更改提供给3.2.8版的org.apache.felix.fileinstall 3.4.2。您从>list:bundle-t0-s的输出将很有帮助。shell:infoI也可以按照您的建议进行操作,但仅限于its调用不要把这个包看作是我的配置文件的侦听器,我如何将我的侦听器添加到正确的文件中?
<configfile finalname="/etc/MQTTBackboneProtocol.cfg">mvn:eu.linksmart.gc/network.backbone.protocol.mqtt.impl/${linksmart.gc.version}/cfg/configuration</configfile>