You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2017/09/19 20:00:23 UTC

[1/2] incubator-tamaya-sandbox git commit: TAMAYA-297: Added OSGI Config trigger for Tamaya changes.

Repository: incubator-tamaya-sandbox
Updated Branches:
  refs/heads/java8 54ff0e6f0 -> 99ce49ed3


TAMAYA-297: Added OSGI Config trigger for Tamaya changes.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/78554829
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/78554829
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/78554829

Branch: refs/heads/java8
Commit: 7855482984c81a11ecf40f2ee63a7c82c603e0c0
Parents: 54ff0e6
Author: anatole <an...@apache.org>
Authored: Tue Sep 19 21:00:32 2017 +0200
Committer: anatole <an...@apache.org>
Committed: Tue Sep 19 21:00:32 2017 +0200

----------------------------------------------------------------------
 osgi/common/bnd.bnd                             |   2 +-
 .../org/apache/tamaya/osgi/ConfigChanger.java   |  20 ++-
 .../org/apache/tamaya/osgi/ConfigHistory.java   |  39 ++++-
 .../org/apache/tamaya/osgi/InitialState.java    |  89 ++++++++++++
 .../apache/tamaya/osgi/TamayaConfigPlugin.java  |  29 +++-
 osgi/updater/bnd.bnd                            |  34 +++++
 osgi/updater/pom.xml                            | 145 +++++++++++++++++++
 .../apache/tamaya/osgi/updater/Activator.java   |  59 ++++++++
 .../tamaya/osgi/updater/EventListener.java      |  79 ++++++++++
 9 files changed, 481 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/78554829/osgi/common/bnd.bnd
----------------------------------------------------------------------
diff --git a/osgi/common/bnd.bnd b/osgi/common/bnd.bnd
index 22c802c..51175cb 100644
--- a/osgi/common/bnd.bnd
+++ b/osgi/common/bnd.bnd
@@ -19,7 +19,7 @@ Bundle-License: Apache Licence version 2
 Bundle-Vendor: Apache Software Foundation
 Bundle-ContactAddress: dev-tamaya@incubator.apache.org
 Bundle-DocURL: http://tamaya.apache.org
-Bundle-Activator: org.apache.tamaya.osgi.Activator
+Bundle-Activator: org.apache.tamaya.osgi.updater.Activator
 Export-Package: \
 	org.apache.tamaya.osgi
 Import-Package: \

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/78554829/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigChanger.java
----------------------------------------------------------------------
diff --git a/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigChanger.java b/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigChanger.java
index 29c4720..1d48fad 100644
--- a/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigChanger.java
+++ b/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigChanger.java
@@ -55,12 +55,18 @@ final class ConfigChanger {
 
     public void configure(String pid, Bundle bundle, OperationMode defaultOpMode) {
         OperationMode opMode = Objects.requireNonNull(defaultOpMode);
-        String opVal = bundle.getHeaders().get("Tamaya-OperationMode");
-        if(opVal!=null){
-            opMode = OperationMode.valueOf(opVal.toUpperCase());
+        if(bundle!=null) {
+            String opVal = bundle.getHeaders().get("Tamaya-OperationMode");
+            if (opVal != null) {
+                opMode = OperationMode.valueOf(opVal.toUpperCase());
+            }
         }
         LOG.finest("Evaluating Tamaya Config for PID: " + pid);
-        ConfigHistory.configuring(pid, "operationMode="+opMode);
+        if(bundle!=null) {
+            ConfigHistory.configuring(pid, "bundle=" + bundle.getSymbolicName() + ", bundle-id=" + bundle.getBundleId() + ", operationMode=" + opMode);
+        }else{
+            ConfigHistory.configuring(pid, "trigger=Tamaya, operationMode=" + opMode);
+        }
         org.apache.tamaya.Configuration tamayaConfig = configMapper().getConfiguration(pid);
         if (tamayaConfig == null) {
             LOG.finest("No Tamaya configuration for PID: " + pid);
@@ -68,11 +74,15 @@ final class ConfigChanger {
         }
         try {
             // TODO Check for Bundle.getLocation() usage here...
-            Configuration osgiConfig = cm.getConfiguration(pid, bundle.getLocation());
+            Configuration osgiConfig = cm.getConfiguration(pid, bundle!=null?bundle.getLocation():null);
             if(osgiConfig!=null){
                 Dictionary<String, Object> dictionary = osgiConfig.getProperties();
                 if(dictionary==null){
                     dictionary = new Hashtable<>();
+                }else{
+                    if(!InitialState.contains(pid)){
+                        InitialState.set(pid, dictionary);
+                    }
                 }
                 modifyConfiguration(pid, tamayaConfig, dictionary, opMode);
                 if(!dictionary.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/78554829/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
----------------------------------------------------------------------
diff --git a/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java b/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
index 8fdd70a..42ecca6 100644
--- a/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
+++ b/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
@@ -18,10 +18,12 @@
  */
 package org.apache.tamaya.osgi;
 
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
+import java.beans.XMLDecoder;
+import java.beans.XMLEncoder;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.*;
 
 /**
  * Class storing the history of changers done to the OSGI configuration by Tamaya.
@@ -88,6 +90,14 @@ public final class ConfigHistory {
         return h;
     }
 
+    public static void setMaxHistory(int maxHistory){
+        ConfigHistory.maxHistory = maxHistory;
+    }
+
+    public static int getMaxHistory(){
+        return maxHistory;
+    }
+
     public static List<ConfigHistory> history(){
         return history(null);
     }
@@ -156,6 +166,27 @@ public final class ConfigHistory {
         return this;
     }
 
+    public static void save(TamayaConfigPlugin plugin){
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        XMLEncoder encoder = new XMLEncoder(bos, "UTF-8", false, 4);
+        encoder.writeObject(history);
+        try {
+            bos.flush();
+            plugin.setConfigValue("history", new String(bos.toByteArray()));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void restore(TamayaConfigPlugin plugin){
+        String serialized = (String)plugin.getConfigValue("history");
+        if(serialized!=null) {
+            ByteArrayInputStream bis = new ByteArrayInputStream(serialized.getBytes());
+            XMLDecoder encoder = new XMLDecoder(bis);
+            ConfigHistory.history = (List<ConfigHistory>) encoder.readObject();
+        }
+    }
+
     @Override
     public String toString() {
         return "ConfigHistory{" +

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/78554829/osgi/common/src/main/java/org/apache/tamaya/osgi/InitialState.java
----------------------------------------------------------------------
diff --git a/osgi/common/src/main/java/org/apache/tamaya/osgi/InitialState.java b/osgi/common/src/main/java/org/apache/tamaya/osgi/InitialState.java
new file mode 100644
index 0000000..faf50e5
--- /dev/null
+++ b/osgi/common/src/main/java/org/apache/tamaya/osgi/InitialState.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.osgi;
+
+import java.beans.XMLDecoder;
+import java.beans.XMLEncoder;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by atsticks on 19.09.17.
+ */
+public final class InitialState {
+
+    private static Map<String, Dictionary<String,?>> initialConfigState = new ConcurrentHashMap<>();
+
+    private InitialState(){}
+
+    public static void set(String pid, Dictionary<String,?> config){
+        initialConfigState.put(pid, config);
+    }
+
+    public static Dictionary<String,?> remove(String pid){
+        return initialConfigState.remove(pid);
+    }
+
+    public static void removeAll(){
+        initialConfigState.clear();
+    }
+
+    public static Dictionary<String,?> get(String pid){
+        return initialConfigState.get(pid);
+    }
+
+    public static Map<String,Dictionary<String,?>> get(){
+        return new HashMap<>(initialConfigState);
+    }
+
+    public static Set<String> getPids(){
+        return initialConfigState.keySet();
+    }
+
+    public static boolean contains(String pid){
+        return initialConfigState.containsKey(pid);
+    }
+
+    public static void save(TamayaConfigPlugin plugin){
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        XMLEncoder encoder = new XMLEncoder(bos, "UTF-8", false, 4);
+        encoder.writeObject(initialConfigState);
+        try {
+            bos.flush();
+            plugin.setConfigValue("backup", new String(bos.toByteArray()));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void restore(TamayaConfigPlugin plugin){
+        String serialized = (String)plugin.getConfigValue("history");
+        if(serialized!=null) {
+            ByteArrayInputStream bis = new ByteArrayInputStream(serialized.getBytes());
+            XMLDecoder encoder = new XMLDecoder(bis);
+            InitialState.initialConfigState = (Map<String, Dictionary<String,?>>) encoder.readObject();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/78554829/osgi/common/src/main/java/org/apache/tamaya/osgi/TamayaConfigPlugin.java
----------------------------------------------------------------------
diff --git a/osgi/common/src/main/java/org/apache/tamaya/osgi/TamayaConfigPlugin.java b/osgi/common/src/main/java/org/apache/tamaya/osgi/TamayaConfigPlugin.java
index 1b844f0..ad964b1 100644
--- a/osgi/common/src/main/java/org/apache/tamaya/osgi/TamayaConfigPlugin.java
+++ b/osgi/common/src/main/java/org/apache/tamaya/osgi/TamayaConfigPlugin.java
@@ -23,7 +23,9 @@ import org.osgi.service.cm.Configuration;
 import org.osgi.service.cm.ConfigurationAdmin;
 
 import java.io.IOException;
-import java.util.*;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Objects;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -36,6 +38,9 @@ public class TamayaConfigPlugin implements BundleListener, ServiceListener{
     /** the logger. */
     private static final Logger LOG = Logger.getLogger(TamayaConfigPlugin.class.getName());
     private static final String TAMAYA_DISABLED = "tamaya.disabled";
+    public static final String TAMAYA_DISABLED_KEY = "Tamaya-Disabled";
+    public static final String TAMAYA_ENABLED_KEY = "Tamaya-Enabled";
+    public static final String TAMAYA_PID_KEY = "Tamaya-PID";
     private boolean disabled = false;
     private OperationMode defaultOpMode = OperationMode.OVERRIDE;
 
@@ -61,6 +66,8 @@ public class TamayaConfigPlugin implements BundleListener, ServiceListener{
      */
     TamayaConfigPlugin(BundleContext context) {
         configChanger = new ConfigChanger(context);
+        InitialState.restore(this);
+        ConfigHistory.restore(this);
         initDefaultEnabled();
         initDefaultOpMode();
         initConfigs();
@@ -113,19 +120,28 @@ public class TamayaConfigPlugin implements BundleListener, ServiceListener{
         if(!isBundleEnabled(bundle)){
             return;
         }
-        String pid = (String)event.getServiceReference().getProperty("service.pid");
+        String pid = (String)event.getServiceReference().getProperty(Constants.SERVICE_PID);
         if(pid==null){
             LOG.finest("No service pid for: " + event.getServiceReference());
             return;
         }
         configChanger.configure(pid, event.getServiceReference().getBundle(), defaultOpMode);
+        InitialState.save(this);
+        ConfigHistory.save(this);
+    }
+
+    public void updateConfig(String pid) {
+        LOG.fine("Updating config for pid...: " + pid);
+        configChanger.configure(pid, null, defaultOpMode);
+        InitialState.save(this);
+        ConfigHistory.save(this);
     }
 
     private void configureBundle(Bundle bundle) {
         if(!isBundleEnabled(bundle)){
             return;
         }
-        String tamayaPid = bundle.getHeaders().get("Tamaya-PID");
+        String tamayaPid = bundle.getHeaders().get(TAMAYA_PID_KEY);
         String pid = tamayaPid!=null?tamayaPid:bundle.getSymbolicName();
         if(pid==null){
             pid = bundle.getLocation();
@@ -135,13 +151,15 @@ public class TamayaConfigPlugin implements BundleListener, ServiceListener{
             return;
         }
         configChanger.configure(pid, bundle, defaultOpMode);
+        InitialState.save(this);
+        ConfigHistory.save(this);
     }
 
 
     public boolean isBundleEnabled(Bundle bundle){
         // Optional MANIFEST entries
-        String enabledTamaya = bundle.getHeaders().get("Tamaya-Enabled");
-        String disabledTamaya = bundle.getHeaders().get("Tamaya-Disabled");
+        String enabledTamaya = bundle.getHeaders().get(TAMAYA_ENABLED_KEY);
+        String disabledTamaya = bundle.getHeaders().get(TAMAYA_DISABLED_KEY);
 
         if(Boolean.parseBoolean(disabledTamaya)){
             LOG.finest("Bundle is disabled for Tamaya: " + bundle.getSymbolicName());
@@ -226,4 +244,5 @@ public class TamayaConfigPlugin implements BundleListener, ServiceListener{
         return null;
     }
 
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/78554829/osgi/updater/bnd.bnd
----------------------------------------------------------------------
diff --git a/osgi/updater/bnd.bnd b/osgi/updater/bnd.bnd
new file mode 100644
index 0000000..ef7d52d
--- /dev/null
+++ b/osgi/updater/bnd.bnd
@@ -0,0 +1,34 @@
+-buildpath: \
+	osgi.annotation; version=6.0.0,\
+	osgi.core; version=6.0,\
+	osgi.cmpn; version=6.0
+
+-testpath: \
+	${junit}
+
+javac.source: 1.8
+javac.target: 1.8
+
+Bundle-Version: ${version}.${tstamp}
+Bundle-Name: Apache Tamaya - OSGI Updater
+Bundle-SymbolicName: org.apache.tamaya.osgi.updater
+Bundle-Description: Apacha Tamaya Configuration - OSGI Updater
+Bundle-Category: Implementation
+Bundle-Copyright: (C) Apache Foundation
+Bundle-License: Apache Licence version 2
+Bundle-Vendor: Apache Software Foundation
+Bundle-ContactAddress: dev-tamaya@incubator.apache.org
+Bundle-DocURL: http://tamaya.apache.org
+Bundle-Activator: org.apache.tamaya.osgi.updater.Activator
+Export-Package: \
+	org.apache.tamaya.osgi.updater
+Import-Package: \
+    org.apache.tamaya.osgi,\
+    org.osgi.service.cm,\
+    org.osgi.framework,\
+    org.apache.tamaya,\
+    org.apache.tamaya.spi,\
+    org.apache.tamaya.functions,\
+    org.apache.tamaya.spisupport,\
+    org.apache.tamaya.events
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/78554829/osgi/updater/pom.xml
----------------------------------------------------------------------
diff --git a/osgi/updater/pom.xml b/osgi/updater/pom.xml
new file mode 100644
index 0000000..a1df83b
--- /dev/null
+++ b/osgi/updater/pom.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        Licensed to the Apache Software Foundation (ASF) under one or more
+        contributor license agreements.  See the NOTICE file distributed with
+        this work for additional information regarding copyright ownership.
+        The ASF licenses this file to You under the Apache License, Version 2.0
+        (the "License"); you may not use this file except in compliance with
+        the License.  You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+        Unless required by applicable law or agreed to in writing, software
+        distributed under the License is distributed on an "AS IS" BASIS,
+        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        See the License for the specific language governing permissions and
+        limitations under the License.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.tamaya.ext</groupId>
+        <artifactId>tamaya-osgi-all</artifactId>
+        <version>0.4-incubating-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>tamaya-osgi-updater_alpha</artifactId>
+    <packaging>jar</packaging>
+    <name>Apache Tamaya :: OSGi :: Updater</name>
+    <description>Tamaya Based OSGI Updater to propagate Tamaya changes to OSGI.</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <!--<dependency>-->
+            <!--<groupId>org.osgi</groupId>-->
+            <!--<artifactId>org.osgi.util.tracker</artifactId>-->
+            <!--<scope>provided</scope>-->
+        <!--</dependency>-->
+
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-atinject_1.0_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-core</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-functions</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-spisupport</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-events</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-osgi_alpha</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
+        <!-- Testing -->
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+
+        <!-- OSGI Testbed -->
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-container-forked</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit4</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-link-mvn</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-aether</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.framework</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit4</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-wrap</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-reference</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/78554829/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java
----------------------------------------------------------------------
diff --git a/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java b/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java
new file mode 100644
index 0000000..55bbd6d
--- /dev/null
+++ b/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.osgi.updater;
+
+import org.apache.tamaya.events.ConfigEventManager;
+import org.apache.tamaya.events.ConfigurationChange;
+import org.osgi.framework.*;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import java.util.logging.Logger;
+
+/**
+ * Activator that registers the Tamaya based Service Class for {@link ConfigurationAdmin},
+ * using a default service priority of {@code 0}. This behaviour is configurable based on OSGI properties:
+ * <ul>
+ *     <li><p><b>org.tamaya.integration.osgi.cm.ranking, type: int</b> allows to configure the OSGI service ranking for
+ *     Tamaya based ConfigurationAdmin instance. The default ranking used is 10.</p></li>
+ *     <li><p><b>org.tamaya.integration.osgi.cm.override, type: boolean</b> allows to configure if Tamaya should
+ *     register its ConfigAdmin service. Default is true.</p></li>
+ * </ul>
+ */
+public class Activator implements BundleActivator {
+
+    private static final Logger LOG = Logger.getLogger(Activator.class.getName());
+
+    private EventListener listener;
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        listener = new EventListener(context);
+        ConfigEventManager.addListener(listener, ConfigurationChange.class);
+        LOG.info("Registered Tamaya config trigger for OSGI.");
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        if (listener != null) {
+            ConfigEventManager.removeListener(this.listener, ConfigurationChange.class);
+            LOG.info("Unregistered Tamaya config trigger for OSGI.");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/78554829/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/EventListener.java
----------------------------------------------------------------------
diff --git a/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/EventListener.java b/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/EventListener.java
new file mode 100644
index 0000000..f2e0e95
--- /dev/null
+++ b/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/EventListener.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.osgi.updater;
+
+import org.apache.tamaya.events.ConfigEvent;
+import org.apache.tamaya.events.ConfigEventListener;
+import org.apache.tamaya.events.ConfigurationChange;
+import org.apache.tamaya.osgi.OperationMode;
+import org.apache.tamaya.osgi.TamayaConfigPlugin;
+import org.osgi.framework.*;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import java.beans.PropertyChangeEvent;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * Tamaya plugin that updates/extends the component configurations managed
+ * by {@link ConfigurationAdmin}, based on the configured {@link OperationMode}.
+ */
+final class EventListener implements ConfigEventListener{
+    private static final Logger LOG = Logger.getLogger(EventListener.class.getName());
+    private BundleContext context;
+
+    public EventListener(BundleContext context){
+        this.context = context;
+    }
+
+
+    @Override
+    public void onConfigEvent(ConfigEvent<?> event) {
+        LOG.finest("Tamya Config change triggered: " + event);
+        Set<String> changedPids = new HashSet<>();
+        ConfigurationChange cc = (ConfigurationChange)event;
+        for(PropertyChangeEvent evt: cc.getChanges()){
+            String key = evt.getPropertyName();
+            String pid = getPid(key);
+            if(pid!=null){
+                changedPids.add(pid);
+            }
+        }
+        if(changedPids.isEmpty()){
+            LOG.finest("Tamya Config change not targeting OSGI.");
+            return;
+        }
+        LOG.finest("Tamya Config change for pids: " + changedPids);
+        // Reload the given pids
+        ServiceReference<TamayaConfigPlugin> pluginRef = context.getServiceReference(TamayaConfigPlugin.class);
+        TamayaConfigPlugin tamayaPlugin = context.getService(pluginRef);
+        for(String pid:changedPids) {
+            tamayaPlugin.updateConfig(pid);
+        }
+    }
+
+    private String getPid(String key) {
+        int index0 = key.indexOf("[");
+        int index1 = key.indexOf("]");
+        if(index0 >=0 && (index1 - index0) > 0){
+            return key.substring(index0+1,index1);
+        }
+        return null;
+    }
+}


[2/2] incubator-tamaya-sandbox git commit: TAMAYA-297: Added OSGI Config trigger for Tamaya changes.

Posted by an...@apache.org.
TAMAYA-297: Added OSGI Config trigger for Tamaya changes.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/99ce49ed
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/99ce49ed
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/99ce49ed

Branch: refs/heads/java8
Commit: 99ce49ed39e938e0d2fb019ef2f5a3270c2c7789
Parents: 7855482
Author: anatole <an...@apache.org>
Authored: Tue Sep 19 22:00:11 2017 +0200
Committer: anatole <an...@apache.org>
Committed: Tue Sep 19 22:00:11 2017 +0200

----------------------------------------------------------------------
 osgi/common/bnd.bnd                             |  2 +-
 .../org/apache/tamaya/osgi/ConfigHistory.java   | 62 +++++++++--------
 .../org/apache/tamaya/osgi/InitialState.java    | 65 ++++++++++++------
 .../tamaya/karaf/shell/BackupCreateCommand.java | 68 ++++++++++++++++++
 .../tamaya/karaf/shell/BackupDeleteCommand.java | 49 +++++++++++++
 .../tamaya/karaf/shell/BackupListCommand.java   | 72 ++++++++++++++++++++
 .../karaf/shell/HistorySizeGetCommand.java      | 47 +++++++++++++
 .../karaf/shell/HistorySizeSetCommand.java      | 56 +++++++++++++++
 .../org/apache/tamaya/karaf/shell/commands      |  5 ++
 osgi/pom.xml                                    |  1 +
 .../apache/tamaya/osgi/updater/Activator.java   |  2 +
 11 files changed, 379 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/common/bnd.bnd
----------------------------------------------------------------------
diff --git a/osgi/common/bnd.bnd b/osgi/common/bnd.bnd
index 51175cb..22c802c 100644
--- a/osgi/common/bnd.bnd
+++ b/osgi/common/bnd.bnd
@@ -19,7 +19,7 @@ Bundle-License: Apache Licence version 2
 Bundle-Vendor: Apache Software Foundation
 Bundle-ContactAddress: dev-tamaya@incubator.apache.org
 Bundle-DocURL: http://tamaya.apache.org
-Bundle-Activator: org.apache.tamaya.osgi.updater.Activator
+Bundle-Activator: org.apache.tamaya.osgi.Activator
 Export-Package: \
 	org.apache.tamaya.osgi
 Import-Package: \

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
----------------------------------------------------------------------
diff --git a/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java b/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
index 42ecca6..9a2e5a9 100644
--- a/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
+++ b/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
@@ -20,16 +20,19 @@ package org.apache.tamaya.osgi;
 
 import java.beans.XMLDecoder;
 import java.beans.XMLEncoder;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
+import java.io.*;
 import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * Class storing the history of changers done to the OSGI configuration by Tamaya.
  * This class can be used in the future to restore the previous state, if needed.
  */
-public final class ConfigHistory {
+public final class ConfigHistory implements Serializable{
+
+    private static final long serialVersionUID = 1L;
+    private static final Logger LOG = Logger.getLogger(ConfigHistory.class.getName());
 
     public enum TaskType{
         PROPERTY,
@@ -38,17 +41,7 @@ public final class ConfigHistory {
     }
 
     private static int maxHistory = 10000;
-    private static List<ConfigHistory> history = new LinkedList<ConfigHistory>(){
-
-        @Override
-        public boolean add(ConfigHistory o) {
-            boolean val = super.add(o);
-            if(val && size() > maxHistory){
-                remove();
-            }
-            return val;
-        }
-    };
+    private static List<ConfigHistory> history = new LinkedList<ConfigHistory>();
 
     private long timestamp = System.currentTimeMillis();
 
@@ -68,6 +61,7 @@ public final class ConfigHistory {
                 .setValue(info);
         synchronized (history){
             history.add(h);
+            checkHistorySize();
         }
         return h;
     }
@@ -76,6 +70,7 @@ public final class ConfigHistory {
                 .setValue(info);
         synchronized (history){
             history.add(h);
+            checkHistorySize();
         }
         return h;
     }
@@ -86,6 +81,7 @@ public final class ConfigHistory {
                 .setValue(value);
         synchronized (history){
             history.add(h);
+            checkHistorySize();
         }
         return h;
     }
@@ -167,23 +163,29 @@ public final class ConfigHistory {
     }
 
     public static void save(TamayaConfigPlugin plugin){
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        XMLEncoder encoder = new XMLEncoder(bos, "UTF-8", false, 4);
-        encoder.writeObject(history);
         try {
-            bos.flush();
-            plugin.setConfigValue("history", new String(bos.toByteArray()));
-        } catch (IOException e) {
-            e.printStackTrace();
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(history);
+            oos.flush();
+            Base64.getEncoder().encode(bos.toByteArray());
+            plugin.setConfigValue("history", Base64.getEncoder().encode(bos.toByteArray()));
+        } catch (Exception e) {
+            LOG.log(Level.WARNING, "Failed to store config change history.", e);
         }
     }
 
     public static void restore(TamayaConfigPlugin plugin){
-        String serialized = (String)plugin.getConfigValue("history");
-        if(serialized!=null) {
-            ByteArrayInputStream bis = new ByteArrayInputStream(serialized.getBytes());
-            XMLDecoder encoder = new XMLDecoder(bis);
-            ConfigHistory.history = (List<ConfigHistory>) encoder.readObject();
+        try{
+            String serialized = (String)plugin.getConfigValue("history");
+            if(serialized!=null) {
+                ByteArrayInputStream bis = new ByteArrayInputStream(Base64.getDecoder().decode(serialized));
+                ObjectInputStream ois = new ObjectInputStream(bis);
+                ConfigHistory.history = (List<ConfigHistory>) ois.readObject();
+                ois.close();
+            }
+        } catch (Exception e) {
+            LOG.log(Level.WARNING, "Failed to store config change history.", e);
         }
     }
 
@@ -196,4 +198,10 @@ public final class ConfigHistory {
                 ", key='" + key + '\'' +
                 '}';
     }
+
+    private static void checkHistorySize(){
+        while(history.size() > maxHistory){
+            history.remove(0);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/common/src/main/java/org/apache/tamaya/osgi/InitialState.java
----------------------------------------------------------------------
diff --git a/osgi/common/src/main/java/org/apache/tamaya/osgi/InitialState.java b/osgi/common/src/main/java/org/apache/tamaya/osgi/InitialState.java
index faf50e5..0a0de21 100644
--- a/osgi/common/src/main/java/org/apache/tamaya/osgi/InitialState.java
+++ b/osgi/common/src/main/java/org/apache/tamaya/osgi/InitialState.java
@@ -18,28 +18,43 @@
  */
 package org.apache.tamaya.osgi;
 
-import java.beans.XMLDecoder;
-import java.beans.XMLEncoder;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * Created by atsticks on 19.09.17.
  */
 public final class InitialState {
 
-    private static Map<String, Dictionary<String,?>> initialConfigState = new ConcurrentHashMap<>();
+    private static final Logger LOG = Logger.getLogger(InitialState.class.getName());
+    private static Map<String, Hashtable<String,?>> initialConfigState = new ConcurrentHashMap<>();
 
     private InitialState(){}
 
     public static void set(String pid, Dictionary<String,?> config){
-        initialConfigState.put(pid, config);
+        initialConfigState.put(pid, toHashtable(config));
+    }
+
+    private static Hashtable<String, ?> toHashtable(Dictionary<String, ?> dictionary) {
+        if (dictionary == null) {
+            return null;
+        }
+        if(dictionary instanceof Hashtable){
+            return (Hashtable) dictionary;
+        }
+        Hashtable<String, Object> map = new Hashtable<>(dictionary.size());
+        Enumeration<String> keys = dictionary.keys();
+        while (keys.hasMoreElements()) {
+            String key = keys.nextElement();
+            map.put(key, dictionary.get(key));
+        }
+        return map;
     }
 
     public static Dictionary<String,?> remove(String pid){
@@ -67,23 +82,29 @@ public final class InitialState {
     }
 
     public static void save(TamayaConfigPlugin plugin){
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        XMLEncoder encoder = new XMLEncoder(bos, "UTF-8", false, 4);
-        encoder.writeObject(initialConfigState);
-        try {
-            bos.flush();
-            plugin.setConfigValue("backup", new String(bos.toByteArray()));
-        } catch (IOException e) {
-            e.printStackTrace();
+        try{
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(initialConfigState);
+            oos.flush();
+            Base64.getEncoder().encode(bos.toByteArray());
+            plugin.setConfigValue("backup", Base64.getEncoder().encode(bos.toByteArray()));
+        }catch(Exception e){
+            LOG.log(Level.SEVERE, "Failed to restore OSGI Backups.", e);
         }
     }
 
     public static void restore(TamayaConfigPlugin plugin){
-        String serialized = (String)plugin.getConfigValue("history");
-        if(serialized!=null) {
-            ByteArrayInputStream bis = new ByteArrayInputStream(serialized.getBytes());
-            XMLDecoder encoder = new XMLDecoder(bis);
-            InitialState.initialConfigState = (Map<String, Dictionary<String,?>>) encoder.readObject();
+        try{
+            String serialized = (String)plugin.getConfigValue("backup");
+            if(serialized!=null) {
+                ByteArrayInputStream bis = new ByteArrayInputStream(Base64.getDecoder().decode(serialized));
+                ObjectInputStream ois = new ObjectInputStream(bis);
+                initialConfigState = (Map<String, Hashtable<String,?>>) ois.readObject();
+                ois.close();
+            }
+        } catch (Exception e) {
+            LOG.log(Level.WARNING, "Failed to store config change history.", e);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupCreateCommand.java
----------------------------------------------------------------------
diff --git a/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupCreateCommand.java b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupCreateCommand.java
new file mode 100644
index 0000000..3346e80
--- /dev/null
+++ b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupCreateCommand.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.karaf.shell;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.tamaya.osgi.InitialState;
+import org.apache.tamaya.osgi.TamayaConfigPlugin;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.annotations.Reference;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+@Command(scope = "tamaya", name = "backup-create", description="Creates a backup of a current OSGI configuration.")
+@Service
+public class BackupCreateCommand implements Action{
+
+    @Argument(index = 0, name = "pid", description = "The target pid to backup.",
+            required = true, multiValued = false)
+    String pid;
+
+    @Option(name = "--force", aliases = "-f", description = "Forces to (over)write a backup, even if one already exists.",
+            required = false, multiValued = false)
+    boolean replace;
+
+    @org.apache.karaf.shell.api.action.lifecycle.Reference
+    ConfigurationAdmin cm;
+
+    @Override
+    public Object execute() throws IOException {
+        Configuration cfg = cm.getConfiguration(pid);
+        if(cfg!=null){
+            Dictionary<String,?> props = cfg.getProperties();
+            if(props!=null){
+                if(replace || !InitialState.contains(pid)){
+                    InitialState.set(pid, props);
+                    System.out.println("Backup created, PID = " + pid);
+                    BackupListCommand.printProps(props);
+                    return null;
+                }
+            }
+        }
+        System.out.println("No Config found, PID = " + pid);
+        return null;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupDeleteCommand.java
----------------------------------------------------------------------
diff --git a/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupDeleteCommand.java b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupDeleteCommand.java
new file mode 100644
index 0000000..2c3f4be
--- /dev/null
+++ b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupDeleteCommand.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.karaf.shell;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.tamaya.osgi.InitialState;
+
+import java.io.IOException;
+
+@Command(scope = "tamaya", name = "backup-delete", description="Deletes the OSGI configuration backup  of Tamya.")
+@Service
+public class BackupDeleteCommand implements Action{
+
+    @Argument(index = 0, name = "pid", description = "Allows to filter on the given PID. '*' removes all backups.",
+            required = true, multiValued = false)
+    String pid;
+
+    @Override
+    public Object execute() throws IOException {
+        if("*".equals(pid)){
+            InitialState.removeAll();
+            System.out.println("All Backups deleted.");
+        }else {
+            InitialState.remove(pid);
+            System.out.println("Backup deleted: " + pid);
+        }
+        return null;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupListCommand.java
----------------------------------------------------------------------
diff --git a/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupListCommand.java b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupListCommand.java
new file mode 100644
index 0000000..d252586
--- /dev/null
+++ b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/BackupListCommand.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.karaf.shell;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.tamaya.osgi.InitialState;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Map;
+
+@Command(scope = "tamaya", name = "backup-list", description="Gets the OSGI configuration before Tamya applied changes.")
+@Service
+public class BackupListCommand implements Action{
+
+    @Argument(index = 0, name = "pid", description = "Allows to filter on the given PID.",
+            required = false, multiValued = false)
+    String pid;
+
+    @Override
+    public Object execute() throws IOException {
+        if(pid!=null){
+            Dictionary<String, ?> props = InitialState.get(pid);
+            if(props==null){
+                System.out.println("No backup found: " + pid);
+            }else{
+                System.out.println("PID: " + pid);
+                printProps(props);
+            }
+        }else {
+            for(Map.Entry<String, Dictionary<String,?>> en: InitialState.get().entrySet()){
+                System.out.println("PID: " + en.getKey());
+                printProps(en.getValue());
+            }
+        }
+        return null;
+    }
+
+    public static void printProps(Dictionary<String, ?> props) {
+        System.out.print(StringUtil.format("  Key", 50));
+        System.out.println(StringUtil.format("  Value", 50));
+        System.out.println("  " + StringUtil.printRepeat("-", 100));
+        Enumeration<String> keys = props.keys();
+        while(keys.hasMoreElements()){
+            String key = keys.nextElement();
+            System.out.print("  " + StringUtil.format(key, 50));
+            System.out.println("  " + StringUtil.format(String.valueOf(props.get(key)), 50));
+        }
+        System.out.println();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/HistorySizeGetCommand.java
----------------------------------------------------------------------
diff --git a/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/HistorySizeGetCommand.java b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/HistorySizeGetCommand.java
new file mode 100644
index 0000000..3658191
--- /dev/null
+++ b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/HistorySizeGetCommand.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.karaf.shell;
+
+import org.apache.karaf.shell.api.action.*;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.apache.tamaya.osgi.ConfigHistory;
+import org.apache.tamaya.osgi.TamayaConfigPlugin;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Command(scope = "tamaya", name = "history-size-get", description="Gets the maximal size of stored history entries.")
+@Service
+public class HistorySizeGetCommand implements Action{
+
+    @Override
+    public Object execute() throws IOException {
+        System.out.println(ConfigHistory.getMaxHistory());
+        return null;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/HistorySizeSetCommand.java
----------------------------------------------------------------------
diff --git a/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/HistorySizeSetCommand.java b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/HistorySizeSetCommand.java
new file mode 100644
index 0000000..ed6ff5a
--- /dev/null
+++ b/osgi/karaf-shell/src/main/java/org/apache/tamaya/karaf/shell/HistorySizeSetCommand.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.karaf.shell;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.apache.tamaya.osgi.ConfigHistory;
+import org.apache.tamaya.osgi.OperationMode;
+import org.apache.tamaya.osgi.TamayaConfigPlugin;
+
+import java.io.IOException;
+import java.util.List;
+
+@Command(scope = "tamaya", name = "history-size-set", description="Sets the maximal size of Tamaya history entries.")
+@Service
+public class HistorySizeSetCommand implements Action{
+
+    @Reference
+    private TamayaConfigPlugin configPlugin;
+
+    @Argument(index = 0, name = "size", description = "The maximum number of entries in the history.",
+            required = true, multiValued = false)
+    int maxSize;
+
+    @Override
+    public Object execute() throws IOException {
+        ConfigHistory.setMaxHistory(maxSize);
+        System.out.println("ConfigHistory.maxSize="+maxSize);
+        return null;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/karaf-shell/src/main/resources/META-INF/services/org/apache/tamaya/karaf/shell/commands
----------------------------------------------------------------------
diff --git a/osgi/karaf-shell/src/main/resources/META-INF/services/org/apache/tamaya/karaf/shell/commands b/osgi/karaf-shell/src/main/resources/META-INF/services/org/apache/tamaya/karaf/shell/commands
index d8f2000..56a9ff8 100644
--- a/osgi/karaf-shell/src/main/resources/META-INF/services/org/apache/tamaya/karaf/shell/commands
+++ b/osgi/karaf-shell/src/main/resources/META-INF/services/org/apache/tamaya/karaf/shell/commands
@@ -16,11 +16,16 @@
 # specific language governing permissions and limitations
 # under the License.
 #
+org.apache.tamaya.karaf.shell.BackupCreateCommand
+org.apache.tamaya.karaf.shell.BackupDeleteCommand
+org.apache.tamaya.karaf.shell.BackupListCommand
 org.apache.tamaya.karaf.shell.ConfigCommand
 org.apache.tamaya.karaf.shell.DefaultDisableCommand
 org.apache.tamaya.karaf.shell.GetPolicyCommand
 org.apache.tamaya.karaf.shell.HistoryClearCommand
 org.apache.tamaya.karaf.shell.HistoryGetCommand
+org.apache.tamaya.karaf.shell.HistorySizeGetCommand
+org.apache.tamaya.karaf.shell.HistorySizeSetCommand
 org.apache.tamaya.karaf.shell.InfoCommand
 org.apache.tamaya.karaf.shell.PolicyGetCommand
 org.apache.tamaya.karaf.shell.PolicySetCommand

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/pom.xml
----------------------------------------------------------------------
diff --git a/osgi/pom.xml b/osgi/pom.xml
index 4797b94..8a30a69 100644
--- a/osgi/pom.xml
+++ b/osgi/pom.xml
@@ -288,6 +288,7 @@
 
     <modules>
         <module>common</module>
+        <module>updater</module>
         <module>karaf-shell</module>
         <!--<module>karaf-features</module>-->
     </modules>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/99ce49ed/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java
----------------------------------------------------------------------
diff --git a/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java b/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java
index 55bbd6d..4c2c50b 100644
--- a/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java
+++ b/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java
@@ -46,6 +46,7 @@ public class Activator implements BundleActivator {
         listener = new EventListener(context);
         ConfigEventManager.addListener(listener, ConfigurationChange.class);
         LOG.info("Registered Tamaya config trigger for OSGI.");
+        ConfigEventManager.enableChangeMonitoring(true);
     }
 
     @Override
@@ -53,6 +54,7 @@ public class Activator implements BundleActivator {
         if (listener != null) {
             ConfigEventManager.removeListener(this.listener, ConfigurationChange.class);
             LOG.info("Unregistered Tamaya config trigger for OSGI.");
+            ConfigEventManager.enableChangeMonitoring(false);
         }
     }