Repository: incubator-tamaya-extensions Updated Branches: refs/heads/master fe5eac609 -> a1cd433a9
TAMAYA-300 Added tests to improver coverage. Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/commit/1e8ac056 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/tree/1e8ac056 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/diff/1e8ac056 Branch: refs/heads/master Commit: 1e8ac05636110b42adb71ecd5147829890ea3287 Parents: fe5eac6 Author: Anatole Tresch <[email protected]> Authored: Mon Oct 16 15:59:10 2017 +0200 Committer: Anatole Tresch <[email protected]> Committed: Mon Oct 16 15:59:10 2017 +0200 ---------------------------------------------------------------------- modules/osgi/updater/bnd.bnd | 34 +++++++ modules/osgi/updater/pom.xml | 92 +++++++++++++++++ .../apache/tamaya/osgi/updater/Activator.java | 76 ++++++++++++++ .../tamaya/osgi/updater/EventListener.java | 79 +++++++++++++++ .../tamaya/osgi/updater/AbstractOSGITest.java | 101 +++++++++++++++++++ .../tamaya/osgi/updater/ActivatorTest.java | 44 ++++++++ .../tamaya/osgi/updater/EventListenerTest.java | 60 +++++++++++ 7 files changed, 486 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/1e8ac056/modules/osgi/updater/bnd.bnd ---------------------------------------------------------------------- diff --git a/modules/osgi/updater/bnd.bnd b/modules/osgi/updater/bnd.bnd new file mode 100644 index 0000000..416db00 --- /dev/null +++ b/modules/osgi/updater/bnd.bnd @@ -0,0 +1,34 @@ +-buildpath: \ + osgi.annotation; version=6.0.0,\ + osgi.core; version=6.0,\ + osgi.cmpn; version=6.0 + +-testpath: \ + ${junit} + +javac.source: 1.8 +javac.target: 1.8 + +Bundle-Version: ${version}.${tstamp} +Bundle-Name: Apache Tamaya - OSGI Updater +Bundle-SymbolicName: org.apache.tamaya.osgi.updater +Bundle-Description: Apacha Tamaya Configuration - OSGI Updater +Bundle-Category: Implementation +Bundle-Copyright: (C) Apache Foundation +Bundle-License: Apache Licence version 2 +Bundle-Vendor: Apache Software Foundation +Bundle-ContactAddress: [email protected] +Bundle-DocURL: http://tamaya.apache.org +Bundle-Activator: org.apache.tamaya.osgi.updater.Activator +Export-Package: \ + org.apache.tamaya.osgi.updater +Import-Package: \ + org.apache.tamaya.osgi,\ + org.osgi.framework,\ + org.osgi.service.cm,\ + org.apache.tamaya,\ + org.apache.tamaya.spi,\ + org.apache.tamaya.functions,\ + org.apache.tamaya.spisupport,\ + org.apache.tamaya.events + http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/1e8ac056/modules/osgi/updater/pom.xml ---------------------------------------------------------------------- diff --git a/modules/osgi/updater/pom.xml b/modules/osgi/updater/pom.xml new file mode 100644 index 0000000..18d5370 --- /dev/null +++ b/modules/osgi/updater/pom.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-osgi-all</artifactId> + <version>0.4-incubating-SNAPSHOT</version> + </parent> + + <artifactId>tamaya-osgi-updater</artifactId> + <packaging>jar</packaging> + <name>Apache Tamaya :: OSGi :: Updater</name> + <description>Tamaya Based OSGI Updater to propagate Tamaya changes to OSGI.</description> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-api</artifactId> + <version>${project.parent.version}</version> + </dependency> + <dependency> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-core</artifactId> + <version>${project.parent.version}</version> + </dependency> + <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-functions</artifactId> + <version>${project.parent.version}</version> + </dependency> + <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-spisupport</artifactId> + <version>${project.parent.version}</version> + </dependency> + <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-events</artifactId> + <version>${project.parent.version}</version> + </dependency> + <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-osgi</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/1e8ac056/modules/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java ---------------------------------------------------------------------- diff --git a/modules/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java b/modules/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java new file mode 100644 index 0000000..a83f18f --- /dev/null +++ b/modules/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/Activator.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.osgi.updater; + +import org.apache.tamaya.events.ConfigEventManager; +import org.apache.tamaya.events.ConfigurationChange; +import org.apache.tamaya.osgi.commands.TamayaConfigService; +import org.osgi.framework.*; +import org.osgi.service.cm.ConfigurationAdmin; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.logging.Logger; + +/** + * Activator that registers the Tamaya based Service Class for {@link ConfigurationAdmin}, + * using a default service priority of {@code 0}. This behaviour is configurable based on OSGI properties: + * <ul> + * <li><p><b>org.tamaya.integration.osgi.cm.ranking, type: int</b> allows to configure the OSGI service ranking for + * Tamaya based ConfigurationAdmin instance. The default ranking used is 10.</p></li> + * <li><p><b>org.tamaya.integration.osgi.cm.override, type: boolean</b> allows to configure if Tamaya should + * register its ConfigAdmin service. Default is true.</p></li> + * </ul> + */ +public class Activator implements BundleActivator { + + private static final Logger LOG = Logger.getLogger(Activator.class.getName()); + + private EventListener listener; + + private static final long DELAY = 5000L; + private static final long PERIOD = 5000L; + private Timer updateTimer = new Timer("Tamaya OSGI update monitor.", true); + + @Override + public void start(BundleContext context) throws Exception { + listener = new EventListener(context); + ConfigEventManager.addListener(listener, ConfigurationChange.class); + LOG.info("Registered Tamaya getConfig trigger for OSGI."); + ServiceReference<TamayaConfigService> pluginRef = context.getServiceReference(TamayaConfigService.class); + TamayaConfigService tamayaPlugin = context.getService(pluginRef); + updateTimer.schedule(new TimerTask() { + @Override + public void run() { + ConfigEventManager.enableChangeMonitoring(tamayaPlugin.isAutoUpdateEnabled()); + } + }, DELAY, PERIOD); + } + + @Override + public void stop(BundleContext context) throws Exception { + updateTimer.cancel(); + if (listener != null) { + ConfigEventManager.removeListener(this.listener, ConfigurationChange.class); + LOG.info("Unregistered Tamaya getConfig trigger for OSGI."); + ConfigEventManager.enableChangeMonitoring(false); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/1e8ac056/modules/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/EventListener.java ---------------------------------------------------------------------- diff --git a/modules/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/EventListener.java b/modules/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/EventListener.java new file mode 100644 index 0000000..68e9bcb --- /dev/null +++ b/modules/osgi/updater/src/main/java/org/apache/tamaya/osgi/updater/EventListener.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.osgi.updater; + +import org.apache.tamaya.events.ConfigEvent; +import org.apache.tamaya.events.ConfigEventListener; +import org.apache.tamaya.events.ConfigurationChange; +import org.apache.tamaya.osgi.Policy; +import org.apache.tamaya.osgi.commands.TamayaConfigService; +import org.osgi.framework.*; +import org.osgi.service.cm.ConfigurationAdmin; + +import java.beans.PropertyChangeEvent; +import java.util.*; +import java.util.logging.Logger; + +/** + * Tamaya plugin that updates/extends the component configurations managed + * by {@link ConfigurationAdmin}, based on the configured {@link Policy}. + */ +final class EventListener implements ConfigEventListener{ + private static final Logger LOG = Logger.getLogger(EventListener.class.getName()); + private BundleContext context; + + public EventListener(BundleContext context){ + this.context = context; + } + + + @Override + public void onConfigEvent(ConfigEvent<?> event) { + LOG.finest("Tamya Config change triggered: " + event); + Set<String> changedPids = new HashSet<>(); + ConfigurationChange cc = (ConfigurationChange)event; + for(PropertyChangeEvent evt: cc.getChanges()){ + String key = evt.getPropertyName(); + String pid = getPid(key); + if(pid!=null){ + changedPids.add(pid); + } + } + if(changedPids.isEmpty()){ + LOG.finest("Tamya Config change not targeting OSGI."); + return; + } + LOG.finest("Tamya Config change for pids: " + changedPids); + // Reload the given pids + ServiceReference<TamayaConfigService> pluginRef = context.getServiceReference(TamayaConfigService.class); + TamayaConfigService tamayaPlugin = context.getService(pluginRef); + for(String pid:changedPids) { + tamayaPlugin.updateConfig(pid); + } + } + + private String getPid(String key) { + int index0 = key.indexOf("["); + int index1 = key.indexOf("]"); + if(index0 >=0 && (index1 - index0) > 0){ + return key.substring(index0+1,index1); + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/1e8ac056/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/AbstractOSGITest.java ---------------------------------------------------------------------- diff --git a/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/AbstractOSGITest.java b/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/AbstractOSGITest.java new file mode 100644 index 0000000..6f9f521 --- /dev/null +++ b/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/AbstractOSGITest.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.osgi.updater; + +import org.apache.tamaya.osgi.TamayaConfigPlugin; +import org.apache.tamaya.osgi.commands.TamayaConfigService; +import org.junit.Before; +import org.mockito.Mock; +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.util.Dictionary; +import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.*; + +/** + * Created by atsticks on 27.09.17. + */ +public abstract class AbstractOSGITest { + + private Map<String,Hashtable<String, Object>> properties = new ConcurrentHashMap<>(); + + @Mock + protected BundleContext bundleContext; + + @Mock + protected ConfigurationAdmin cm; + + @Mock + private ServiceReference<ConfigurationAdmin> cmRef; + + @Mock + private ServiceReference<TamayaConfigService> tamayaRef; + + @Mock + protected TamayaConfigService tamayaConfigService; + + protected Dictionary<String,Object> getProperties(String pid){ + return this.properties.get(pid); + } + + @Before + public void setup()throws Exception{ + doAnswer(invocation -> { + return initConfigurationMock((String)invocation.getArguments()[0]); + }).when(cm).getConfiguration(any()); + doAnswer(invocation -> { + return initConfigurationMock((String)invocation.getArguments()[0]); + }).when(cm).getConfiguration(any(), any()); + doReturn(new Bundle[0]).when(bundleContext).getBundles(); + doReturn(cmRef).when(bundleContext).getServiceReference(ConfigurationAdmin.class); + doReturn(cm).when(bundleContext).getService(cmRef); + doReturn(tamayaConfigService).when(bundleContext).getService(tamayaRef); + doReturn(tamayaRef).when(bundleContext).getServiceReference(TamayaConfigService.class); + } + + protected Configuration initConfigurationMock(final String pid)throws Exception{ + Configuration config = mock(Configuration.class); + doAnswer(invocation -> { + Hashtable<String,Object> props = properties.get(pid); + props.clear(); + props.putAll((Map<? extends String, ?>) invocation.getArguments()[0]); + return null; + }).when(config).update(any(Dictionary.class)); + doAnswer(invocation -> { + Hashtable<String,Object> props = properties.get(pid); + if(props==null){ + props = new Hashtable<>(); + properties.put(pid, props); + for(Map.Entry en:System.getProperties().entrySet()){ + props.put(en.getKey().toString(), en.getValue()); + } + } + return new Hashtable<>(props); + }).when(config).getProperties(); + return config; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/1e8ac056/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/ActivatorTest.java ---------------------------------------------------------------------- diff --git a/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/ActivatorTest.java b/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/ActivatorTest.java new file mode 100644 index 0000000..5e1f614 --- /dev/null +++ b/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/ActivatorTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.osgi.updater; + +import org.apache.tamaya.events.ConfigEventManager; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; + +import static junit.framework.TestCase.assertEquals; + +/** + * Created by atsti on 30.09.2017. + */ +@RunWith(MockitoJUnitRunner.class) +public class ActivatorTest extends AbstractOSGITest{ + + @Test + public void startStop() throws Exception { + int size = ConfigEventManager.getListeners().size(); + Activator activator = new Activator(); + activator.start(super.bundleContext); + assertEquals(ConfigEventManager.getListeners().size(), size+1); + activator.stop(super.bundleContext); + assertEquals(ConfigEventManager.getListeners().size(), size); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/1e8ac056/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/EventListenerTest.java ---------------------------------------------------------------------- diff --git a/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/EventListenerTest.java b/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/EventListenerTest.java new file mode 100644 index 0000000..6ffd618 --- /dev/null +++ b/modules/osgi/updater/src/test/java/org/apache/tamaya/osgi/updater/EventListenerTest.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.osgi.updater; + +import org.apache.tamaya.events.ConfigEvent; +import org.apache.tamaya.events.ConfigurationChangeBuilder; +import org.apache.tamaya.osgi.commands.TamayaConfigService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +/** + * Created by atsti on 30.09.2017. + */ +@RunWith(MockitoJUnitRunner.class) +public class EventListenerTest extends AbstractOSGITest{ + + private EventListener eventListener; + + @Before + public void setupEL() throws Exception { + eventListener = new EventListener(bundleContext); + } + + @Test + public void testEventWithNoDataDoesNotTriggerTamayaServices() throws Exception { + ConfigEvent evt = ConfigurationChangeBuilder.of().addChange("a", "b").build(); + eventListener.onConfigEvent(evt); + verify(bundleContext, never()).getServiceReference(TamayaConfigService.class); + } + + @Test + public void testEventForPIDDoesTriggerTamayaServices() throws Exception { + ConfigEvent evt = ConfigurationChangeBuilder.of().addChange("[PID.foo]a", "b").build(); + eventListener.onConfigEvent(evt); + verify(bundleContext).getServiceReference(TamayaConfigService.class); + verify(tamayaConfigService).updateConfig("PID.foo"); + } + +} \ No newline at end of file
