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/02/05 09:45:03 UTC
[1/3] aries-rsa git commit: [ARIES-1771] Support service changes,
let TopologyManager handle the closing of ExportRegistrations
Repository: aries-rsa
Updated Branches:
refs/heads/master 094996dc0 -> 55e2c1cb4
[ARIES-1771] Support service changes, let TopologyManager handle the closing of ExportRegistrations
Project: http://git-wip-us.apache.org/repos/asf/aries-rsa/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-rsa/commit/1ad152b4
Tree: http://git-wip-us.apache.org/repos/asf/aries-rsa/tree/1ad152b4
Diff: http://git-wip-us.apache.org/repos/asf/aries-rsa/diff/1ad152b4
Branch: refs/heads/master
Commit: 1ad152b46616f4394177588cf06a758913671a77
Parents: 094996d
Author: Christian Schneider <cs...@adobe.com>
Authored: Fri Feb 2 18:35:44 2018 +0100
Committer: Christian Schneider <cs...@adobe.com>
Committed: Fri Feb 2 18:35:44 2018 +0100
----------------------------------------------------------------------
.../rsa/itests/felix/rsa/TestRSAListener.java | 2 +
parent/pom.xml | 12 +-
.../aries/rsa/core/ExportRegistrationImpl.java | 30 +--
.../aries/rsa/core/RemoteServiceAdminCore.java | 20 --
.../core/DistributionProviderTrackerTest.java | 7 -
topology-manager/pom.xml | 6 -
.../aries/rsa/topologymanager/Activator.java | 76 +-------
.../EndpointEventListenerTracker.java | 39 ++++
.../EndpointListenerTracker.java | 43 +++++
.../exporter/EndpointListenerNotifier.java | 27 +--
.../exporter/EndpointRepository.java | 147 ---------------
.../exporter/ServiceExportsRepository.java | 122 ++++++++++++
.../exporter/TopologyManagerExport.java | 189 +++++++++++--------
.../exporter/EndpointListenerNotifierTest.java | 29 +--
.../exporter/EndpointRepositoryTest.java | 74 --------
.../exporter/TopologyManagerExportTest.java | 93 +++++----
16 files changed, 426 insertions(+), 490 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/rsa/TestRSAListener.java
----------------------------------------------------------------------
diff --git a/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/rsa/TestRSAListener.java b/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/rsa/TestRSAListener.java
index 8a0c9f9..0371787 100644
--- a/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/rsa/TestRSAListener.java
+++ b/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/rsa/TestRSAListener.java
@@ -71,6 +71,8 @@ public class TestRSAListener extends RsaTestBase implements RemoteServiceAdminLi
serviceBundle.start();
assertEvent(RemoteServiceAdminEvent.EXPORT_REGISTRATION);
+ Thread.sleep(1000);
+
serviceBundle.stop();
assertEvent(RemoteServiceAdminEvent.EXPORT_UNREGISTRATION);
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 43a4c07..09e9cc7 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -80,6 +80,11 @@
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
</dependency>
+ <dependency>
+ <groupId>com.shazam</groupId>
+ <artifactId>shazamcrest</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<dependencyManagement>
@@ -124,7 +129,12 @@
<artifactId>hawtbuf-proto</artifactId>
<version>${hawtbuf.version}</version>
</dependency>
-
+ <dependency>
+ <groupId>com.shazam</groupId>
+ <artifactId>shazamcrest</artifactId>
+ <version>0.11</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java b/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
index bb8ee04..81bb859 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
@@ -21,7 +21,6 @@ package org.apache.aries.rsa.core;
import java.io.Closeable;
import java.io.IOException;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -40,7 +39,7 @@ public class ExportRegistrationImpl implements ExportRegistration {
private static final Logger LOG = LoggerFactory.getLogger(ExportRegistrationImpl.class);
private final CloseHandler closeHandler;
- private final ExportReferenceImpl exportReference;
+ private ExportReferenceImpl exportReference;
private final Closeable server;
private final Throwable exception;
@@ -138,14 +137,17 @@ public class ExportRegistrationImpl implements ExportRegistration {
instanceCount--;
if (instanceCount <= 0) {
LOG.debug("really closing ExportRegistration now!");
+ closeServer();
+ }
+ }
+ }
- if (server != null) {
- try {
- server.close();
- } catch (IOException e) {
- LOG.warn("Error closing ExportRegistration", e);
- }
- }
+ private void closeServer() {
+ if (server != null) {
+ try {
+ server.close();
+ } catch (IOException e) {
+ LOG.warn("Error closing ExportRegistration", e);
}
}
}
@@ -175,11 +177,13 @@ public class ExportRegistrationImpl implements ExportRegistration {
@Override
public EndpointDescription update(Map<String, ?> properties) {
- Map<String, Object> newProps = new HashMap<String, Object>(getExportReference().getExportedEndpoint().getProperties());
- for (String key : properties.keySet()) {
- newProps.put(key, properties.get(key));
+ if (getExportReference() == null) {
+ return null;
}
+ ServiceReference<?> sref = getExportReference().getExportedService();
+ EndpointDescription epd = new EndpointDescription(sref, properties);
+ exportReference = new ExportReferenceImpl(sref, epd);
this.sender.notifyUpdate(this.getExportReference());
- return new EndpointDescription(newProps);
+ return epd;
}
}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
index e2a574b..98fca14 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
@@ -39,8 +39,6 @@ import org.apache.aries.rsa.util.EndpointHelper;
import org.apache.aries.rsa.util.StringPlus;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
@@ -93,24 +91,6 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin {
removeImportRegistration((ImportRegistrationImpl) importReg);
}
};
- // listen for exported services being unregistered so we can close the export
- createExportedServicesListener();
- }
-
- protected void createExportedServicesListener() {
- this.exportedServiceListener = new ServiceListener() {
- public void serviceChanged(ServiceEvent event) {
- if (event.getType() == ServiceEvent.UNREGISTERING) {
- removeServiceExports(event.getServiceReference());
- }
- }
- };
- try {
- String filter = "(" + RemoteConstants.SERVICE_EXPORTED_INTERFACES + "=*)";
- bctx.addServiceListener(exportedServiceListener, filter);
- } catch (InvalidSyntaxException ise) {
- throw new RuntimeException(ise); // can never happen
- }
}
@Override
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java
----------------------------------------------------------------------
diff --git a/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java b/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java
index ca71802..1468b8b 100644
--- a/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java
+++ b/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java
@@ -29,7 +29,6 @@ import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
@@ -59,9 +58,6 @@ public class DistributionProviderTrackerTest {
EasyMock.isA(Dictionary.class)))
.andReturn(rsaReg).atLeastOnce();
- context.addServiceListener(EasyMock.isA(ServiceListener.class), EasyMock.isA(String.class));
- EasyMock.expectLastCall();
-
final BundleContext apiContext = c.createMock(BundleContext.class);
c.replay();
DistributionProviderTracker tracker = new DistributionProviderTracker(context) {
@@ -100,9 +96,6 @@ public class DistributionProviderTrackerTest {
EasyMock.isA(Dictionary.class)))
.andReturn(rsaReg).atLeastOnce();
- context.addServiceListener(EasyMock.isA(ServiceListener.class), EasyMock.isA(String.class));
- EasyMock.expectLastCall();
-
final BundleContext apiContext = c.createMock(BundleContext.class);
c.replay();
DistributionProviderTracker tracker = new DistributionProviderTracker(context) {
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/pom.xml
----------------------------------------------------------------------
diff --git a/topology-manager/pom.xml b/topology-manager/pom.xml
index cc63441..43a0582 100644
--- a/topology-manager/pom.xml
+++ b/topology-manager/pom.xml
@@ -42,12 +42,6 @@
<artifactId>org.apache.aries.rsa.spi</artifactId>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-all</artifactId>
- <version>1.3</version>
- <scope>test</scope>
- </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java
index 70d1111..5efc1c5 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java
@@ -26,9 +26,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.aries.rsa.spi.ExportPolicy;
import org.apache.aries.rsa.topologymanager.exporter.DefaultExportPolicy;
-import org.apache.aries.rsa.topologymanager.exporter.EndpointListenerAdapter;
import org.apache.aries.rsa.topologymanager.exporter.EndpointListenerNotifier;
-import org.apache.aries.rsa.topologymanager.exporter.EndpointRepository;
import org.apache.aries.rsa.topologymanager.exporter.TopologyManagerExport;
import org.apache.aries.rsa.topologymanager.importer.TopologyManagerImport;
import org.apache.aries.rsa.topologymanager.importer.local.EndpointListenerManager;
@@ -39,8 +37,6 @@ import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointEventListener;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
import org.osgi.util.tracker.ServiceTracker;
@@ -48,7 +44,6 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-@SuppressWarnings("deprecation")
public class Activator implements BundleActivator {
public static final String RSA_EXPORT_POLICY_FILTER = "rsa.export.policy.filter";
static final String DOSGI_SERVICES = "(" + RemoteConstants.SERVICE_EXPORTED_INTERFACES + "=*)";
@@ -56,13 +51,13 @@ public class Activator implements BundleActivator {
private TopologyManagerExport exportManager;
private TopologyManagerImport importManager;
- private EndpointListenerNotifier notifier;
+ EndpointListenerNotifier notifier;
private ServiceTracker<RemoteServiceAdmin, RemoteServiceAdmin> rsaTracker;
private ThreadPoolExecutor exportExecutor;
- private ServiceTracker<EndpointListener, EndpointListener> epListenerTracker;
private ServiceTracker<ExportPolicy, ExportPolicy> policyTracker;
private EndpointListenerManager endpointListenerManager;
+ private EndpointListenerTracker epListenerTracker;
private EndpointEventListenerTracker epeListenerTracker;
public void start(final BundleContext bc) throws Exception {
@@ -103,13 +98,11 @@ public class Activator implements BundleActivator {
public void doStart(final BundleContext bc, ExportPolicy policy) {
LOG.debug("TopologyManager: start()");
- EndpointRepository endpointRepo = new EndpointRepository();
- notifier = new EndpointListenerNotifier(endpointRepo);
- epListenerTracker = new EndpointListenerTracker(bc);
- epeListenerTracker = new EndpointEventListenerTracker(bc);
- endpointRepo.setNotifier(notifier);
+ notifier = new EndpointListenerNotifier();
exportExecutor = new ThreadPoolExecutor(5, 10, 50, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
- exportManager = new TopologyManagerExport(endpointRepo, exportExecutor, policy);
+ exportManager = new TopologyManagerExport(notifier, exportExecutor, policy);
+ epListenerTracker = new EndpointListenerTracker(bc, exportManager);
+ epeListenerTracker = new EndpointEventListenerTracker(bc, exportManager);
importManager = new TopologyManagerImport(bc);
endpointListenerManager = new EndpointListenerManager(bc, importManager);
endpointListenerManager.start();
@@ -151,63 +144,6 @@ public class Activator implements BundleActivator {
}
}
- private final class EndpointListenerTracker extends ServiceTracker<EndpointListener, EndpointListener> {
- private EndpointListenerTracker(BundleContext context) {
- super(context, EndpointListener.class, null);
- }
-
- @Override
- public EndpointListener addingService(ServiceReference<EndpointListener> reference) {
- EndpointListener listener = super.addingService(reference);
- EndpointListenerAdapter adapter = new EndpointListenerAdapter(listener);
- notifier.add(adapter, EndpointListenerNotifier.filtersFromEL(reference));
- return listener;
- }
-
- @Override
- public void modifiedService(ServiceReference<EndpointListener> reference,
- EndpointListener listener) {
- super.modifiedService(reference, listener);
- EndpointListenerAdapter adapter = new EndpointListenerAdapter(listener);
- notifier.add(adapter, EndpointListenerNotifier.filtersFromEL(reference));
- }
-
- @Override
- public void removedService(ServiceReference<EndpointListener> reference,
- EndpointListener listener) {
- EndpointListenerAdapter adapter = new EndpointListenerAdapter(listener);
- notifier.remove(adapter);
- super.removedService(reference, listener);
- }
- }
-
- private final class EndpointEventListenerTracker extends ServiceTracker<EndpointEventListener, EndpointEventListener> {
- private EndpointEventListenerTracker(BundleContext context) {
- super(context, EndpointEventListener.class, null);
- }
-
- @Override
- public EndpointEventListener addingService(ServiceReference<EndpointEventListener> reference) {
- EndpointEventListener listener = super.addingService(reference);
- notifier.add(listener, EndpointListenerNotifier.filtersFromEEL(reference));
- return listener;
- }
-
- @Override
- public void modifiedService(ServiceReference<EndpointEventListener> reference,
- EndpointEventListener listener) {
- notifier.add(listener, EndpointListenerNotifier.filtersFromEEL(reference));
- super.modifiedService(reference, listener);
- }
-
- @Override
- public void removedService(ServiceReference<EndpointEventListener> reference,
- EndpointEventListener listener) {
- notifier.remove(listener);
- super.removedService(reference, listener);
- }
- }
-
private final class RSATracker extends ServiceTracker<RemoteServiceAdmin, RemoteServiceAdmin> {
private RSATracker(BundleContext context, Class<RemoteServiceAdmin> clazz,
ServiceTrackerCustomizer<RemoteServiceAdmin, RemoteServiceAdmin> customizer) {
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/EndpointEventListenerTracker.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/EndpointEventListenerTracker.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/EndpointEventListenerTracker.java
new file mode 100644
index 0000000..1f8ba43
--- /dev/null
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/EndpointEventListenerTracker.java
@@ -0,0 +1,39 @@
+package org.apache.aries.rsa.topologymanager;
+
+import org.apache.aries.rsa.topologymanager.exporter.EndpointListenerNotifier;
+import org.apache.aries.rsa.topologymanager.exporter.TopologyManagerExport;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
+import org.osgi.util.tracker.ServiceTracker;
+
+final class EndpointEventListenerTracker extends ServiceTracker<EndpointEventListener, EndpointEventListener> {
+ private TopologyManagerExport tmExport;
+
+ EndpointEventListenerTracker(BundleContext context, TopologyManagerExport tmExport) {
+ super(context, EndpointEventListener.class, null);
+ this.tmExport = tmExport;
+ }
+
+ @Override
+ public EndpointEventListener addingService(ServiceReference<EndpointEventListener> reference) {
+ EndpointEventListener listener = super.addingService(reference);
+ this.tmExport.addEPListener(listener, EndpointListenerNotifier.filtersFromEEL(reference));
+ return listener;
+ }
+
+ @Override
+ public void modifiedService(ServiceReference<EndpointEventListener> reference,
+ EndpointEventListener listener) {
+ this.tmExport.addEPListener(listener, EndpointListenerNotifier.filtersFromEEL(reference));
+ super.modifiedService(reference, listener);
+ }
+
+ @Override
+ public void removedService(ServiceReference<EndpointEventListener> reference,
+ EndpointEventListener listener) {
+ this.tmExport.removeEPListener(listener);
+ super.removedService(reference, listener);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/EndpointListenerTracker.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/EndpointListenerTracker.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/EndpointListenerTracker.java
new file mode 100644
index 0000000..87ab0ae
--- /dev/null
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/EndpointListenerTracker.java
@@ -0,0 +1,43 @@
+package org.apache.aries.rsa.topologymanager;
+
+import org.apache.aries.rsa.topologymanager.exporter.EndpointListenerAdapter;
+import org.apache.aries.rsa.topologymanager.exporter.EndpointListenerNotifier;
+import org.apache.aries.rsa.topologymanager.exporter.TopologyManagerExport;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.util.tracker.ServiceTracker;
+
+@SuppressWarnings("deprecation")
+final class EndpointListenerTracker extends ServiceTracker<EndpointListener, EndpointListener> {
+ private TopologyManagerExport tmExport;
+
+ EndpointListenerTracker(BundleContext context, TopologyManagerExport tmExport) {
+ super(context, EndpointListener.class, null);
+ this.tmExport = tmExport;
+ }
+
+ @Override
+ public EndpointListener addingService(ServiceReference<EndpointListener> reference) {
+ EndpointListener listener = super.addingService(reference);
+ EndpointListenerAdapter adapter = new EndpointListenerAdapter(listener);
+ tmExport.addEPListener(adapter, EndpointListenerNotifier.filtersFromEL(reference));
+ return listener;
+ }
+
+ @Override
+ public void modifiedService(ServiceReference<EndpointListener> reference,
+ EndpointListener listener) {
+ super.modifiedService(reference, listener);
+ EndpointListenerAdapter adapter = new EndpointListenerAdapter(listener);
+ tmExport.addEPListener(adapter, EndpointListenerNotifier.filtersFromEL(reference));
+ }
+
+ @Override
+ public void removedService(ServiceReference<EndpointListener> reference,
+ EndpointListener listener) {
+ EndpointListenerAdapter adapter = new EndpointListenerAdapter(listener);
+ tmExport.removeEPListener(adapter);
+ super.removedService(reference, listener);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java
index 827fe6a..b816306 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java
@@ -18,6 +18,7 @@
*/
package org.apache.aries.rsa.topologymanager.exporter;
+import java.util.Collection;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
@@ -42,13 +43,11 @@ import org.slf4j.LoggerFactory;
* Tracks EndpointListeners and allows to notify them of endpoints.
*/
@SuppressWarnings("deprecation")
-public class EndpointListenerNotifier implements EndpointEventListener {
+public class EndpointListenerNotifier {
private static final Logger LOG = LoggerFactory.getLogger(EndpointListenerNotifier.class);
private Map<EndpointEventListener, Set<Filter>> listeners;
- private EndpointRepository endpointRepo;
- public EndpointListenerNotifier(final EndpointRepository endpointRepo) {
- this.endpointRepo = endpointRepo;
+ public EndpointListenerNotifier() {
this.listeners = new ConcurrentHashMap<EndpointEventListener, Set<Filter>>();
}
@@ -73,32 +72,22 @@ public class EndpointListenerNotifier implements EndpointEventListener {
}
return filters;
}
-
- public void removre(EndpointListener ep) {
- LOG.debug("EndpointListener modified");
- EndpointListenerAdapter adapter = new EndpointListenerAdapter(ep);
- listeners.remove(adapter);
- }
- public void add(EndpointEventListener ep, Set<Filter> filters) {
- LOG.debug("new EndpointListener detected");
+ public void add(EndpointEventListener ep, Set<Filter> filters, Collection<EndpointDescription> endpoints) {
+ LOG.debug("EndpointListener added");
listeners.put(ep, filters);
- for (EndpointDescription endpoint : endpointRepo.getAllEndpoints()) {
+ for (EndpointDescription endpoint : endpoints) {
EndpointEvent event = new EndpointEvent(EndpointEvent.ADDED, endpoint);
notifyListener(event, ep, filters);
}
}
public void remove(EndpointEventListener ep) {
- LOG.debug("EndpointListener modified");
+ LOG.debug("EndpointListener removed");
listeners.remove(ep);
}
- /**
- * NOTICE: filter will be ignored
- */
- @Override
- public void endpointChanged(EndpointEvent event, String filter) {
+ public void sendEvent(EndpointEvent event) {
for (EndpointEventListener listener : listeners.keySet()) {
Set<Filter> filters = listeners.get(listener);
notifyListener(event, listener, filters);
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepository.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepository.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepository.java
deleted file mode 100644
index b02cbba..0000000
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepository.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * 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.aries.rsa.topologymanager.exporter;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.EndpointEvent;
-import org.osgi.service.remoteserviceadmin.EndpointEventListener;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Holds all endpoints that are exported by a TopologyManager. For each ServiceReference that is exported a
- * map is maintained which contains information on the endpoints for each RemoteAdminService that created the
- * endpoints.
- */
-@SuppressWarnings("rawtypes")
-public class EndpointRepository {
-
- private static final Logger LOG = LoggerFactory.getLogger(EndpointRepository.class);
-
- private final Map<ServiceReference, Map<RemoteServiceAdmin, Collection<EndpointDescription>>> exportedServices
- = new LinkedHashMap<ServiceReference, Map<RemoteServiceAdmin, Collection<EndpointDescription>>>();
-
- private EndpointEventListener notifier;
-
- public void setNotifier(EndpointEventListener notifier) {
- this.notifier = notifier;
- }
-
-
- /**
- * Remove all services exported by the given rsa.
- *
- * @param rsa the RemoteServiceAdmin to remove
- * @return list of removed endpoints
- */
- public synchronized List<EndpointDescription> removeRemoteServiceAdmin(RemoteServiceAdmin rsa) {
- LOG.debug("RemoteServiceAdmin removed: {}", rsa.getClass().getName());
- List<EndpointDescription> removedEndpoints = new ArrayList<EndpointDescription>();
- for (Map<RemoteServiceAdmin, Collection<EndpointDescription>> exports : exportedServices.values()) {
- Collection<EndpointDescription> endpoints = exports.get(rsa);
- if (endpoints != null) {
- removedEndpoints.addAll(endpoints);
- exports.remove(rsa);
- }
- }
- endpointsRemoved(removedEndpoints);
- return removedEndpoints;
- }
-
- public synchronized void removeService(ServiceReference sref) {
- List<EndpointDescription> removedEndpoints = new ArrayList<EndpointDescription>();
- Map<RemoteServiceAdmin, Collection<EndpointDescription>> rsaToEndpoints = exportedServices.get(sref);
- if (rsaToEndpoints != null) {
- for (Collection<EndpointDescription> endpoints : rsaToEndpoints.values()) {
- removedEndpoints.addAll(endpoints);
- }
- exportedServices.remove(sref);
- }
- endpointsRemoved(removedEndpoints);
- }
-
- public synchronized void addService(ServiceReference sref) {
- if (!exportedServices.containsKey(sref)) {
- Bundle bundle = sref.getBundle();
- if (bundle != null) {
- LOG.info("Marking service from bundle {} for export", bundle.getSymbolicName());
- }
- exportedServices.put(sref, new LinkedHashMap<RemoteServiceAdmin, Collection<EndpointDescription>>());
- }
- }
-
- public synchronized void addEndpoints(ServiceReference sref, RemoteServiceAdmin rsa,
- List<EndpointDescription> endpoints) {
- addService(sref);
- Map<RemoteServiceAdmin, Collection<EndpointDescription>> exports = exportedServices.get(sref);
- exports.put(rsa, endpoints);
- endpointsAdded(endpoints);
- }
-
- synchronized boolean isAlreadyExportedForRsa(ServiceReference sref, RemoteServiceAdmin rsa) {
- Map<RemoteServiceAdmin, Collection<EndpointDescription>> exports = exportedServices.get(sref);
- return exports != null && exports.containsKey(rsa);
- }
-
- public synchronized Collection<EndpointDescription> getAllEndpoints() {
- List<EndpointDescription> allEndpoints = new ArrayList<EndpointDescription>();
- for (Map<RemoteServiceAdmin, Collection<EndpointDescription>> exports : exportedServices.values()) {
- for (Collection<EndpointDescription> endpoints : exports.values()) {
- allEndpoints.addAll(endpoints);
- }
- }
- return allEndpoints;
- }
-
- public synchronized Set<ServiceReference> getServicesToBeExportedFor(RemoteServiceAdmin rsa) {
- Set<ServiceReference> servicesToBeExported = new HashSet<ServiceReference>();
- for (Map.Entry<ServiceReference, Map<RemoteServiceAdmin, Collection<EndpointDescription>>> entry
- : exportedServices.entrySet()) {
- if (!entry.getValue().containsKey(rsa)) {
- servicesToBeExported.add(entry.getKey());
- }
- }
- return servicesToBeExported;
- }
-
- private void endpointsAdded(List<EndpointDescription> endpoints) {
- for (EndpointDescription epd : endpoints) {
- EndpointEvent event = new EndpointEvent(EndpointEvent.ADDED, epd);
- notifier.endpointChanged(event, null);
- }
- }
-
- private void endpointsRemoved(List<EndpointDescription> endpoints) {
- for (EndpointDescription epd : endpoints) {
- EndpointEvent event = new EndpointEvent(EndpointEvent.REMOVED, epd);
- notifier.endpointChanged(event, null);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/ServiceExportsRepository.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/ServiceExportsRepository.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/ServiceExportsRepository.java
new file mode 100644
index 0000000..99a2faf
--- /dev/null
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/ServiceExportsRepository.java
@@ -0,0 +1,122 @@
+/**
+ * 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.aries.rsa.topologymanager.exporter;
+
+import java.io.Closeable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.EndpointEvent;
+import org.osgi.service.remoteserviceadmin.ExportReference;
+import org.osgi.service.remoteserviceadmin.ExportRegistration;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Holds all Exports of a given RemoteServiceAdmin
+ */
+public class ServiceExportsRepository implements Closeable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ServiceExportsRepository.class);
+
+ private RemoteServiceAdmin rsa;
+ private EndpointListenerNotifier notifier;
+
+ private final Map<ServiceReference<?>, Collection<ExportRegistration>> exportsMap = new LinkedHashMap<>();
+
+
+ public ServiceExportsRepository(RemoteServiceAdmin rsa, EndpointListenerNotifier notifier) {
+ this.rsa = rsa;
+ this.notifier = notifier;
+ }
+
+ public void close() {
+ LOG.debug("Closing registry for RemoteServiceAdmin {}", rsa.getClass().getName());
+ for (ServiceReference<?> sref : exportsMap.keySet()) {
+ removeService(sref);
+ }
+ }
+
+ private void closeReg(ExportRegistration reg) {
+ ExportReference exportReference = reg.getExportReference();
+ if (exportReference != null) {
+ EndpointDescription endpoint = exportReference.getExportedEndpoint();
+ notifier.sendEvent(new EndpointEvent(EndpointEvent.REMOVED, endpoint));
+ reg.close();
+ }
+ }
+
+ public synchronized void addService(ServiceReference<?> sref, Collection<ExportRegistration> exports) {
+ exportsMap.put(sref, new ArrayList<ExportRegistration>(exports));
+ for (ExportRegistration reg : exports) {
+ ExportReference exportReference = reg.getExportReference();
+ if (exportReference != null) {
+ EndpointDescription endpoint = exportReference.getExportedEndpoint();
+ EndpointEvent event = new EndpointEvent(EndpointEvent.ADDED, endpoint);
+ notifier.sendEvent(event);
+ }
+ }
+ }
+
+
+ public synchronized void modifyService(ServiceReference<?> sref) {
+ Collection<ExportRegistration> exports = exportsMap.get(sref);
+ if (exports != null) {
+ for (ExportRegistration reg : exports) {
+ reg.update(null);
+ ExportReference exportReference = reg.getExportReference();
+ if (exportReference != null) {
+ EndpointDescription endpoint = exportReference.getExportedEndpoint();
+ EndpointEvent event = new EndpointEvent(EndpointEvent.MODIFIED, endpoint);
+ notifier.sendEvent(event);
+ }
+ }
+ }
+ }
+
+ public synchronized void removeService(ServiceReference<?> sref) {
+ Collection<ExportRegistration> exports = exportsMap.get(sref);
+ if (exports != null) {
+ for (ExportRegistration reg : exports) {
+ closeReg(reg);
+ }
+ exports.clear();
+ }
+ }
+
+ public List<EndpointDescription> getAllEndpoints() {
+ List<EndpointDescription> endpoints = new ArrayList<>();
+ for (ServiceReference<?> sref : exportsMap.keySet()) {
+ Collection<ExportRegistration> exports = exportsMap.get(sref);
+ for (ExportRegistration reg : exports) {
+ ExportReference exportRef = reg.getExportReference();
+ if (exportRef != null) {
+ endpoints.add(exportRef.getExportedEndpoint());
+ }
+ }
+ }
+ return endpoints;
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java
index e11801c..257c924 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java
@@ -20,6 +20,8 @@ package org.apache.aries.rsa.topologymanager.exporter;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -29,11 +31,12 @@ import java.util.concurrent.Executor;
import org.apache.aries.rsa.spi.ExportPolicy;
import org.apache.aries.rsa.util.StringPlus;
import org.osgi.framework.Bundle;
+import org.osgi.framework.Filter;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.ExportReference;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
import org.osgi.service.remoteserviceadmin.ExportRegistration;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
@@ -56,44 +59,90 @@ public class TopologyManagerExport implements ServiceListener {
private static final Logger LOG = LoggerFactory.getLogger(TopologyManagerExport.class);
private final Executor execService;
- private final EndpointRepository endpointRepo;
+ private final Map<RemoteServiceAdmin, ServiceExportsRepository> endpointRepo;
private ExportPolicy policy;
- private final Set<RemoteServiceAdmin> rsaSet;
-
-
- public TopologyManagerExport(final EndpointRepository endpointRepo, Executor executor, ExportPolicy policy) {
- this.endpointRepo = endpointRepo;
- this.policy = policy;
- this.rsaSet = new HashSet<RemoteServiceAdmin>();
+ private Map<Integer, String> typeNames;
+ private final EndpointListenerNotifier notifier;
+ private Set<ServiceReference<?>> toBeExported;
+
+ public TopologyManagerExport(
+ EndpointListenerNotifier notifier,
+ Executor executor,
+ ExportPolicy policy) {
+ this.notifier = notifier;
this.execService = executor;
+ this.policy = policy;
+ this.endpointRepo = new HashMap<>();
+ this.toBeExported = new HashSet<>();
+ createTypeNames();
+ }
+
+ private void createTypeNames() {
+ this.typeNames = new HashMap<>();
+ this.typeNames.put(ServiceEvent.MODIFIED, "modified");
+ this.typeNames.put(ServiceEvent.MODIFIED_ENDMATCH, "modified endmatch");
+ this.typeNames.put(ServiceEvent.REGISTERED, "registered");
+ this.typeNames.put(ServiceEvent.UNREGISTERING, "unregistering");
}
// track all service registrations so we can export any services that are configured to be exported
// ServiceListener events may be delivered out of order, concurrently, re-entrant, etc. (see spec or docs)
public void serviceChanged(ServiceEvent event) {
+ LOG.info("Received ServiceEvent type: {}, sref: {}", getTypeName(event), event.getServiceReference());
ServiceReference<?> sref = event.getServiceReference();
- if (event.getType() == ServiceEvent.REGISTERED) {
- LOG.debug("Received REGISTERED ServiceEvent: {}", event);
- export(sref);
- } else if (event.getType() == ServiceEvent.UNREGISTERING) {
- LOG.debug("Received UNREGISTERING ServiceEvent: {}", event);
- endpointRepo.removeService(sref);
+ switch (event.getType()) {
+ case ServiceEvent.REGISTERED:
+ exportInBackground(sref);
+ break;
+
+ case ServiceEvent.MODIFIED:
+ modified(sref);
+ break;
+
+ case ServiceEvent.MODIFIED_ENDMATCH:
+ remove(sref);
+ break;
+
+ case ServiceEvent.UNREGISTERING:
+ remove(sref);
+ break;
}
}
+ private void modified(ServiceReference<?> sref) {
+ for (RemoteServiceAdmin rsa : endpointRepo.keySet()) {
+ ServiceExportsRepository repo = endpointRepo.get(rsa);
+ repo.modifyService(sref);
+ }
+ }
+
+ private void remove(ServiceReference<?> sref) {
+ toBeExported.remove(sref);
+ for (RemoteServiceAdmin rsa : endpointRepo.keySet()) {
+ ServiceExportsRepository repo = endpointRepo.get(rsa);
+ repo.removeService(sref);
+ }
+ }
+
+ public String getTypeName(ServiceEvent event) {
+ return typeNames.get(event.getType());
+ }
+
public void add(RemoteServiceAdmin rsa) {
- rsaSet.add(rsa);
- for (ServiceReference<?> serviceRef : endpointRepo.getServicesToBeExportedFor(rsa)) {
- export(serviceRef);
+ endpointRepo.put(rsa, new ServiceExportsRepository(rsa, notifier));
+ for (ServiceReference<?> serviceRef : toBeExported) {
+ exportInBackground(serviceRef);
}
};
public void remove(RemoteServiceAdmin rsa) {
- rsaSet.remove(rsa);
- endpointRepo.removeRemoteServiceAdmin(rsa);
+ ServiceExportsRepository repo = endpointRepo.remove(rsa);
+ if (repo != null) {
+ repo.close();
+ }
};
- private void export(final ServiceReference<?> sref) {
+ private void exportInBackground(final ServiceReference<?> sref) {
execService.execute(new Runnable() {
public void run() {
doExport(sref);
@@ -108,92 +157,82 @@ public class TopologyManagerExport implements ServiceListener {
return;
}
LOG.debug("Exporting service {}", sref);
- endpointRepo.addService(sref); // mark for future export even if there are currently no RSAs
- if (rsaSet.size() == 0) {
- LOG.error("No RemoteServiceAdmin available! Unable to export service from bundle {}, interfaces: {}",
+ toBeExported.add(sref);
+ if (endpointRepo.size() == 0) {
+ LOG.error("Unable to export service from bundle {}, interfaces: {} as no RemoteServiceAdmin is available. Marked for later export.",
getSymbolicName(sref.getBundle()),
sref.getProperty(org.osgi.framework.Constants.OBJECTCLASS));
return;
}
- HashSet<RemoteServiceAdmin> rsaSetCopy = new HashSet<>(rsaSet);
- for (RemoteServiceAdmin remoteServiceAdmin : rsaSetCopy) {
- LOG.debug("TopologyManager: handling remoteServiceAdmin " + remoteServiceAdmin);
- if (endpointRepo.isAlreadyExportedForRsa(sref, remoteServiceAdmin)) {
- LOG.debug("already handled by this remoteServiceAdmin -> skipping");
- } else {
- exportServiceUsingRemoteServiceAdmin(sref, remoteServiceAdmin, addProps);
- }
+ for (RemoteServiceAdmin remoteServiceAdmin : endpointRepo.keySet()) {
+ ServiceExportsRepository repo = endpointRepo.get(remoteServiceAdmin);
+ Collection<ExportRegistration> regs = exportService(remoteServiceAdmin, sref, addProps);
+ repo.addService(sref, regs);
}
}
-
- private boolean shouldExport(ServiceReference<?> sref, Map<String, ?> addProps) {
- List<String> exported= StringPlus.normalize(sref.getProperty(RemoteConstants.SERVICE_EXPORTED_INTERFACES));
- List<String> addExported = StringPlus.normalize(addProps.get(RemoteConstants.SERVICE_EXPORTED_INTERFACES));
- return sizeOf(exported) + sizeOf(addExported) > 0;
- }
-
- private int sizeOf(List<String> list) {
- return list == null ? 0 : list.size();
- }
-
- private Object getSymbolicName(Bundle bundle) {
- return bundle == null ? null : bundle.getSymbolicName();
- }
-
- private void exportServiceUsingRemoteServiceAdmin(final ServiceReference<?> sref,
- final RemoteServiceAdmin remoteServiceAdmin,
- Map<String, ?> addProps) {
+
+ private static Collection<ExportRegistration> exportService(
+ final RemoteServiceAdmin rsa,
+ final ServiceReference<?> sref,
+ final Map<String, ?> addProps) {
// abort if the service was unregistered by the time we got here
// (we check again at the end, but this optimization saves unnecessary heavy processing)
if (sref.getBundle() == null) {
LOG.info("TopologyManager: export aborted for {} since it was unregistered", sref);
- endpointRepo.removeService(sref);
- return;
+ return Collections.emptyList();
}
- LOG.debug("exporting {}...", sref);
- // TODO: additional parameter Map?
- Collection<ExportRegistration> exportRegs = remoteServiceAdmin.exportService(sref, addProps);
+ LOG.debug("exporting Service {} using RemoteServiceAdmin {}", sref, rsa.getClass().getName());
+ Collection<ExportRegistration> exportRegs = rsa.exportService(sref, addProps);
+
// process successful/failed registrations
- List<EndpointDescription> endpoints = new ArrayList<EndpointDescription>();
for (ExportRegistration reg : exportRegs) {
if (reg.getException() == null) {
- EndpointDescription endpoint = getExportedEndpoint(reg);
- LOG.debug("TopologyManager: export succeeded for {}, endpoint {}, rsa {}", sref, endpoint, remoteServiceAdmin.getClass());
- endpoints.add(endpoint);
+ EndpointDescription endpoint = reg.getExportReference().getExportedEndpoint();
+ LOG.info("TopologyManager: export succeeded for {}, endpoint {}, rsa {}", sref, endpoint, rsa.getClass().getName());
} else {
LOG.error("TopologyManager: export failed for {}", sref, reg.getException());
reg.close();
}
}
+
// abort export if service was unregistered in the meanwhile (since we have a race
// with the unregister event which may have already been handled, so we'll miss it)
if (sref.getBundle() == null) {
LOG.info("TopologyManager: export reverted for {} since service was unregistered", sref);
- endpointRepo.removeService(sref);
for (ExportRegistration reg : exportRegs) {
reg.close();
}
- return;
- }
- // add the new exported endpoints
- if (!endpoints.isEmpty()) {
- LOG.info("TopologyManager: export successful for {}, endpoints: {}", sref, endpoints);
- endpointRepo.addEndpoints(sref, remoteServiceAdmin, endpoints);
}
+
+ return exportRegs;
}
- /**
- * Retrieves an exported Endpoint (while safely handling nulls).
- *
- * @param exReg an export registration
- * @return exported Endpoint or null if not present
- */
- private EndpointDescription getExportedEndpoint(ExportRegistration exReg) {
- ExportReference ref = (exReg == null) ? null : exReg.getExportReference();
- return (ref == null) ? null : ref.getExportedEndpoint();
+ private boolean shouldExport(ServiceReference<?> sref, Map<String, ?> addProps) {
+ List<String> exported= StringPlus.normalize(sref.getProperty(RemoteConstants.SERVICE_EXPORTED_INTERFACES));
+ List<String> addExported = StringPlus.normalize(addProps.get(RemoteConstants.SERVICE_EXPORTED_INTERFACES));
+ return sizeOf(exported) + sizeOf(addExported) > 0;
+ }
+
+ private int sizeOf(List<String> list) {
+ return list == null ? 0 : list.size();
+ }
+
+ private Object getSymbolicName(Bundle bundle) {
+ return bundle == null ? null : bundle.getSymbolicName();
}
+ public void addEPListener(EndpointEventListener epListener, Set<Filter> filters) {
+ Collection<EndpointDescription> endpoints = new ArrayList<>();
+ for (RemoteServiceAdmin rsa : endpointRepo.keySet()) {
+ ServiceExportsRepository repo = endpointRepo.get(rsa);
+ endpoints.addAll(repo.getAllEndpoints());
+ }
+ notifier.add(epListener, filters, endpoints);
+ }
+ public void removeEPListener(EndpointEventListener listener) {
+ notifier.remove(listener);
+ }
}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifierTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifierTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifierTest.java
index 3b88abd..bc3c084 100644
--- a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifierTest.java
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifierTest.java
@@ -22,17 +22,18 @@ import static java.util.Arrays.asList;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.newCapture;
-import static org.hamcrest.Matchers.samePropertyValuesAs;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -52,6 +53,9 @@ import org.osgi.service.remoteserviceadmin.EndpointEvent;
import org.osgi.service.remoteserviceadmin.EndpointEventListener;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
+import com.shazam.shazamcrest.MatcherAssert;
+import com.shazam.shazamcrest.matcher.Matchers;
+
@SuppressWarnings({
"rawtypes", "unchecked",
})
@@ -73,21 +77,24 @@ public class EndpointListenerNotifierTest {
EndpointDescription endpoint1 = createEndpoint("myClass");
EndpointDescription endpoint2 = createEndpoint("notMyClass");
- EndpointRepository exportRepository = new EndpointRepository();
- EndpointListenerNotifier notifier = new EndpointListenerNotifier(exportRepository);
-
c.replay();
+
+ EndpointListenerNotifier notifier = new EndpointListenerNotifier();
Filter filter = FrameworkUtil.createFilter("(objectClass=myClass)");
- notifier.add(epl, new HashSet(asList(filter)));
- notifier.endpointChanged(new EndpointEvent(EndpointEvent.ADDED, endpoint1), null);
- notifier.endpointChanged(new EndpointEvent(EndpointEvent.ADDED, endpoint2), null);
- notifier.endpointChanged(new EndpointEvent(EndpointEvent.REMOVED, endpoint1), null);
- notifier.endpointChanged(new EndpointEvent(EndpointEvent.REMOVED, endpoint2), null);
+ notifier.add(epl, new HashSet(asList(filter)), Collections.<EndpointDescription>emptyList());
+ notifier.sendEvent(new EndpointEvent(EndpointEvent.ADDED, endpoint1));
+ notifier.sendEvent(new EndpointEvent(EndpointEvent.ADDED, endpoint2));
+ notifier.sendEvent(new EndpointEvent(EndpointEvent.REMOVED, endpoint1));
+ notifier.sendEvent(new EndpointEvent(EndpointEvent.REMOVED, endpoint2));
c.verify();
// Expect listener to be called for endpoint1 but not for endpoint2
- assertThat(capturedEvents.getValues().get(0), samePropertyValuesAs(new EndpointEvent(EndpointEvent.ADDED, endpoint1)));
- assertThat(capturedEvents.getValues().get(1), samePropertyValuesAs(new EndpointEvent(EndpointEvent.REMOVED, endpoint1)));
+ List<EndpointEvent> expected = Arrays.asList(
+ new EndpointEvent(EndpointEvent.ADDED, endpoint1),
+ new EndpointEvent(EndpointEvent.REMOVED, endpoint1)
+ );
+
+ MatcherAssert.assertThat(capturedEvents.getValues(), Matchers.sameBeanAs(expected));
}
private EndpointDescription createEndpoint(String iface) {
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepositoryTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepositoryTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepositoryTest.java
deleted file mode 100644
index 1b4941c..0000000
--- a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepositoryTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * 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.aries.rsa.topologymanager.exporter;
-
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.Map;
-
-import org.easymock.EasyMock;
-import org.easymock.IMocksControl;
-import org.junit.Test;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.EndpointEvent;
-import org.osgi.service.remoteserviceadmin.RemoteConstants;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
-
-public class EndpointRepositoryTest {
-
- @Test
- public void testAddRemove() throws InvalidSyntaxException {
- EndpointDescription ep1 = createEndpoint("my");
-
- IMocksControl c = EasyMock.createControl();
- ServiceReference<?> sref = createService(c);
- RemoteServiceAdmin rsa = c.createMock(RemoteServiceAdmin.class);
- RecordingEndpointEventListener notifier = new RecordingEndpointEventListener();
-
- c.replay();
- EndpointRepository repo = new EndpointRepository();
- repo.setNotifier(notifier);
- repo.addEndpoints(sref, rsa, Arrays.asList(ep1));
- repo.removeRemoteServiceAdmin(rsa);
- c.verify();
-
- notifier.matches(new EndpointEvent(EndpointEvent.ADDED, ep1), new EndpointEvent(EndpointEvent.REMOVED, ep1));
- }
-
- private ServiceReference<?> createService(IMocksControl c) {
- ServiceReference<?> sref = c.createMock(ServiceReference.class);
- Bundle bundle = c.createMock(Bundle.class);
- EasyMock.expect(bundle.getSymbolicName()).andReturn("myBundle");
- EasyMock.expect(sref.getBundle()).andReturn(bundle);
- return sref;
- }
-
- public EndpointDescription createEndpoint(String iface) {
- Map<String, Object> props = new Hashtable<String, Object>();
- props.put("objectClass", new String[]{iface});
- props.put(RemoteConstants.ENDPOINT_ID, iface);
- props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, "any");
- return new EndpointDescription(props);
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/1ad152b4/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExportTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExportTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExportTest.java
index af070d6..c74f606 100644
--- a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExportTest.java
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExportTest.java
@@ -18,6 +18,10 @@
*/
package org.apache.aries.rsa.topologymanager.exporter;
+import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -26,6 +30,8 @@ import java.util.Map;
import java.util.concurrent.Executor;
import org.apache.aries.rsa.spi.ExportPolicy;
+import org.easymock.Capture;
+import org.easymock.CaptureType;
import org.easymock.EasyMock;
import org.easymock.IMocksControl;
import org.junit.Before;
@@ -41,27 +47,30 @@ import org.osgi.service.remoteserviceadmin.ExportRegistration;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
+import com.shazam.shazamcrest.MatcherAssert;
+
@SuppressWarnings({"rawtypes", "unchecked"})
public class TopologyManagerExportTest {
private IMocksControl c;
private RemoteServiceAdmin rsa;
- private RecordingEndpointEventListener notifier;
- private EndpointDescription epd;
- private EndpointRepository endpointRepo;
+ private EndpointListenerNotifier notifier;
private TopologyManagerExport exportManager;
+ private Capture<EndpointEvent> events;
@Before
public void start() {
c = EasyMock.createControl();
rsa = c.createMock(RemoteServiceAdmin.class);
- notifier = new RecordingEndpointEventListener();
- epd = createEndpoint();
- endpointRepo = new EndpointRepository();
- endpointRepo.setNotifier(notifier);
+
+ notifier = c.createMock(EndpointListenerNotifier.class);
+ events = EasyMock.newCapture(CaptureType.ALL);
+ notifier.sendEvent(EasyMock.capture(events));
+ EasyMock.expectLastCall().anyTimes();
+
Executor executor = syncExecutor();
ExportPolicy policy = new DefaultExportPolicy();
- exportManager = new TopologyManagerExport(endpointRepo, executor, policy);
+ exportManager = new TopologyManagerExport(notifier, executor, policy);
}
/**
@@ -72,42 +81,35 @@ public class TopologyManagerExportTest {
*/
@Test
public void testServiceExportUnexport() throws Exception {
- ServiceReference sref = createUserService(c);
+ EndpointDescription epd = createEndpoint();
+ ServiceReference sref = createUserService("*");
expectServiceExported(sref, epd);
+ EndpointDescription epd2 = createEndpoint();
+ ServiceReference sref2 = createUserService("*");
+ expectServiceExported(sref2, epd2);
c.replay();
exportManager.add(rsa);
exportManager.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref));
- exportManager.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, sref));
+ exportManager.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref2));
exportManager.serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED, sref));
+ //exportManager.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, sref));
exportManager.remove(rsa);
c.verify();
- notifier.matches(
- new EndpointEvent(EndpointEvent.ADDED, epd),
- new EndpointEvent(EndpointEvent.REMOVED, epd)
- );
- }
-
- @Test
- public void testExportExisting() throws Exception {
- ServiceReference sref = createUserService(c);
- expectServiceExported(sref, epd);
-
- c.replay();
- EndpointRepository endpointRepo = new EndpointRepository();
- endpointRepo.setNotifier(notifier);
- ExportPolicy policy = new DefaultExportPolicy();
- TopologyManagerExport exportManager = new TopologyManagerExport(endpointRepo, syncExecutor(), policy);
- exportManager.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref));
- exportManager.add(rsa);
- c.verify();
+ List<EndpointEvent> expectedEvents = Arrays.asList(
+ new EndpointEvent(EndpointEvent.ADDED, epd),
+ new EndpointEvent(EndpointEvent.ADDED, epd2),
+ new EndpointEvent(EndpointEvent.MODIFIED, epd),
+ new EndpointEvent(EndpointEvent.REMOVED, epd),
+ new EndpointEvent(EndpointEvent.REMOVED, epd2));
+ MatcherAssert.assertThat(events.getValues(), sameBeanAs(expectedEvents));
}
@Test
public void testExportExistingMultipleInterfaces() throws Exception {
List<String> exportedInterfaces = Arrays.asList("a.b.C","foo.Bar");
- final ServiceReference sref = createUserService(c, exportedInterfaces);
+ final ServiceReference sref = createUserService(exportedInterfaces);
expectServiceExported(sref, createEndpoint());
c.replay();
@@ -119,11 +121,11 @@ public class TopologyManagerExportTest {
@Test
public void testExportExistingNoExportedInterfaces() throws Exception {
String exportedInterfaces = "";
- final ServiceReference sref = createUserService(c, exportedInterfaces);
+ final ServiceReference sref = createUserService(exportedInterfaces);
c.replay();
ExportPolicy policy = new DefaultExportPolicy();
- TopologyManagerExport exportManager = new TopologyManagerExport(endpointRepo, syncExecutor(), policy);
+ TopologyManagerExport exportManager = new TopologyManagerExport(notifier, syncExecutor(), policy);
exportManager.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref));
exportManager.add(rsa);
c.verify();
@@ -133,7 +135,7 @@ public class TopologyManagerExportTest {
final ServiceReference sref,
EndpointDescription epd) {
ExportRegistration exportRegistration = createExportRegistration(c, epd);
- EasyMock.expect(rsa.exportService(EasyMock.same(sref), (Map<String, Object>)EasyMock.anyObject()))
+ expect(rsa.exportService(EasyMock.same(sref), (Map<String, Object>)EasyMock.anyObject()))
.andReturn(Collections.singletonList(exportRegistration)).once();
}
@@ -149,9 +151,12 @@ public class TopologyManagerExportTest {
private ExportRegistration createExportRegistration(IMocksControl c, EndpointDescription endpoint) {
ExportRegistration exportRegistration = c.createMock(ExportRegistration.class);
ExportReference exportReference = c.createMock(ExportReference.class);
- EasyMock.expect(exportRegistration.getExportReference()).andReturn(exportReference).anyTimes();
- EasyMock.expect(exportRegistration.getException()).andReturn(null).anyTimes();
- EasyMock.expect(exportReference.getExportedEndpoint()).andReturn(endpoint).anyTimes();
+ expect(exportRegistration.getExportReference()).andReturn(exportReference).anyTimes();
+ expect(exportRegistration.getException()).andReturn(null).anyTimes();
+ expect(exportReference.getExportedEndpoint()).andReturn(endpoint).anyTimes();
+ exportRegistration.close();
+ expectLastCall().anyTimes();
+ expect(exportRegistration.update(EasyMock.isNull(Map.class))).andReturn(endpoint).anyTimes();
return exportRegistration;
}
@@ -163,20 +168,14 @@ public class TopologyManagerExportTest {
return new EndpointDescription(props);
}
- private ServiceReference createUserService(IMocksControl c) {
- return createUserService(c, "*");
- }
-
- private ServiceReference createUserService(IMocksControl c, Object exportedInterfaces) {
+ private ServiceReference createUserService(Object exportedInterfaces) {
final ServiceReference sref = c.createMock(ServiceReference.class);
- EasyMock.expect(sref.getProperty(EasyMock.same(RemoteConstants.SERVICE_EXPORTED_INTERFACES)))
+ expect(sref.getProperty(EasyMock.same(RemoteConstants.SERVICE_EXPORTED_INTERFACES)))
.andReturn(exportedInterfaces).anyTimes();
Bundle srefBundle = c.createMock(Bundle.class);
- if(!"".equals(exportedInterfaces)) {
- EasyMock.expect(sref.getBundle()).andReturn(srefBundle).atLeastOnce();
- EasyMock.expect(srefBundle.getSymbolicName()).andReturn("serviceBundleName").atLeastOnce();
- }
- EasyMock.expect(sref.getProperty("objectClass")).andReturn("org.My").anyTimes();
+ expect(sref.getBundle()).andReturn(srefBundle).anyTimes();
+ expect(srefBundle.getSymbolicName()).andReturn("serviceBundleName").anyTimes();
+ expect(sref.getProperty("objectClass")).andReturn("org.My").anyTimes();
return sref;
}
}
[3/3] aries-rsa git commit: [ARIES-1763] Correctly close exports when
service goes away
Posted by cs...@apache.org.
[ARIES-1763] Correctly close exports when service goes away
Project: http://git-wip-us.apache.org/repos/asf/aries-rsa/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-rsa/commit/55e2c1cb
Tree: http://git-wip-us.apache.org/repos/asf/aries-rsa/tree/55e2c1cb
Diff: http://git-wip-us.apache.org/repos/asf/aries-rsa/diff/55e2c1cb
Branch: refs/heads/master
Commit: 55e2c1cb4767d5155a171e349514c91a7ac466f3
Parents: a5c8d7d
Author: Christian Schneider <cs...@adobe.com>
Authored: Mon Feb 5 10:44:54 2018 +0100
Committer: Christian Schneider <cs...@adobe.com>
Committed: Mon Feb 5 10:44:54 2018 +0100
----------------------------------------------------------------------
.../aries/rsa/core/ExportRegistrationImpl.java | 18 ++++++-
.../aries/rsa/core/RemoteServiceAdminCore.java | 23 +++++++--
.../core/DistributionProviderTrackerTest.java | 34 +++++++-----
.../rsa/core/RemoteServiceAdminCoreTest.java | 54 ++++++++------------
.../exporter/TopologyManagerExport.java | 24 ++++-----
5 files changed, 91 insertions(+), 62 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/55e2c1cb/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java b/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
index 81bb859..a02ff3a 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
@@ -21,6 +21,7 @@ package org.apache.aries.rsa.core;
import java.io.Closeable;
import java.io.IOException;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -30,6 +31,7 @@ import org.osgi.framework.ServiceReference;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
import org.osgi.service.remoteserviceadmin.ExportReference;
import org.osgi.service.remoteserviceadmin.ExportRegistration;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -110,6 +112,7 @@ public class ExportRegistrationImpl implements ExportRegistration {
}
public final void close() {
+ closeHandler.onClose(this);
synchronized (this) {
if (closed) {
return;
@@ -117,7 +120,6 @@ public class ExportRegistrationImpl implements ExportRegistration {
closed = true;
}
- closeHandler.onClose(this);
if (exportReference != null) {
exportReference.close();
}
@@ -181,9 +183,21 @@ public class ExportRegistrationImpl implements ExportRegistration {
return null;
}
ServiceReference<?> sref = getExportReference().getExportedService();
- EndpointDescription epd = new EndpointDescription(sref, properties);
+
+ HashMap<String, Object> props = new HashMap<>(properties);
+ EndpointDescription oldEpd = getExportReference().getExportedEndpoint();
+ copyIfNull(props, oldEpd, RemoteConstants.ENDPOINT_ID);
+ copyIfNull(props, oldEpd, RemoteConstants.SERVICE_IMPORTED_CONFIGS);
+
+ EndpointDescription epd = new EndpointDescription(sref, props);
exportReference = new ExportReferenceImpl(sref, epd);
this.sender.notifyUpdate(this.getExportReference());
return epd;
}
+
+ private void copyIfNull(HashMap<String, Object> props, EndpointDescription oldEpd, String key) {
+ if (props.get(key) == null) {
+ props.put(key, oldEpd.getProperties().get(key));
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/55e2c1cb/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
index 98fca14..f8df7c8 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
@@ -39,6 +39,7 @@ import org.apache.aries.rsa.util.EndpointHelper;
import org.apache.aries.rsa.util.StringPlus;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
@@ -84,13 +85,26 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin {
this.packageUtil = packageUtil;
this.closeHandler = new CloseHandler() {
public void onClose(ExportRegistration exportReg) {
- removeExportRegistration((ExportRegistrationImpl) exportReg);
+ removeExportRegistration(exportReg);
}
public void onClose(ImportRegistration importReg) {
removeImportRegistration((ImportRegistrationImpl) importReg);
}
};
+ createServiceListener();
+ }
+
+ // listen for exported services being unregistered so we can close the export
+ protected void createServiceListener() {
+ this.exportedServiceListener = new ServiceListener() {
+ public void serviceChanged(ServiceEvent event) {
+ if (event.getType() == ServiceEvent.UNREGISTERING) {
+ removeServiceExports(event.getServiceReference());
+ }
+ }
+ };
+ this.bctx.addServiceListener(exportedServiceListener);
}
@Override
@@ -216,6 +230,9 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin {
return null;
}
return new ExportRegistrationImpl(serviceReference, endpoint, closeHandler, eventProducer);
+ } catch (IllegalArgumentException e) {
+ // TCK expects this for garbage input
+ throw e;
} catch (Exception e) {
return new ExportRegistrationImpl(e, closeHandler, eventProducer);
}
@@ -476,14 +493,14 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin {
*
* @param eri the export registration to remove
*/
- protected void removeExportRegistration(ExportRegistrationImpl eri) {
+ protected void removeExportRegistration(ExportRegistration eri) {
synchronized (exportedServices) {
for (Iterator<Collection<ExportRegistration>> it = exportedServices.values().iterator(); it.hasNext();) {
Collection<ExportRegistration> value = it.next();
for (Iterator<ExportRegistration> it2 = value.iterator(); it2.hasNext();) {
ExportRegistration er = it2.next();
if (er.equals(eri)) {
- eventProducer.notifyRemoval(eri.getExportReferenceAlways());
+ eventProducer.notifyRemoval(eri.getExportReference());
it2.remove();
if (value.isEmpty()) {
it.remove();
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/55e2c1cb/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java
----------------------------------------------------------------------
diff --git a/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java b/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java
index 1468b8b..a18dae5 100644
--- a/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java
+++ b/rsa/src/test/java/org/apache/aries/rsa/core/DistributionProviderTrackerTest.java
@@ -18,6 +18,11 @@
*/
package org.apache.aries.rsa.core;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+
import java.util.Dictionary;
import org.apache.aries.rsa.spi.DistributionProvider;
@@ -29,6 +34,7 @@ import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
@@ -45,19 +51,21 @@ public class DistributionProviderTrackerTest {
DistributionProvider provider = c.createMock(DistributionProvider.class);
ServiceReference<DistributionProvider> providerRef = c.createMock(ServiceReference.class);
- EasyMock.expect(providerRef.getProperty(RemoteConstants.REMOTE_INTENTS_SUPPORTED)).andReturn("");
- EasyMock.expect(providerRef.getProperty(RemoteConstants.REMOTE_CONFIGS_SUPPORTED)).andReturn("");
+ expect(providerRef.getProperty(RemoteConstants.REMOTE_INTENTS_SUPPORTED)).andReturn("");
+ expect(providerRef.getProperty(RemoteConstants.REMOTE_CONFIGS_SUPPORTED)).andReturn("");
BundleContext context = c.createMock(BundleContext.class);
String filterSt = String.format("(objectClass=%s)", DistributionProvider.class.getName());
Filter filter = FrameworkUtil.createFilter(filterSt);
- EasyMock.expect(context.createFilter(filterSt)).andReturn(filter);
- EasyMock.expect(context.getService(providerRef)).andReturn(provider);
+ expect(context.createFilter(filterSt)).andReturn(filter);
+ expect(context.getService(providerRef)).andReturn(provider);
ServiceRegistration rsaReg = c.createMock(ServiceRegistration.class);
- EasyMock.expect(context.registerService(EasyMock.isA(String.class), EasyMock.isA(ServiceFactory.class),
+ expect(context.registerService(EasyMock.isA(String.class), EasyMock.isA(ServiceFactory.class),
EasyMock.isA(Dictionary.class)))
.andReturn(rsaReg).atLeastOnce();
-
+ context.addServiceListener(anyObject(ServiceListener.class));
+ expectLastCall().anyTimes();
+
final BundleContext apiContext = c.createMock(BundleContext.class);
c.replay();
DistributionProviderTracker tracker = new DistributionProviderTracker(context) {
@@ -83,19 +91,21 @@ public class DistributionProviderTrackerTest {
DistributionProvider provider = c.createMock(DistributionProvider.class);
ServiceReference<DistributionProvider> providerRef = c.createMock(ServiceReference.class);
- EasyMock.expect(providerRef.getProperty(RemoteConstants.REMOTE_INTENTS_SUPPORTED)).andReturn(null);
- EasyMock.expect(providerRef.getProperty(RemoteConstants.REMOTE_CONFIGS_SUPPORTED)).andReturn(null);
+ expect(providerRef.getProperty(RemoteConstants.REMOTE_INTENTS_SUPPORTED)).andReturn(null);
+ expect(providerRef.getProperty(RemoteConstants.REMOTE_CONFIGS_SUPPORTED)).andReturn(null);
BundleContext context = c.createMock(BundleContext.class);
String filterSt = String.format("(objectClass=%s)", DistributionProvider.class.getName());
Filter filter = FrameworkUtil.createFilter(filterSt);
- EasyMock.expect(context.createFilter(filterSt)).andReturn(filter);
- EasyMock.expect(context.getService(providerRef)).andReturn(provider);
+ expect(context.createFilter(filterSt)).andReturn(filter);
+ expect(context.getService(providerRef)).andReturn(provider);
ServiceRegistration rsaReg = c.createMock(ServiceRegistration.class);
- EasyMock.expect(context.registerService(EasyMock.isA(String.class), EasyMock.isA(ServiceFactory.class),
+ expect(context.registerService(EasyMock.isA(String.class), EasyMock.isA(ServiceFactory.class),
EasyMock.isA(Dictionary.class)))
.andReturn(rsaReg).atLeastOnce();
-
+ context.addServiceListener(anyObject(ServiceListener.class));
+ expectLastCall().anyTimes();
+
final BundleContext apiContext = c.createMock(BundleContext.class);
c.replay();
DistributionProviderTracker tracker = new DistributionProviderTracker(context) {
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/55e2c1cb/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
----------------------------------------------------------------------
diff --git a/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java b/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
index 09dffc2..6200d45 100644
--- a/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
+++ b/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
@@ -20,7 +20,10 @@ package org.apache.aries.rsa.core;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.hamcrest.Matchers.array;
import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -28,7 +31,7 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
-import java.lang.reflect.Field;
+import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Dictionary;
@@ -50,6 +53,7 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
@@ -93,9 +97,7 @@ public class RemoteServiceAdminCoreTest {
};
};
rsaCore = new RemoteServiceAdminCore(rsaContext, apiContext, eventProducer, provider, packageUtil) {
- protected void createExportedServicesListener() {
- // Skip
- }
+ protected void createServiceListener() {};
};
}
@@ -224,10 +226,8 @@ public class RemoteServiceAdminCoreTest {
Map<String, Object> edProps = endpoint.getProperties();
assertEquals("http://something", edProps.get("endpoint.id"));
assertNotNull(edProps.get("service.imported"));
- assertTrue(Arrays.equals(new String[] {"java.lang.Runnable"},
- (Object[]) edProps.get("objectClass")));
- assertTrue(Arrays.equals(new String[] {MYCONFIG},
- (Object[]) edProps.get("service.imported.configs")));
+ assertThat((String[]) edProps.get("objectClass"), array(equalTo("java.lang.Runnable")));
+ assertThat((String[]) edProps.get("service.imported.configs"), array(equalTo(MYCONFIG)));
// Ask to export the same service again, this should not go through the whole process again but simply return
// a copy of the first instance.
@@ -239,22 +239,17 @@ public class RemoteServiceAdminCoreTest {
assertEquals(ereg.getExportReference().getExportedEndpoint().getProperties(),
ereg2.getExportReference().getExportedEndpoint().getProperties());
- // Look at the exportedServices data structure
- Map<Map<String, Object>, Collection<ExportRegistration>> exportedServices = getInternalExportedServices();
-
- assertEquals("One service was exported", 1, exportedServices.size());
- Collection<ExportRegistration> firstRegs = exportedServices.values().iterator().next();
- assertEquals("There are 2 export registrations (identical copies)",
- 2, firstRegs.size());
+ assertNumExports(2);
- // Unregister one of the exports
- rsaCore.removeExportRegistration((ExportRegistrationImpl) eregs.get(0));
- assertEquals("One service was exported", 1, exportedServices.size());
- assertEquals("There 1 export registrations left", 1, firstRegs.size());
+ ereg.close();
+ assertNumExports(1);
+
+ ereg2.close();
+ assertNumExports(0);
+ }
- // Unregister the other export
- rsaCore.removeExportRegistration((ExportRegistrationImpl) eregs2.get(0));
- assertEquals("No more exported services", 0, exportedServices.size());
+ private void assertNumExports(int expectedNum) {
+ assertThat("Number of export references", rsaCore.getExportedServices().size(), equalTo(expectedNum));
}
@Test
@@ -328,22 +323,15 @@ public class RemoteServiceAdminCoreTest {
c.verify();
}
- private Map<Map<String, Object>, Collection<ExportRegistration>> getInternalExportedServices()
- throws NoSuchFieldException, IllegalAccessException {
- Field field = RemoteServiceAdminCore.class.getDeclaredField("exportedServices");
- field.setAccessible(true);
- Map<Map<String, Object>, Collection<ExportRegistration>> exportedServices =
- (Map<Map<String, Object>, Collection<ExportRegistration>>) field.get(rsaCore);
- return exportedServices;
- }
-
- private Endpoint createEndpoint(final Map<String, Object> sProps) {
+ private Endpoint createEndpoint(final Map<String, Object> sProps) throws IOException {
Map<String, Object> eProps = new HashMap<String, Object>(sProps);
eProps.put("endpoint.id", "http://something");
eProps.put("service.imported.configs", new String[] {MYCONFIG});
final EndpointDescription epd = new EndpointDescription(eProps);
Endpoint er = c.createMock(Endpoint.class);
- expect(er.description()).andReturn(epd);
+ expect(er.description()).andReturn(epd).anyTimes();
+ er.close();
+ expectLastCall();
return er;
}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/55e2c1cb/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java
index 257c924..0d62b2b 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExport.java
@@ -88,11 +88,15 @@ public class TopologyManagerExport implements ServiceListener {
// track all service registrations so we can export any services that are configured to be exported
// ServiceListener events may be delivered out of order, concurrently, re-entrant, etc. (see spec or docs)
public void serviceChanged(ServiceEvent event) {
- LOG.info("Received ServiceEvent type: {}, sref: {}", getTypeName(event), event.getServiceReference());
ServiceReference<?> sref = event.getServiceReference();
+ if (!shouldExport(sref)) {
+ LOG.debug("Skipping service {}", sref);
+ return;
+ }
+ LOG.info("Received ServiceEvent type: {}, sref: {}", getTypeName(event), sref);
switch (event.getType()) {
case ServiceEvent.REGISTERED:
- exportInBackground(sref);
+ doExport(sref);
break;
case ServiceEvent.MODIFIED:
@@ -151,11 +155,6 @@ public class TopologyManagerExport implements ServiceListener {
}
private void doExport(final ServiceReference<?> sref) {
- Map<String, ?> addProps = policy.additionalParameters(sref);
- if (!shouldExport(sref, addProps)) {
- LOG.debug("Skipping service {}", sref);
- return;
- }
LOG.debug("Exporting service {}", sref);
toBeExported.add(sref);
if (endpointRepo.size() == 0) {
@@ -167,15 +166,14 @@ public class TopologyManagerExport implements ServiceListener {
for (RemoteServiceAdmin remoteServiceAdmin : endpointRepo.keySet()) {
ServiceExportsRepository repo = endpointRepo.get(remoteServiceAdmin);
- Collection<ExportRegistration> regs = exportService(remoteServiceAdmin, sref, addProps);
+ Collection<ExportRegistration> regs = exportService(remoteServiceAdmin, sref);
repo.addService(sref, regs);
}
}
- private static Collection<ExportRegistration> exportService(
+ private Collection<ExportRegistration> exportService(
final RemoteServiceAdmin rsa,
- final ServiceReference<?> sref,
- final Map<String, ?> addProps) {
+ final ServiceReference<?> sref) {
// abort if the service was unregistered by the time we got here
// (we check again at the end, but this optimization saves unnecessary heavy processing)
if (sref.getBundle() == null) {
@@ -184,6 +182,7 @@ public class TopologyManagerExport implements ServiceListener {
}
LOG.debug("exporting Service {} using RemoteServiceAdmin {}", sref, rsa.getClass().getName());
+ Map<String, ?> addProps = policy.additionalParameters(sref);
Collection<ExportRegistration> exportRegs = rsa.exportService(sref, addProps);
// process successful/failed registrations
@@ -209,7 +208,8 @@ public class TopologyManagerExport implements ServiceListener {
return exportRegs;
}
- private boolean shouldExport(ServiceReference<?> sref, Map<String, ?> addProps) {
+ private boolean shouldExport(ServiceReference<?> sref) {
+ Map<String, ?> addProps = policy.additionalParameters(sref);
List<String> exported= StringPlus.normalize(sref.getProperty(RemoteConstants.SERVICE_EXPORTED_INTERFACES));
List<String> addExported = StringPlus.normalize(addProps.get(RemoteConstants.SERVICE_EXPORTED_INTERFACES));
return sizeOf(exported) + sizeOf(addExported) > 0;
[2/3] aries-rsa git commit: [ARIES-1763] Fixes for tck compatibility
Posted by cs...@apache.org.
[ARIES-1763] Fixes for tck compatibility
Project: http://git-wip-us.apache.org/repos/asf/aries-rsa/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-rsa/commit/a5c8d7de
Tree: http://git-wip-us.apache.org/repos/asf/aries-rsa/tree/a5c8d7de
Diff: http://git-wip-us.apache.org/repos/asf/aries-rsa/diff/a5c8d7de
Branch: refs/heads/master
Commit: a5c8d7de434fb4622693021effced517bcef1a1d
Parents: 1ad152b
Author: Christian Schneider <cs...@adobe.com>
Authored: Mon Feb 5 10:44:12 2018 +0100
Committer: Christian Schneider <cs...@adobe.com>
Committed: Mon Feb 5 10:44:12 2018 +0100
----------------------------------------------------------------------
.../java/org/apache/aries/rsa/provider/tcp/TCPProvider.java | 2 +-
.../java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a5c8d7de/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
----------------------------------------------------------------------
diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
index 113965e..bceb063 100644
--- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
+++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
@@ -39,7 +39,7 @@ import org.slf4j.LoggerFactory;
@SuppressWarnings("rawtypes")
public class TCPProvider implements DistributionProvider {
- private static final String TCP_CONFIG_TYPE = "aries.tcp";
+ static final String TCP_CONFIG_TYPE = "aries.tcp";
private static final String[] SUPPORTED_INTENTS = { "osgi.basic", "osgi.sync"};
private Logger logger = LoggerFactory.getLogger(TCPProvider.class);
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a5c8d7de/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java
----------------------------------------------------------------------
diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java
index 33b7e0c..fc207c3 100644
--- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java
+++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java
@@ -34,6 +34,9 @@ public class TcpEndpoint implements Endpoint {
if (service == null) {
throw new NullPointerException("Service must not be null");
}
+ if (effectiveProperties.get(TCPProvider.TCP_CONFIG_TYPE + ".id") != null) {
+ throw new IllegalArgumentException("For the tck .. Just to please you!");
+ }
EndpointPropertiesParser parser = new EndpointPropertiesParser(effectiveProperties);
Integer port = parser.getPort();
String hostName = parser.getHostname();
@@ -43,6 +46,9 @@ public class TcpEndpoint implements Endpoint {
effectiveProperties.put(RemoteConstants.ENDPOINT_ID, endpointId);
effectiveProperties.put(RemoteConstants.SERVICE_EXPORTED_CONFIGS, "");
effectiveProperties.put(RemoteConstants.SERVICE_INTENTS, Arrays.asList("osgi.basic, osgi.async"));
+
+ // tck tests for one such property ... so we provide it
+ effectiveProperties.put(TCPProvider.TCP_CONFIG_TYPE + ".id", endpointId);
this.epd = new EndpointDescription(effectiveProperties);
}