tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anat...@apache.org
Subject [6/7] incubator-tamaya-extensions git commit: TAMAYA-300 Added tests to improve mutation coverage. Movewd OSGI and MP to extensions.
Date Mon, 16 Oct 2017 23:03:22 GMT
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/main/java/org/apache/tamaya/microprofile/converter/BooleanAsIntegerConverterFix.java
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/main/java/org/apache/tamaya/microprofile/converter/BooleanAsIntegerConverterFix.java b/modules/microprofile/src/main/java/org/apache/tamaya/microprofile/converter/BooleanAsIntegerConverterFix.java
new file mode 100644
index 0000000..1debc71
--- /dev/null
+++ b/modules/microprofile/src/main/java/org/apache/tamaya/microprofile/converter/BooleanAsIntegerConverterFix.java
@@ -0,0 +1,61 @@
+/*
+ * 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.microprofile.converter;
+
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+import javax.annotation.Priority;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean for 1 = true, otherwise false.
+ */
+@Priority(-1)
+public class BooleanAsIntegerConverterFix implements PropertyConverter<Boolean> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public Boolean convert(String value, ConversionContext context) {
+        context.addSupportedFormats(getClass(), "'1' (true), otherwise false.");
+        try{
+            int val = Integer.parseInt(Objects.requireNonNull(value).trim());
+            if(val==1) {
+                return Boolean.TRUE;
+            }
+            return Boolean.FALSE;
+        }catch(Exception e){
+            // OK
+            return Boolean.FALSE;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/main/java/org/apache/tamaya/microprofile/converter/ProviderConverter.java
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/main/java/org/apache/tamaya/microprofile/converter/ProviderConverter.java b/modules/microprofile/src/main/java/org/apache/tamaya/microprofile/converter/ProviderConverter.java
new file mode 100644
index 0000000..163481d
--- /dev/null
+++ b/modules/microprofile/src/main/java/org/apache/tamaya/microprofile/converter/ProviderConverter.java
@@ -0,0 +1,98 @@
+/*
+ * 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.microprofile.converter;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigQuery;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+import javax.annotation.Priority;
+import javax.inject.Provider;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean for 1 = true, otherwise false.
+ */
+@Priority(-1)
+public class ProviderConverter implements PropertyConverter<Provider> {
+
+    private static final Logger LOG = Logger.getLogger(ProviderConverter.class.getName());
+
+    @Override
+    public Provider convert(String value, ConversionContext context) {
+        return () -> {
+            try{
+                Type targetType = context.getTargetType().getType();
+                ConvertQuery converter = new ConvertQuery(value, TypeLiteral.of(targetType));
+                return context.getConfiguration().query(converter);
+            }catch(Exception e){
+                throw new ConfigException("Error evaluating config value.", e);
+            }
+        };
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+
+    private static final class ConvertQuery<T> implements ConfigQuery<T> {
+
+        private String rawValue;
+        private TypeLiteral<T> type;
+
+        public ConvertQuery(String rawValue, TypeLiteral<T> type) {
+            this.rawValue = Objects.requireNonNull(rawValue);
+            this.type = Objects.requireNonNull(type);
+        }
+
+        @Override
+        public T query(Configuration config) {
+            List<PropertyConverter<T>> converters = config.getContext().getPropertyConverters(type);
+            ConversionContext context = new ConversionContext.Builder(type).setConfigurationContext(config.getContext())
+                    .setConfiguration(config).setKey(ConvertQuery.class.getName()).build();
+            for(PropertyConverter<?> conv: converters) {
+                try{
+                    if(conv instanceof ProviderConverter){
+                        continue;
+                    }
+                    T result = (T)conv.convert(rawValue, context);
+                    if(result!=null){
+                        return result;
+                    }
+                }catch(Exception e){
+                    LOG.log(Level.FINEST,  e, () -> "Converter "+ conv +" failed to convert to " + type);
+                }
+            }
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/modules/microprofile/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..21ec9d5
--- /dev/null
+++ b/modules/microprofile/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+
+org.apache.tamaya.microprofile.cdi.MicroprofileCDIExtension
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter b/modules/microprofile/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
new file mode 100644
index 0000000..2205fa2
--- /dev/null
+++ b/modules/microprofile/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+
+org.apache.tamaya.microprofile.converter.BooleanAsIntegerConverterFix
+org.apache.tamaya.microprofile.converter.ProviderConverter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/modules/microprofile/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
new file mode 100644
index 0000000..585700b
--- /dev/null
+++ b/modules/microprofile/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+
+org.apache.tamaya.microprofile.MicroprofileDefaultProperties
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver b/modules/microprofile/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver
new file mode 100644
index 0000000..040f5fd
--- /dev/null
+++ b/modules/microprofile/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+
+org.apache.tamaya.microprofile.MicroprofileConfigProviderResolver
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/main/resources/beans.xml
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/main/resources/beans.xml b/modules/microprofile/src/main/resources/beans.xml
new file mode 100644
index 0000000..9b07802
--- /dev/null
+++ b/modules/microprofile/src/main/resources/beans.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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 current 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.
+-->
+<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">
+
+
+</beans>
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigBuilderTest.java
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigBuilderTest.java b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigBuilderTest.java
new file mode 100644
index 0000000..3250102
--- /dev/null
+++ b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigBuilderTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.microprofile;
+
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.spi.ConfigBuilder;
+import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 24.03.17.
+ */
+public class MicroprofileConfigBuilderTest {
+
+    private ConfigSource testSource = new ConfigSource() {
+        @Override
+        public Map<String, String> getProperties() {
+            Map<String,String> map = new HashMap<>();
+            map.put("timestamp", String.valueOf(System.currentTimeMillis()));
+            return map;
+        }
+
+        @Override
+        public String getValue(String propertyName) {
+            if("timestamp".equals(propertyName)){
+                return String.valueOf(System.currentTimeMillis());
+            }
+            return null;
+        }
+
+        @Override
+        public String getName() {
+            return "test";
+        }
+    };
+
+    @Test
+    public void testBuildEmptyConfig(){
+        ConfigBuilder builder = ConfigProviderResolver.instance().getBuilder();
+        assertNotNull(builder);
+        Config config = builder.build();
+        assertNotNull(config);
+        assertFalse(config.getPropertyNames().iterator().hasNext());
+        assertFalse(config.getConfigSources().iterator().hasNext());
+    }
+
+    @Test
+    public void testBuildConfig(){
+        ConfigBuilder builder = ConfigProviderResolver.instance().getBuilder();
+        assertNotNull(builder);
+        builder.withSources(testSource);
+        Config config = builder.build();
+        assertNotNull(config);
+        assertTrue(config.getPropertyNames().iterator().hasNext());
+        assertTrue(config.getConfigSources().iterator().hasNext());
+        assertNotNull(config.getValue("timestamp", String.class));
+        ConfigSource src = config.getConfigSources().iterator().next();
+        assertNotNull(src);
+        assertEquals(src, testSource);
+    }
+
+    @Test
+    public void testBuildDefaultConfig(){
+        ConfigBuilder builder = ConfigProviderResolver.instance().getBuilder();
+        assertNotNull(builder);
+        builder.addDefaultSources();
+        Config config = builder.build();
+        assertNotNull(config);
+        assertTrue(config.getPropertyNames().iterator().hasNext());
+        assertTrue(config.getConfigSources().iterator().hasNext());
+        assertNotNull(config.getValue("java.home", String.class));
+        ConfigSource src = config.getConfigSources().iterator().next();
+        assertNotNull(src);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigProviderResolverTest.java
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigProviderResolverTest.java b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigProviderResolverTest.java
new file mode 100644
index 0000000..9b6b554
--- /dev/null
+++ b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigProviderResolverTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.microprofile;
+
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.spi.ConfigBuilder;
+import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
+import org.junit.Test;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 24.03.17.
+ */
+public class MicroprofileConfigProviderResolverTest {
+
+    @Test
+    public void testInstance(){
+        assertNotNull(ConfigProviderResolver.instance());
+    }
+
+    @Test
+    public void testGetBuilder(){
+        assertNotNull(ConfigProviderResolver.instance().getBuilder());
+    }
+
+    @Test
+    public void testGetConfig(){
+        assertNotNull(ConfigProviderResolver.instance().getConfig());
+    }
+
+    @Test
+    public void testGetConfig_CL(){
+        assertNotNull(ConfigProviderResolver.instance().getConfig(ClassLoader.getSystemClassLoader()));
+    }
+
+    @Test
+    public void testRegisterAndReleaseConfig(){
+        ClassLoader cl = new URLClassLoader(new URL[]{});
+        Config emptyConfig = ConfigProviderResolver.instance().getBuilder().build();
+        assertNotNull(emptyConfig);
+        Config cfg = ConfigProviderResolver.instance().getConfig(cl);
+        assertNotNull(cfg);
+        ConfigProviderResolver.instance().registerConfig(emptyConfig, cl);
+        cfg = ConfigProviderResolver.instance().getConfig(cl);
+        assertNotNull(cfg);
+        assertEquals(cfg, emptyConfig);
+        ConfigProviderResolver.instance().releaseConfig(emptyConfig);
+        cfg = ConfigProviderResolver.instance().getConfig(cl);
+        assertNotNull(cfg);
+        assertNotSame(cfg, emptyConfig);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigProviderTest.java
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigProviderTest.java b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigProviderTest.java
new file mode 100644
index 0000000..039145d
--- /dev/null
+++ b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigProviderTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.microprofile;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by atsticks on 24.03.17.
+ */
+public class MicroprofileConfigProviderTest {
+
+    @Test
+    public void testDefaultConfigAccess(){
+        Config config = ConfigProvider.getConfig();
+        assertNotNull(config);
+        Iterable<String> names = config.getPropertyNames();
+        assertNotNull(names);
+        int count = 0;
+        for(String name:names){
+            count++;
+            System.out.println(count + ": " +name);
+        }
+        assertTrue(ConfigurationProvider.getConfiguration().getProperties().size() <= count);
+    }
+
+    @Test
+    public void testClassloaderAccess(){
+        Config config = ConfigProvider.getConfig(Thread.currentThread().getContextClassLoader());
+        assertNotNull(config);
+        Iterable<String> names = config.getPropertyNames();
+        assertNotNull(names);
+        int count = 0;
+        for(String name:names){
+            count++;
+        }
+        assertTrue(count>0);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigTest.java
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigTest.java b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigTest.java
new file mode 100644
index 0000000..1c5375a
--- /dev/null
+++ b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/MicroprofileConfigTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.microprofile;
+
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.junit.Test;
+
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 24.03.17.
+ */
+public class MicroprofileConfigTest {
+
+    @Test
+    public void testDefaultConfigAccess() {
+        Config config = ConfigProvider.getConfig();
+        Iterable<ConfigSource> sources = config.getConfigSources();
+        int count = 0;
+        for (ConfigSource cs : sources) {
+            count++;
+        }
+        assertEquals(3, count);
+    }
+
+    @Test
+    public void testOptionalAccess(){
+        Config config = ConfigProvider.getConfig();
+        int count = 0;
+        for(String key:config.getPropertyNames()){
+            Optional<String> val = config.getOptionalValue(key, String.class);
+            assertNotNull(val);
+            val = config.getOptionalValue(key + System.currentTimeMillis(), String.class);
+            assertNotNull(val);
+            assertFalse(val.isPresent());
+        }
+    }
+
+    @Test
+    public void testGetValue(){
+        Config config = ConfigProvider.getConfig();
+        int count = 0;
+        for(String key:config.getPropertyNames()){
+            String val = config.getValue(key, String.class);
+            assertNotNull(val);
+        }
+    }
+
+    @Test(expected = NoSuchElementException.class)
+    public void testGetValue_NoValue(){
+        Config config = ConfigProvider.getConfig();
+        config.getValue("fooBar", String.class);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetValue_InvalidType(){
+        Config config = ConfigProvider.getConfig();
+        config.getValue("java.version", Integer.class);
+    }
+
+    @Test
+    public void testEmptySystemProperty(){
+        System.setProperty("my.empty.property", "");
+        Config config = ConfigProvider.getConfig();
+        assertEquals("", config.getValue("my.empty.property", String.class));
+    }
+
+    @Test
+    public void testEmptyConfigProperty(){
+        Config config = ConfigProvider.getConfig();
+        assertEquals("", config.getValue("my.empty.property.in.config.file", String.class));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/tck/TamayaConfigArchiveProcessor.java
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/tck/TamayaConfigArchiveProcessor.java b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/tck/TamayaConfigArchiveProcessor.java
new file mode 100644
index 0000000..61cd11c
--- /dev/null
+++ b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/tck/TamayaConfigArchiveProcessor.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.microprofile.tck;
+
+import org.apache.tamaya.core.internal.converters.OptionalConverter;
+import org.apache.tamaya.microprofile.MicroprofileAdapter;
+import org.apache.tamaya.microprofile.MicroprofileConfigProviderResolver;
+import org.apache.tamaya.microprofile.cdi.MicroprofileCDIExtension;
+import org.apache.tamaya.microprofile.converter.BooleanAsIntegerConverterFix;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
+import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
+import org.jboss.arquillian.test.spi.TestClass;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+
+import javax.enterprise.inject.spi.Extension;
+import java.io.File;
+
+/**
+ * Adds the whole Config implementation classes and resources to the
+ * Arquillian deployment archive. This is needed to have the container
+ * pick up the beans from within the impl for the TCK tests.
+ *
+ * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
+ */
+public class TamayaConfigArchiveProcessor implements ApplicationArchiveProcessor {
+
+    @Override
+    public void process(Archive<?> applicationArchive, TestClass testClass) {
+        if (applicationArchive instanceof WebArchive) {
+            File[] coreLibs = Maven.resolver()
+                    .loadPomFromFile("pom.xml").resolve("org.apache.tamaya:tamaya-core")
+                    .withTransitivity().asFile();
+            File[] apiLibs = Maven.resolver()
+                    .loadPomFromFile("pom.xml").resolve("org.apache.tamaya:tamaya-api")
+                    .withTransitivity().asFile();
+            File[] functionsLib = Maven.resolver()
+                    .loadPomFromFile("pom.xml").resolve("org.apache.tamaya.ext:tamaya-functions")
+                    .withTransitivity().asFile();
+
+            JavaArchive configJar = ShrinkWrap
+                    .create(JavaArchive.class, "tamaya-config-impl.jar")
+                    .addPackage(MicroprofileAdapter.class.getPackage())
+                    .addPackage(MicroprofileCDIExtension.class.getPackage())
+                    .addPackage(BooleanAsIntegerConverterFix.class.getPackage())
+                    .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
+                    .addAsServiceProvider(ConfigProviderResolver.class, MicroprofileConfigProviderResolver.class)
+                    .addAsServiceProvider(PropertyConverter.class, BooleanAsIntegerConverterFix.class)
+                    .addAsServiceProvider(PropertyConverter.class, OptionalConverter.class)
+                    .addAsServiceProvider(Extension.class, MicroprofileCDIExtension.class);
+            ((WebArchive) applicationArchive).addAsLibraries(
+                    configJar)
+                    .addAsLibraries(apiLibs)
+                    .addAsLibraries(coreLibs)
+                    .addAsLibraries(functionsLib);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/tck/TamayaConfigExtension.java
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/tck/TamayaConfigExtension.java b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/tck/TamayaConfigExtension.java
new file mode 100644
index 0000000..9c0dfd3
--- /dev/null
+++ b/modules/microprofile/src/test/java/org/apache/tamaya/microprofile/tck/TamayaConfigExtension.java
@@ -0,0 +1,36 @@
+/*
+ * 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.microprofile.tck;
+
+import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
+import org.jboss.arquillian.core.spi.LoadableExtension;
+
+/**
+ * Arquillian extension to load Tamaya into Arquillian context.
+ * @author <a href="mailto:anatole@apache.org">Anatole Tresch</a>
+ */
+public class TamayaConfigExtension implements LoadableExtension {
+
+    @Override
+    public void register(ExtensionBuilder extensionBuilder) {
+        extensionBuilder.service(
+                ApplicationArchiveProcessor.class,
+                TamayaConfigArchiveProcessor.class);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/resources/META-INF/beans.xml b/modules/microprofile/src/test/resources/META-INF/beans.xml
new file mode 100644
index 0000000..adee378
--- /dev/null
+++ b/modules/microprofile/src/test/resources/META-INF/beans.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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 current 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.
+-->
+<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">
+
+</beans>
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/resources/META-INF/microprofile-config.properties
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/resources/META-INF/microprofile-config.properties b/modules/microprofile/src/test/resources/META-INF/microprofile-config.properties
new file mode 100644
index 0000000..2e63bf8
--- /dev/null
+++ b/modules/microprofile/src/test/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,105 @@
+#
+# Copyright (c) 2016-2017 Contributors to the Eclipse Foundation
+#
+# See the NOTICES file(s) distributed with this work for additional
+# information regarding copyright ownership.
+#
+# Licensed 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.
+#
+
+my.optional.int.property=1234
+my.optional.string.property=hello
+
+tck.config.test.javaconfig.properties.key1=VALue1
+
+
+tck.config.test.overwritten.in.custompropertyfile.key1=value from microprofile-config.properties
+
+
+tck.config.test.javaconfig.converter.integervalue = 1234
+tck.config.test.javaconfig.converter.integervalue.broken = xxx
+
+tck.config.test.javaconfig.converter.longvalue = 1234567890
+tck.config.test.javaconfig.converter.longvalue.broken = xxx
+
+tck.config.test.javaconfig.converter.floatvalue = 12.34
+tck.config.test.javaconfig.converter.floatvalue.broken = alfasdf
+
+tck.config.test.javaconfig.converter.doublevalue = 12.34
+tck.config.test.javaconfig.converter.doublevalue.broken = alfasdf
+
+tck.config.test.javaconfig.converter.durationvalue = PT15M
+tck.config.test.javaconfig.converter.durationvalue.broken = alfasdf
+
+tck.config.test.javaconfig.converter.localtimevalue = 10:37
+tck.config.test.javaconfig.converter.localtimevalue.broken = alfasdf
+
+tck.config.test.javaconfig.converter.localdatevalue = 2017-12-24
+tck.config.test.javaconfig.converter.localdatevalue.broken = alfasdf
+
+tck.config.test.javaconfig.converter.localdatetimevalue = 2017-12-24T10:25:30
+tck.config.test.javaconfig.converter.localdatetimevalue.broken = alfasdf
+
+tck.config.test.javaconfig.converter.offsetdatetimevalue = 2007-12-03T10:15:30+01:00
+tck.config.test.javaconfig.converter.offsetdatetimevalue.broken = alfasdf
+
+tck.config.test.javaconfig.converter.offsettimevalue = 13:45:30.123456789+02:00
+tck.config.test.javaconfig.converter.offsettimevalue.broken = alfasdf
+
+tck.config.test.javaconfig.converter.instantvalue = 2015-06-02T21:34:33.616Z
+tck.config.test.javaconfig.converter.instantvalue.broken = alfasdf
+
+tck.config.test.javaconfig.configvalue.key1=value1
+
+# test BooleanConverter START
+tck.config.test.javaconfig.configvalue.boolean.true=true
+tck.config.test.javaconfig.configvalue.boolean.true_uppercase=TRUE
+tck.config.test.javaconfig.configvalue.boolean.true_mixedcase=TruE
+tck.config.test.javaconfig.configvalue.boolean.false=false
+
+tck.config.test.javaconfig.configvalue.boolean.one=1
+tck.config.test.javaconfig.configvalue.boolean.zero=0
+tck.config.test.javaconfig.configvalue.boolean.seventeen=17
+
+tck.config.test.javaconfig.configvalue.boolean.yes=yes
+tck.config.test.javaconfig.configvalue.boolean.yes_uppercase=YES
+tck.config.test.javaconfig.configvalue.boolean.yes_mixedcase=Yes
+tck.config.test.javaconfig.configvalue.boolean.no=no
+
+tck.config.test.javaconfig.configvalue.boolean.y=y
+tck.config.test.javaconfig.configvalue.boolean.y_uppercase=Y
+tck.config.test.javaconfig.configvalue.boolean.n=n
+
+tck.config.test.javaconfig.configvalue.boolean.on=on
+tck.config.test.javaconfig.configvalue.boolean.on_uppercase=ON
+tck.config.test.javaconfig.configvalue.boolean.on_mixedcase=oN
+tck.config.test.javaconfig.configvalue.boolean.off=off
+
+# test BooleanConverter END
+
+# various other converter
+tck.config.test.javaconfig.configvalue.integer=1234
+tck.config.test.javaconfig.configvalue.long=1234567890123456
+tck.config.test.javaconfig.configvalue.float=12.34
+tck.config.test.javaconfig.configvalue.double=12.34567890123456
+
+# Custom Converter tests
+tck.config.test.javaconfig.converter.duckname=Hannelore
+
+# URL Converter tests
+tck.config.test.javaconfig.converter.urlvalue=http://microprofile.io
+tck.config.test.javaconfig.converter.urlvalue.broken=tt:--location$
+
+# Empty values
+my.empty.property.in.config.file=
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/modules/microprofile/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100644
index 0000000..b2af25c
--- /dev/null
+++ b/modules/microprofile/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+org.apache.tamaya.microprofile.tck.TamayaConfigExtension
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/resources/sampleconfig.yaml
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/resources/sampleconfig.yaml b/modules/microprofile/src/test/resources/sampleconfig.yaml
new file mode 100644
index 0000000..27f2392
--- /dev/null
+++ b/modules/microprofile/src/test/resources/sampleconfig.yaml
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2016-2017 Mark Struberg and others
+#
+# Licensed 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.
+#
+# just needed as a trigger for the ConfigSource pickup.
+# Content is hardcoded in SampleYamlConfigSource
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/microprofile/src/test/tck-suite.xml
----------------------------------------------------------------------
diff --git a/modules/microprofile/src/test/tck-suite.xml b/modules/microprofile/src/test/tck-suite.xml
new file mode 100644
index 0000000..84d36ad
--- /dev/null
+++ b/modules/microprofile/src/test/tck-suite.xml
@@ -0,0 +1,27 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+<!--
+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 current 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.
+-->
+<suite name="microprofile-config-TCK" verbose="2" configfailurepolicy="continue" >
+        <test name="microprofile-config 1.1 TCK">
+            <packages>
+                <package name="org.eclipse.microprofile.config.tck.*">
+                </package>
+            </packages>
+        </test>
+</suite>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/osgi/common/bnd.bnd
----------------------------------------------------------------------
diff --git a/modules/osgi/common/bnd.bnd b/modules/osgi/common/bnd.bnd
new file mode 100644
index 0000000..e937379
--- /dev/null
+++ b/modules/osgi/common/bnd.bnd
@@ -0,0 +1,33 @@
+-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 ConfigurationPlugin
+Bundle-SymbolicName: org.apache.tamaya.osgi
+Bundle-Description: Apacha Tamaya Configuration - OSGI ConfigurationPlugin
+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.Activator
+Export-Package: \
+	org.apache.tamaya.osgi,\
+	org.apache.tamaya.osgi.commands
+Import-Package: \
+    org.osgi.framework,\
+    org.osgi.service.cm,\
+    org.apache.tamaya,\
+    org.apache.tamaya.spi,\
+    org.apache.tamaya.functions,\
+    org.apache.tamaya.spisupport
+Export-Service:   org.apache.tamaya.osgi.commands.TamayaConfigService

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/osgi/common/pom.xml
----------------------------------------------------------------------
diff --git a/modules/osgi/common/pom.xml b/modules/osgi/common/pom.xml
new file mode 100644
index 0000000..622907b
--- /dev/null
+++ b/modules/osgi/common/pom.xml
@@ -0,0 +1,91 @@
+<?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</artifactId>
+    <packaging>jar</packaging>
+    <name>Apache Tamaya :: OSGi :: Common</name>
+    <description>Tamaya Based OSGI Common Functionality</description>
+
+    <properties>
+        <osgi.config.version>1.5.0</osgi.config.version>
+        <osgi.tracker.version>1.5.1</osgi.tracker.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.util.tracker</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>
+
+        <!-- Testing -->
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Activator.java b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Activator.java
new file mode 100644
index 0000000..aef323d
--- /dev/null
+++ b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Activator.java
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.tamaya.osgi.commands.TamayaConfigService;
+import org.osgi.framework.*;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationPlugin;
+import org.osgi.service.component.annotations.Reference;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+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 Integer DEFAULT_RANKING = 100000;
+
+    private static final Logger LOG = Logger.getLogger(Activator.class.getName());
+
+    private ServiceRegistration<TamayaConfigService> registration;
+
+    private TamayaConfigPlugin plugin;
+
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        ServiceReference<ConfigurationAdmin> cmRef = context.getServiceReference(ConfigurationAdmin.class);
+        ConfigurationAdmin cm = context.getService(cmRef);
+        Configuration configuration = cm.getConfiguration(TamayaConfigPlugin.COMPONENTID, null);
+        this.plugin = new TamayaConfigPlugin(context);
+        Dictionary<String, Object> props = new Hashtable<>();
+        props.put(Constants.SERVICE_RANKING, DEFAULT_RANKING);
+        LOG.info("Registering Tamaya OSGI Config Service...");
+        registration = context.registerService(
+                TamayaConfigService.class,
+                this.plugin, props);
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        if (registration != null) {
+            registration.unregister();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Backups.java
----------------------------------------------------------------------
diff --git a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Backups.java b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Backups.java
new file mode 100644
index 0000000..0ae1048
--- /dev/null
+++ b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Backups.java
@@ -0,0 +1,157 @@
+/*
+ * 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+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;
+
+/**
+ * Singleton class to store OSGI configuration backups before change the OSGI
+ * Config with Tamaya settings. This allows to restore the configuration in
+ * case of issues.
+ */
+final class Backups {
+
+    private static final Logger LOG = Logger.getLogger(Backups.class.getName());
+    public static final String TAMAYA_BACKUP = "tamaya.backup";
+    private static Map<String, Hashtable<String,?>> initialConfigState = new ConcurrentHashMap<>();
+
+    private Backups(){}
+
+    /**
+     * Sets the given backup for a PID.
+     * @param pid the PID, not null.
+     * @param config the config to store.
+     */
+    public static void set(String pid, Dictionary<String,?> config){
+        initialConfigState.put(pid, toHashtable(config));
+    }
+
+    /**
+     * Converts the dictionary to a hash table to enabled serialization.
+     * @param dictionary he config, not null.
+     * @return the correspoinding Hashtable
+     */
+    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;
+    }
+
+    /**
+     * Removes a backup.
+     * @param pid the PID, not null.
+     * @return
+     */
+    public static Dictionary<String,?> remove(String pid){
+        return initialConfigState.remove(pid);
+    }
+
+    /**
+     * Removes all backups.
+     */
+    public static void removeAll(){
+        initialConfigState.clear();
+    }
+
+    /**
+     * Get a backup for a PID.
+     * @param pid the PID, not null.
+     * @return the backup found, or null.
+     */
+    public static Dictionary<String,?> get(String pid){
+        return initialConfigState.get(pid);
+    }
+
+    /**
+     * Get all current stored backups.
+     * @return The backups stored, by PID.
+     */
+    public static Map<String,Dictionary<String,?>> get(){
+        return new HashMap<>(initialConfigState);
+    }
+
+    /**
+     * Get all current kjnown PIDs.
+     * @return the PIDs, never null.
+     */
+    public static Set<String> getPids(){
+        return initialConfigState.keySet();
+    }
+
+    /**
+     * Checks if a backup exists for a given PID.
+     * @param pid the pid, not null.
+     * @return
+     */
+    public static boolean contains(String pid){
+        return initialConfigState.containsKey(pid);
+    }
+
+    /**
+     * Saves the bachups into the given config.
+     * @param config the config, not nul.
+     */
+    public static void save(Dictionary<String,Object> config){
+        try{
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(initialConfigState);
+            oos.flush();
+            Base64.getEncoder().encode(bos.toByteArray());
+            config.put(TAMAYA_BACKUP, Base64.getEncoder().encodeToString(bos.toByteArray()));
+        }catch(Exception e){
+            LOG.log(Level.SEVERE, "Failed to restore OSGI Backups.", e);
+        }
+    }
+
+    /**
+     * Restores the backups ino the given config.
+     * @param config the config, not null.
+     */
+    public static void restore(Dictionary<String,Object> config){
+        try{
+            String serialized = (String)config.get("tamaya.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 getConfig change getHistory.", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigChanger.java
----------------------------------------------------------------------
diff --git a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigChanger.java b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigChanger.java
new file mode 100644
index 0000000..0969a59
--- /dev/null
+++ b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigChanger.java
@@ -0,0 +1,215 @@
+/*
+ * 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 org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Created by atsticks on 19.09.17.
+ */
+final class ConfigChanger {
+
+    private static final Logger LOG = Logger.getLogger(TamayaConfigPlugin.class.getName());
+
+    private BundleContext context;
+    private ConfigurationAdmin cm;
+
+    public ConfigChanger(BundleContext context){
+        this.context = context;
+        ServiceReference<ConfigurationAdmin> cmRef = context.getServiceReference(ConfigurationAdmin.class);
+        this.cm = context.getService(cmRef);
+    }
+
+    public BundleContext getContext(){
+        return context;
+    }
+
+    public ConfigurationAdmin getConfigurationAdmin(){
+        return cm;
+    }
+
+    public Dictionary<String, Object> configure(String pid, Bundle bundle, Policy policy, boolean opModeExplicit, boolean dryRun) {
+        try {
+            String root = '[' + pid + ']';
+            // TODO Check for Bundle.getLocation() usage here...
+            Configuration osgiConfig = cm.getConfiguration(pid, bundle!=null?bundle.getLocation():null);
+            Policy opMode = Objects.requireNonNull(policy);
+            // Check manifest config
+            if(bundle!=null) {
+                if(!opModeExplicit) {
+                    String opVal = bundle.getHeaders().get(TamayaConfigPlugin.TAMAYA_POLICY_MANIFEST);
+                    if (opVal != null) {
+                        opMode = Policy.valueOf(opVal.toUpperCase());
+                    }
+                }
+                String customRoot = bundle.getHeaders().get(TamayaConfigPlugin.TAMAYA_CUSTOM_ROOT_MANIFEST);
+                if(customRoot!=null){
+                    root = customRoot;
+                }
+            }
+            // Check for dynamic OSGI overrides
+            if(osgiConfig!=null){
+                Dictionary<String,Object> props = osgiConfig.getProperties();
+                if(props!=null){
+                    if(!opModeExplicit) {
+                        String opVal = (String) props.get(TamayaConfigPlugin.TAMAYA_POLICY_PROP);
+                        if (opVal != null) {
+                            opMode = Policy.valueOf(opVal.toUpperCase());
+                        }
+                    }
+                    String customRoot = (String)props.get(TamayaConfigPlugin.TAMAYA_CUSTOM_ROOT_PROP);
+                    if(customRoot!=null){
+                        root = customRoot;
+                    }
+                }else{
+                    props = new Hashtable<>();
+                }
+                if(!dryRun && !Backups.contains(pid)){
+                    Backups.set(pid, props);
+                    LOG.finest("Stored OSGI configuration backup for PID: " + pid);
+                }
+                LOG.finest("Evaluating Tamaya Config for PID: " + pid);
+                org.apache.tamaya.Configuration tamayaConfig = getTamayaConfiguration(root);
+                if (tamayaConfig == null) {
+                    LOG.finest("No Tamaya configuration for root: " + root);
+                }else {
+                    if(dryRun){
+                        modifyConfiguration(pid, tamayaConfig, props, opMode);
+                    }else {
+                        try {
+                            if (bundle != null) {
+                                ConfigHistory.configuring(pid, "bundle=" + bundle.getSymbolicName() + ", opMode=" + opMode);
+                            } else {
+                                ConfigHistory.configuring(pid, "trigger=Tamaya, opMode=" + opMode);
+                            }
+                            modifyConfiguration(pid, tamayaConfig, props, opMode);
+                            if (!props.isEmpty()) {
+                                osgiConfig.update(props);
+                                LOG.info("Updated configuration for PID: " + pid + ": " + props);
+                                ConfigHistory.configured(pid, "SUCCESS");
+                            }
+                        }catch(Exception e){
+                            LOG.log(Level.WARNING, "Failed to update configuration for PID: " + pid, e);
+                            ConfigHistory.configured(pid, "FAILED: " + e);
+                        }
+                    }
+                }
+                return props;
+            }
+            return null;
+        } catch (Exception e) {
+            LOG.log(Level.WARNING, "Failed to initialize configuration for PID: " + pid, e);
+            return null;
+        }
+    }
+
+    public void modifyConfiguration(String pid, org.apache.tamaya.Configuration config, Dictionary<String, Object> dictionary, Policy opMode) {
+        LOG.info(() -> "Updating configuration for PID: " + pid + "...");
+        dictionary.put("tamaya.modified.at", new Date().toString());
+
+        Map<String, Object> dictionaryMap = new HashMap<>();
+        Enumeration<String> keys = dictionary.keys();
+        while (keys.hasMoreElements()) {
+            String key = keys.nextElement();
+            Object value = dictionary.get(key);
+            dictionaryMap.put(key, value);
+        }
+        for (Map.Entry<String, Object> dictEntry : dictionaryMap.entrySet()) {
+            Object configuredValue = config.getOrDefault(dictEntry.getKey(), dictEntry.getValue().getClass(), null);
+            if (configuredValue != null) {
+                if(configuredValue.equals(dictEntry.getValue())){
+                    continue;
+                }
+                switch (opMode) {
+                    case EXTEND:
+                        break;
+                    case OVERRIDE:
+                        LOG.info(() -> "Setting key " + dictEntry.getKey() + " to " + configuredValue);
+                        ConfigHistory.propertySet(pid,dictEntry.getKey(), configuredValue, dictEntry.getValue());
+                        dictionary.put(dictEntry.getKey(), configuredValue);
+                        break;
+                    case UPDATE_ONLY:
+                        LOG.info(() -> "Setting key " + dictEntry.getKey() + " to " + configuredValue);
+                        ConfigHistory.propertySet(pid,dictEntry.getKey(), configuredValue, dictEntry.getValue());
+                        dictionary.put(dictEntry.getKey(), configuredValue);
+                }
+            }
+        }
+        for (Map.Entry<String, String> configEntry : config.getProperties().entrySet()) {
+            Object dictValue = dictionary.get(configEntry.getKey());
+            if(dictValue!=null && dictValue.equals(configEntry.getValue())){
+                continue;
+            }
+            switch (opMode) {
+                case EXTEND:
+                    if(dictValue==null){
+                        LOG.info(() -> "Setting key " + configEntry.getKey() + " to " + configEntry.getValue());
+                        ConfigHistory.propertySet(pid,configEntry.getKey(), configEntry.getValue(), null);
+                        dictionary.put(configEntry.getKey(), configEntry.getValue());
+                    }
+                    break;
+                case OVERRIDE:
+                    LOG.info(() -> "Setting key " + configEntry.getKey() + " to " + configEntry.getValue());
+                    ConfigHistory.propertySet(pid,configEntry.getKey(), configEntry.getValue(), null);
+                    dictionary.put(configEntry.getKey(), configEntry.getValue());
+                    break;
+                case UPDATE_ONLY:
+                    if(dictValue!=null){
+                        LOG.info(() -> "Setting key " + configEntry.getKey() + " to " + configEntry.getValue());
+                        ConfigHistory.propertySet(pid,configEntry.getKey(), configEntry.getValue(), dictValue);
+                        dictionary.put(configEntry.getKey(), configEntry.getValue());
+                    }
+                    break;
+            }
+        }
+    }
+
+    public org.apache.tamaya.Configuration getTamayaConfiguration(String root) {
+        if (root != null) {
+            return ConfigurationProvider.getConfiguration()
+                    .with(ConfigurationFunctions.section(root, true));
+        }
+        return null;
+    }
+
+    public void restoreBackup(String pid, Dictionary<String, Object> config)throws IOException{
+        Configuration osgiConfig = cm.getConfiguration(pid);
+        if(osgiConfig!=null){
+            config.put(TamayaConfigPlugin.TAMAYA_ENABLED_PROP, "false");
+            osgiConfig.update(Objects.requireNonNull(config));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
----------------------------------------------------------------------
diff --git a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
new file mode 100644
index 0000000..dc41787
--- /dev/null
+++ b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/ConfigHistory.java
@@ -0,0 +1,268 @@
+/*
+ * 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.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 implements Serializable{
+
+    private static final long serialVersionUID = 1L;
+    private static final Logger LOG = Logger.getLogger(ConfigHistory.class.getName());
+    /** The key of the plugin OSGI configuration, where the history is stored/retrieved. */
+    private static final String HISTORY_KEY = "tamaya.history";
+
+    public enum TaskType{
+        PROPERTY,
+        BEGIN,
+        END,
+    }
+    /** The max number of changes tracked. */
+    private static int maxHistory = 10000;
+    /** The overall history. */
+    private static List<ConfigHistory> history = new LinkedList<ConfigHistory>();
+
+    /** The entry timestamp. */
+    private long timestamp = System.currentTimeMillis();
+    /** The entry type. */
+    private TaskType type;
+    /** The previous value. */
+    private Object previousValue;
+    /** The current value. */
+    private Object value;
+    /** The key. */
+    private String key;
+    /** The target PID. */
+    private String pid;
+
+    private ConfigHistory(TaskType taskType, String pid){
+        this.type = Objects.requireNonNull(taskType);
+        this.pid = Objects.requireNonNull(pid);
+    }
+
+    /**
+     * Creates and registers an entry when starting to configure a bundle.
+     * @param pid the PID
+     * @param info any info.
+     * @return the entry, never null.
+     */
+    public static ConfigHistory configuring(String pid, String info){
+        ConfigHistory h = new ConfigHistory(TaskType.BEGIN, pid)
+                .setValue(info);
+        synchronized (history){
+            history.add(h);
+            checkHistorySize();
+        }
+        return h;
+    }
+
+    /**
+     * Creates and registers an entry when finished to configure a bundle.
+     * @param pid the PID
+     * @param info any info.
+     * @return the entry, never null.
+     */
+    public static ConfigHistory configured(String pid, String info){
+        ConfigHistory h = new ConfigHistory(TaskType.END, pid)
+                .setValue(info);
+        synchronized (history){
+            history.add(h);
+            checkHistorySize();
+        }
+        return h;
+    }
+
+    /**
+     * Creates and registers an entry when a property has been changed.
+     * @param pid the PID
+     * @param key the key, not null.
+     * @param previousValue the previous value.
+     * @param value the new value.
+     * @return the entry, never null.
+     */
+    public static ConfigHistory propertySet(String pid, String key, Object value, Object previousValue){
+        ConfigHistory h = new ConfigHistory(TaskType.PROPERTY, pid)
+                .setKey(key)
+                .setPreviousValue(previousValue)
+                .setValue(value);
+        synchronized (history){
+            history.add(h);
+            checkHistorySize();
+        }
+        return h;
+    }
+
+    /**
+     * Sets the maximum history size.
+     * @param maxHistory the size
+     */
+    static void setMaxHistory(int maxHistory){
+        ConfigHistory.maxHistory = maxHistory;
+    }
+
+    /**
+     * Get the max history size.
+     * @return the max size
+     */
+    static int getMaxHistory(){
+        return maxHistory;
+    }
+
+    /**
+     * Access the current history.
+     * @return the current history, never null.
+     */
+    static List<ConfigHistory> getHistory(){
+        return getHistory(null);
+    }
+
+    /**
+     * Clears the history.
+     */
+    static void clearHistory(){
+        clearHistory(null);
+    }
+
+    /**
+     * Clears the history for a PID.
+     * @param pid the pid, null clears the full history.
+     */
+    static void clearHistory(String pid){
+        synchronized (history){
+            if("*".equals(pid)) {
+                history.clear();
+            }else{
+                history.removeAll(getHistory(pid));
+            }
+        }
+    }
+
+    /**
+     * Get the history for a PID.
+     * @param pid the pid, null returns the full history.
+     * @return
+     */
+    public static List<ConfigHistory> getHistory(String pid) {
+        if(pid==null || pid.isEmpty()){
+            return new ArrayList<>(history);
+        }
+        synchronized (history) {
+            List<ConfigHistory> result = new ArrayList<>();
+            for (ConfigHistory h : history) {
+                if (h.getPid().startsWith(pid)) {
+                    result.add(h);
+                }
+            }
+            return result;
+        }
+    }
+
+    public TaskType getType(){
+        return type;
+    }
+
+    public String getPid() {
+        return pid;
+    }
+
+    public Object getPreviousValue() {
+        return previousValue;
+    }
+
+    public ConfigHistory setPreviousValue(Object previousValue) {
+        this.previousValue = previousValue;
+        return this;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public ConfigHistory setValue(Object value) {
+        this.value = value;
+        return this;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public ConfigHistory setKey(String key) {
+        this.key = key;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "ConfigHistory{" +
+                "timestamp=" + timestamp +
+                ", previousValue=" + previousValue +
+                ", value=" + value +
+                ", key='" + key + '\'' +
+                '}';
+    }
+
+
+    /**
+     * This methd saves the (serialized) history in the plugin's OSGI configuration using
+     * the HISTORY_KEY key.
+     * @param osgiConfig the plugin config, not null.
+     */
+    static void save(Dictionary<String,Object> osgiConfig){
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(history);
+            oos.flush();
+            osgiConfig.put(HISTORY_KEY, Base64.getEncoder().encodeToString(bos.toByteArray()));
+        } catch (Exception e) {
+            LOG.log(Level.WARNING, "Failed to store getConfig change history.", e);
+        }
+    }
+
+    /**
+     * Restores the history from the plugin's OSGI configuration.
+     * @param osgiConfig
+     */
+    static void restore(Dictionary<String,Object> osgiConfig){
+        try{
+            String serialized = (String)osgiConfig.get(HISTORY_KEY);
+            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 getConfig change history.", e);
+        }
+    }
+
+    private static void checkHistorySize(){
+        while(history.size() > maxHistory){
+            history.remove(0);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/a1cd433a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Policy.java
----------------------------------------------------------------------
diff --git a/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Policy.java b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Policy.java
new file mode 100644
index 0000000..f19c2d1
--- /dev/null
+++ b/modules/osgi/common/src/main/java/org/apache/tamaya/osgi/Policy.java
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+/**
+ * Operation mode applied to the getConfig read.
+ */
+public enum Policy {
+    /** Only add properties not existing in the getConfig. */
+    EXTEND,
+    /** Override existing properties and add new properties. */
+    OVERRIDE,
+    /** Override existing properties only. */
+    UPDATE_ONLY
+}
\ No newline at end of file


Mime
View raw message