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/10/16 23:03:22 UTC
[6/7] incubator-tamaya-extensions git commit: TAMAYA-300 Added tests
to improve mutation coverage. Movewd OSGI and MP to extensions.
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