You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by cs...@apache.org on 2018/05/28 14:29:01 UTC
svn commit: r1832399 - in /aries/trunk/component-dsl:
component-dsl/src/main/java/org/apache/aries/component/dsl/internal/
itests/src/main/java/org/apache/aries/component/dsl/test/
Author: csierra
Date: Mon May 28 14:29:00 2018
New Revision: 1832399
URL: http://svn.apache.org/viewvc?rev=1832399&view=rev
Log:
[Component-DSL] Get initial configuration state
so configuration is not always set to empty and then initialized
asynchronously to the existing value
Modified:
aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationOSGiImpl.java
aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationsOSGiImpl.java
aries/trunk/component-dsl/itests/src/main/java/org/apache/aries/component/dsl/test/DSLTest.java
Modified: aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationOSGiImpl.java?rev=1832399&r1=1832398&r2=1832399&view=diff
==============================================================================
--- aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationOSGiImpl.java (original)
+++ aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationOSGiImpl.java Mon May 28 14:29:00 2018
@@ -17,11 +17,18 @@
package org.apache.aries.component.dsl.internal;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
import java.util.Dictionary;
import java.util.Hashtable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@@ -32,7 +39,7 @@ public class ConfigurationOSGiImpl exten
public ConfigurationOSGiImpl(String pid) {
super((bundleContext, op) -> {
- AtomicReference<Dictionary<String, ?>> atomicReference =
+ AtomicReference<Configuration> atomicReference =
new AtomicReference<>(null);
AtomicReference<Runnable>
@@ -40,17 +47,55 @@ public class ConfigurationOSGiImpl exten
AtomicBoolean closed = new AtomicBoolean();
- ServiceRegistration<ManagedService> serviceRegistration =
+ CountDownLatch countDownLatch = new CountDownLatch(1);
+
+ ServiceRegistration<?> serviceRegistration =
bundleContext.registerService(
- ManagedService.class,
- properties -> {
- atomicReference.set(properties);
+ ConfigurationListener.class,
+ (ConfigurationEvent configurationEvent) -> {
+ if (configurationEvent.getFactoryPid() != null ||
+ !configurationEvent.getPid().equals(pid)) {
+
+ return;
+ }
+
+ try {
+ countDownLatch.await(1, TimeUnit.MINUTES);
+ }
+ catch (InterruptedException e) {
+ return;
+ }
+
+ Configuration configuration;
+
+ if (configurationEvent.getType() ==
+ ConfigurationEvent.CM_DELETED) {
- signalLeave(terminatorAtomicReference);
+ atomicReference.set(null);
- if (properties != null) {
+ signalLeave(terminatorAtomicReference);
+ }
+ else {
+ configuration = getConfiguration(
+ bundleContext, configurationEvent);
+
+ if (configuration == null) {
+ return;
+ }
+
+ Configuration old = atomicReference.get();
+
+ if (old == null ||
+ configuration.getChangeCount() !=
+ old.getChangeCount()) {
+
+ atomicReference.set(configuration);
+ }
+
+ signalLeave(terminatorAtomicReference);
+
terminatorAtomicReference.set(
- op.apply(properties));
+ op.apply(configuration.getProperties()));
if (closed.get()) {
/*
@@ -59,14 +104,27 @@ public class ConfigurationOSGiImpl exten
directly instead of storing it
*/
signalLeave(terminatorAtomicReference);
-
- return;
}
}
},
- new Hashtable<String, Object>() {{
- put("service.pid", pid);
- }});
+ new Hashtable<>());
+
+ ServiceReference<ConfigurationAdmin> serviceReference =
+ bundleContext.getServiceReference(ConfigurationAdmin.class);
+
+ if (serviceReference != null) {
+ Configuration configuration = getConfiguration(
+ bundleContext, pid, serviceReference);
+
+ if (configuration != null) {
+ atomicReference.set(configuration);
+
+ terminatorAtomicReference.set(
+ op.apply(configuration.getProperties()));
+ }
+ }
+
+ countDownLatch.countDown();
return new OSGiResultImpl(
() -> {
@@ -79,6 +137,43 @@ public class ConfigurationOSGiImpl exten
});
}
+ private static Configuration getConfiguration(
+ BundleContext bundleContext, ConfigurationEvent configurationEvent) {
+
+ String pid = configurationEvent.getPid();
+
+ ServiceReference<ConfigurationAdmin> reference =
+ configurationEvent.getReference();
+
+ return getConfiguration(bundleContext, pid, reference);
+ }
+
+ private static Configuration getConfiguration(
+ BundleContext bundleContext, String pid,
+ ServiceReference<ConfigurationAdmin> reference) {
+
+ ConfigurationAdmin configurationAdmin = bundleContext.getService(
+ reference);
+
+ try {
+ Configuration[] configurations =
+ configurationAdmin.listConfigurations(
+ "(&(service.pid=" + pid + ")(!(service.factoryPid=*)))");
+
+ if (configurations.length == 0) {
+ return null;
+ }
+
+ return configurations[0];
+ }
+ catch (Exception e) {
+ return null;
+ }
+ finally {
+ bundleContext.ungetService(reference);
+ }
+ }
+
private static void signalLeave(
AtomicReference<Runnable> terminatorAtomicReference) {
Modified: aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationsOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationsOSGiImpl.java?rev=1832399&r1=1832398&r2=1832399&view=diff
==============================================================================
--- aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationsOSGiImpl.java (original)
+++ aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationsOSGiImpl.java Mon May 28 14:29:00 2018
@@ -17,37 +17,123 @@
package org.apache.aries.component.dsl.internal;
-import org.apache.aries.component.dsl.Publisher;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
/**
* @author Carlos Sierra Andrés
*/
-public class ConfigurationsOSGiImpl
- extends OSGiImpl<Dictionary<String, ?>> {
+public class ConfigurationsOSGiImpl extends OSGiImpl<Dictionary<String, ?>> {
public ConfigurationsOSGiImpl(String factoryPid) {
super((bundleContext, op) -> {
- Map<String, Runnable> results = new ConcurrentHashMap<>();
+ ConcurrentHashMap<String, Configuration> configurations =
+ new ConcurrentHashMap<>();
+
+ ConcurrentHashMap<String, Runnable> terminators =
+ new ConcurrentHashMap<>();
AtomicBoolean closed = new AtomicBoolean();
- ServiceRegistration<ManagedServiceFactory> serviceRegistration =
+ CountDownLatch countDownLatch = new CountDownLatch(1);
+
+ ServiceRegistration<?> serviceRegistration =
bundleContext.registerService(
- ManagedServiceFactory.class,
- new ConfigurationsManagedServiceFactory(
- results, op, closed),
- new Hashtable<String, Object>() {{
- put("service.pid", factoryPid);
- }});
+ ConfigurationListener.class,
+ (ConfigurationEvent configurationEvent) -> {
+ String incomingFactoryPid =
+ configurationEvent.getFactoryPid();
+
+ if (incomingFactoryPid == null ||
+ !factoryPid.equals(incomingFactoryPid)) {
+
+ return;
+ }
+
+ try {
+ countDownLatch.await(1, TimeUnit.MINUTES);
+ }
+ catch (InterruptedException e) {
+ return;
+ }
+
+ String pid = configurationEvent.getPid();
+
+ Configuration configuration;
+
+ if (configurationEvent.getType() ==
+ ConfigurationEvent.CM_DELETED) {
+
+ configurations.remove(pid);
+
+ signalLeave(pid, terminators);
+ }
+ else {
+ configuration = getConfiguration(
+ bundleContext, configurationEvent);
+
+ Dictionary<String, Object> properties =
+ configuration.getProperties();
+
+ configurations.compute(
+ pid,
+ (__, old) -> {
+ if (old == null ||
+ configuration.getChangeCount() !=
+ old.getChangeCount()) {
+
+ return configuration;
+ }
+
+ return old;
+ }
+ );
+
+ signalLeave(pid, terminators);
+
+ terminators.put(pid, op.apply(properties));
+
+ if (closed.get()) {
+ /*
+ if we have closed while executing the
+ effects we have to execute the terminator
+ directly instead of storing it
+ */
+ signalLeave(pid, terminators);
+ }
+ }
+ },
+ new Hashtable<>());
+
+ ServiceReference<ConfigurationAdmin> serviceReference =
+ bundleContext.getServiceReference(ConfigurationAdmin.class);
+
+ if (serviceReference != null) {
+ Configuration[] configuration = getConfigurations(
+ bundleContext, factoryPid, serviceReference);
+
+ for (Configuration c : configuration) {
+ configurations.put(c.getPid(), c);
+
+ terminators.put(c.getPid(), op.apply(c.getProperties()));
+ }
+ }
+
+ countDownLatch.countDown();
return new OSGiResultImpl(
() -> {
@@ -55,68 +141,88 @@ public class ConfigurationsOSGiImpl
serviceRegistration.unregister();
- results.values().forEach(Runnable::run);
-
- results.clear();
+ for (Runnable runnable : terminators.values()) {
+ if (runnable != null) {
+ runnable.run();
+ }
+ }
});
});
}
- private static class ConfigurationsManagedServiceFactory
- implements ManagedServiceFactory {
+ private static Configuration getConfiguration(
+ BundleContext bundleContext, ConfigurationEvent configurationEvent) {
- private final Map<String, Runnable> _results;
+ String pid = configurationEvent.getPid();
+ String factoryPid = configurationEvent.getFactoryPid();
- private final Publisher<? super Dictionary<String, ?>> _op;
- private AtomicBoolean _closed;
+ ServiceReference<ConfigurationAdmin> reference =
+ configurationEvent.getReference();
- public ConfigurationsManagedServiceFactory(
- Map<String, Runnable> results,
- Publisher<? super Dictionary<String, ?>> op,
- AtomicBoolean closed) {
+ return getConfiguration(bundleContext, pid, factoryPid, reference);
+ }
- _results = results;
- _op = op;
- _closed = closed;
- }
+ private static Configuration getConfiguration(
+ BundleContext bundleContext, String pid, String factoryPid,
+ ServiceReference<ConfigurationAdmin> reference) {
+
+ ConfigurationAdmin configurationAdmin = bundleContext.getService(
+ reference);
+
+ try {
+ Configuration[] configurations =
+ configurationAdmin.listConfigurations(
+ "(&(service.pid=" + pid + ")" +
+ "(service.factoryPid="+ factoryPid + "))");
- @Override
- public void deleted(String s) {
- Runnable runnable = _results.remove(s);
+ if (configurations == null || configurations.length == 0) {
+ return null;
+ }
- runnable.run();
+ return configurations[0];
}
-
- @Override
- public String getName() {
- return "Functional OSGi Managed Service Factory";
+ catch (Exception e) {
+ return null;
+ }
+ finally {
+ bundleContext.ungetService(reference);
}
+ }
- @Override
- public void updated(String s, Dictionary<String, ?> dictionary)
- throws ConfigurationException {
+ private static Configuration[] getConfigurations(
+ BundleContext bundleContext, String factoryPid,
+ ServiceReference<ConfigurationAdmin> serviceReference) {
+
+ ConfigurationAdmin configurationAdmin = bundleContext.getService(
+ serviceReference);
+
+ try {
+ Configuration[] configurations =
+ configurationAdmin.listConfigurations(
+ "(&(service.pid=*)(service.factoryPid="+ factoryPid +"))");
- Runnable terminator = _op.apply(dictionary);
+ if (configurations == null) {
+ return new Configuration[0];
+ }
- Runnable old = _results.put(s, terminator);
+ return configurations;
+ }
+ catch (Exception e) {
+ return new Configuration[0];
+ }
+ finally {
+ bundleContext.ungetService(serviceReference);
+ }
+ }
- if (old != null) {
- old.run();
- }
+ private static void signalLeave(
+ String factoryPid, ConcurrentHashMap<String, Runnable> terminators) {
- if (_closed.get()) {
- /* if we have been closed while executing the effects we have
- to check if this terminator has been left unexecuted.
- */
- _results.computeIfPresent(
- s,
- (key, runnable) -> {
- runnable.run();
+ Runnable runnable = terminators.remove(factoryPid);
- return null;
- });
- }
+ if (runnable != null) {
+ runnable.run();
}
-
}
+
}
Modified: aries/trunk/component-dsl/itests/src/main/java/org/apache/aries/component/dsl/test/DSLTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/itests/src/main/java/org/apache/aries/component/dsl/test/DSLTest.java?rev=1832399&r1=1832398&r2=1832399&view=diff
==============================================================================
--- aries/trunk/component-dsl/itests/src/main/java/org/apache/aries/component/dsl/test/DSLTest.java (original)
+++ aries/trunk/component-dsl/itests/src/main/java/org/apache/aries/component/dsl/test/DSLTest.java Mon May 28 14:29:00 2018
@@ -32,7 +32,9 @@ import org.osgi.framework.ServiceRegistr
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.util.tracker.ServiceTracker;
import java.io.IOException;
import java.util.ArrayList;
@@ -390,6 +392,65 @@ public class DSLTest {
}
@Test
+ public void testConfigurationWithExistingValues()
+ throws IOException, InterruptedException {
+
+ ServiceReference<ConfigurationAdmin> serviceReference =
+ bundleContext.getServiceReference(ConfigurationAdmin.class);
+
+ ConfigurationAdmin configurationAdmin = bundleContext.getService(
+ serviceReference);
+
+ Configuration configuration = configurationAdmin.getConfiguration(
+ "test.configuration");
+
+ configuration.update(new Hashtable<>());
+
+ AtomicReference<Dictionary<?,?>> atomicReference =
+ new AtomicReference<>(null);
+
+ AtomicInteger counter = new AtomicInteger();
+
+ CountDownLatch countDownLatch = new CountDownLatch(2);
+
+ ServiceRegistration<ManagedService> serviceRegistration =
+ bundleContext.registerService(
+ ManagedService.class, __ -> countDownLatch.countDown(),
+ new Hashtable<String, Object>() {{
+ put("service.pid", "test.configuration");
+ }});
+
+ try(OSGiResult result =
+ configuration("test.configuration").run(
+ bundleContext,
+ x -> {
+ atomicReference.set(x);
+
+ counter.incrementAndGet();
+
+ countDownLatch.countDown();
+
+ return NOOP;
+ }))
+ {
+ assertNotNull(atomicReference.get());
+
+ countDownLatch.await(10, TimeUnit.SECONDS);
+
+ assertEquals(1, counter.get());
+ }
+ finally {
+ bundleContext.ungetService(serviceReference);
+
+ configuration.delete();
+
+ if (serviceRegistration != null) {
+ serviceRegistration.unregister();
+ }
+ }
+ }
+
+ @Test
public void testConfigurations() throws IOException, InterruptedException {
ServiceReference<ConfigurationAdmin> serviceReference =
bundleContext.getServiceReference(ConfigurationAdmin.class);
@@ -470,58 +531,34 @@ public class DSLTest {
CountDownLatch addedLatch = new CountDownLatch(3);
- ServiceRegistration<?> addedServiceRegistration =
- bundleContext.registerService(
- ManagedServiceFactory.class,
- new ManagedServiceFactory() {
- @Override
- public String getName() {
- return "";
- }
-
- @Override
- public void updated(
- String s, Dictionary<String, ?> dictionary)
- throws ConfigurationException {
+ ServiceTracker serviceTracker = new ServiceTracker<Service, Service>(
+ bundleContext, Service.class, null) {
- addedLatch.countDown();
- }
+ @Override
+ public Service addingService(ServiceReference<Service> reference) {
+ addedLatch.countDown();
- @Override
- public void deleted(String s) {
+ return null;
+ }
+ };
- }
- },
- new Hashtable<String, Object>() {{
- put("service.pid", "test.configuration");
- }});
+ serviceTracker.open();
CountDownLatch deletedLatch = new CountDownLatch(3);
- ServiceRegistration<?> deletedServiceRegistration =
- bundleContext.registerService(
- ManagedServiceFactory.class,
- new ManagedServiceFactory() {
- @Override
- public String getName() {
- return "";
- }
-
- @Override
- public void updated(
- String s, Dictionary<String, ?> dictionary)
- throws ConfigurationException {
-
- }
-
- @Override
- public void deleted(String s) {
- deletedLatch.countDown();
- }
- },
- new Hashtable<String, Object>() {{
- put("service.pid", "test.configuration");
- }});
+ ServiceTracker serviceTracker2 = new ServiceTracker<Service, Service>(
+ bundleContext, Service.class, null) {
+
+ @Override
+ public void removedService(
+ ServiceReference<Service> reference,
+ Service service) {
+
+ deletedLatch.countDown();
+ }
+ };
+
+ serviceTracker2.open();
Configuration configuration =
configurationAdmin.createFactoryConfiguration("test.configuration");
@@ -572,9 +609,9 @@ public class DSLTest {
bundleContext.getServiceReferences(
Service.class, "(test.configuration=*)").size());
- addedServiceRegistration.unregister();
+ serviceTracker.close();
- deletedServiceRegistration.unregister();
+ serviceTracker2.close();
result.close();