简体   繁体   中英

How to place bundle configuration/property file in /etc karaf folder

I want to deploy all the configuration files of the bundles deployed in karaf be placed in the karaf etc folder. I want that when the bundles conf files are change are notice by the karaf.

I have a distribution which consist of several features an example of a feature of the XML.I already tried several things eg I add the conf file into the feature as below, but this dose not work.

<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>

Some of the things I have tried:

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

I don't want to copy the file with a specific path as is shown here:

have anyone an idea how to do this?

UPDATE

To achieve that the configuration file get deployed in the etc folder so the bundle can be reconfigured externally, I have done it in 3 steps:

Building the configuration file: ( Works )

To make the config file addressable by Maven I added the following part in the bundle pom. In this way the config file is deploy on the repository:

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>

Deploy the file in the karaf etc ( Works )

To deploy the config file in the karaf etc folder I added the <configfile> in the feature file as following:

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>

Capture configuration change: ( not working )

To capture the change of a config file I add the code you suggested (@Donald_W). The problem is that I get just notifications of files are on the folder deploy but not in etc . I debug this code and I find out that for the files in etc are called specifically the "listeners" of those files. I don't know then how I can become a listener of a file deployed in the etc

You can use the Felix File Installer which is built into Karaf, which will give you callbacks when files change under etc .

Once you publish a service which implements ArtifactInstaller into the OSGi service registry it will be detected by the FileInstaller - ie the Whiteboard pattern .

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

Sample code (using iPojo but Blueprint / DS would work just as well) would be:

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));
        }
    }
}

Should give you output like this:

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

You'll need a unique file extension. .cfg will be captured by the ConfigurationAdmin service which you say you don't want to use.

Something like .props (as above) would do the trick.

As an aside, you really should look at using ConfigurationAdmin . It's incredibly powerful. There are commands built into karaf for managing the configuration, and any changes you make will persist back to the .cfg files.

Eureka!

As I mentioned in the UPDATE the step 1 (build configuration file with maven) and 2 (deploy the conf file etc ) was working but the bundle and the configuration file were not connected. Apparently the reason was that the configuration file was install with another PID as the service which was registering to it. To solve this I registered the ManageService to the PID of the configurated file deployed. In my case looks as following:

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

Where this is the class which implements the ManageService and the PID must be the same as is deployed configuration in the etc , in this case "MQTTBackboneProtocol" due to the feature definition indicate the configuration file as:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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