You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by am...@apache.org on 2021/03/10 10:27:29 UTC

[aries-rsa] 04/04: ARIES-2043 - Fix LocalDiscovery not updated when listener scope changes

This is an automated email from the ASF dual-hosted git repository.

amichai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/aries-rsa.git

commit f2d25032e8c6039dbbc51131904c78d1e6933024
Author: Amichai Rothman <am...@apache.org>
AuthorDate: Wed Mar 10 00:29:58 2021 +0200

    ARIES-2043 - Fix LocalDiscovery not updated when listener scope changes
---
 .../aries/rsa/discovery/local/LocalDiscovery.java  |  9 ++++
 .../rsa/discovery/local/LocalDiscoveryTest.java    | 53 ++++++++++++++++------
 2 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/discovery/local/src/main/java/org/apache/aries/rsa/discovery/local/LocalDiscovery.java b/discovery/local/src/main/java/org/apache/aries/rsa/discovery/local/LocalDiscovery.java
index 0181bb2..63e5cf2 100644
--- a/discovery/local/src/main/java/org/apache/aries/rsa/discovery/local/LocalDiscovery.java
+++ b/discovery/local/src/main/java/org/apache/aries/rsa/discovery/local/LocalDiscovery.java
@@ -125,6 +125,15 @@ public class LocalDiscovery implements BundleListener {
         }
     }
 
+    void updatedListener(ServiceReference<EndpointEventListener> endpointListenerRef, EndpointEventListener endpointListener) {
+        // if service properties have been updated, the filter (scope)
+        // might have changed so we remove and re-add the listener
+        synchronized (listenerToFilters) {
+            unbindListener(endpointListener);
+            bindListener(endpointListenerRef, endpointListener);
+        }
+    }
+
     private Map<String, Collection<EndpointEventListener>> getMatchingListeners(EndpointDescription endpoint) {
         // return a copy of matched filters/listeners so that caller doesn't need to hold locks while triggering events
         Map<String, Collection<EndpointEventListener>> matched = new HashMap<>();
diff --git a/discovery/local/src/test/java/org/apache/aries/rsa/discovery/local/LocalDiscoveryTest.java b/discovery/local/src/test/java/org/apache/aries/rsa/discovery/local/LocalDiscoveryTest.java
index c18b8e0..871b016 100644
--- a/discovery/local/src/test/java/org/apache/aries/rsa/discovery/local/LocalDiscoveryTest.java
+++ b/discovery/local/src/test/java/org/apache/aries/rsa/discovery/local/LocalDiscoveryTest.java
@@ -132,36 +132,38 @@ public class LocalDiscoveryTest {
     public void testEndpointListenerService() throws Exception {
         LocalDiscovery ld = new LocalDiscovery();
 
-        Bundle bundle = createBundle();
+        Bundle bundle = createBundle(); // created with two endpoint descriptions, ClassA and ClassB
         BundleEvent event = new BundleEvent(BundleEvent.STARTED, bundle);
         ld.bundleChanged(event);
         assertEquals(2, ld.endpointDescriptions.size());
 
-        ServiceReference<EndpointEventListener> sr = epListenerWithScope("(objectClass=org.example.ClassA)");
+        assertEquals("Precondition failed", 0, ld.listenerToFilters.size());
+        assertEquals("Precondition failed", 0, ld.filterToListeners.size());
 
         EndpointEventListener el = EasyMock.createMock(EndpointEventListener.class);
+
+        ServiceReference<EndpointEventListener> sr = epListenerWithScope("(objectClass=org.example.ClassA)");
         el.endpointChanged(EasyMock.anyObject(EndpointEvent.class),
                 EasyMock.eq("(objectClass=org.example.ClassA)"));
         EasyMock.expectLastCall();
+
         EasyMock.replay(el);
 
-        // Add the EndpointListener Service
-        assertEquals("Precondition failed", 0, ld.listenerToFilters.size());
-        assertEquals("Precondition failed", 0, ld.filterToListeners.size());
+        // add the EndpointListener service
         ld.bindListener(sr, el);
 
+        EasyMock.verify(el);
+
         assertEquals(1, ld.listenerToFilters.size());
         assertEquals(Collections.singletonList("(objectClass=org.example.ClassA)"), ld.listenerToFilters.get(el));
         assertEquals(1, ld.filterToListeners.size());
         assertEquals(Collections.singletonList(el), ld.filterToListeners.get("(objectClass=org.example.ClassA)"));
 
-        EasyMock.verify(el);
-
-        // Modify the EndpointListener Service
-        // no need to reset the mock for this...
-        ServiceReference<EndpointEventListener> sr2 = epListenerWithScope("(|(objectClass=org.example.ClassA)(objectClass=org.example.ClassB))");
+        // unbind the listener, modify its scope, and bind again
 
         EasyMock.reset(el);
+
+        ServiceReference<EndpointEventListener> sr2 = epListenerWithScope("(|(objectClass=org.example.ClassA)(objectClass=org.example.ClassB))");
         final Set<String> actualEndpoints = new HashSet<>();
         el.endpointChanged(EasyMock.anyObject(EndpointEvent.class),
                 EasyMock.eq("(|(objectClass=org.example.ClassA)(objectClass=org.example.ClassB))"));
@@ -173,22 +175,45 @@ public class LocalDiscoveryTest {
                 return null;
             }
         }).times(2);
+
         EasyMock.replay(el);
 
         ld.unbindListener(el);
         ld.bindListener(sr2, el);
+
+        EasyMock.verify(el);
+
         assertEquals(1, ld.listenerToFilters.size());
-        assertEquals(Arrays.asList("(|(objectClass=org.example.ClassA)(objectClass=org.example.ClassB))"),
+        assertEquals(Collections.singletonList("(|(objectClass=org.example.ClassA)(objectClass=org.example.ClassB))"),
             ld.listenerToFilters.get(el));
         assertEquals(1, ld.filterToListeners.size());
         assertEquals(Collections.singletonList(el),
             ld.filterToListeners.get("(|(objectClass=org.example.ClassA)(objectClass=org.example.ClassB))"));
-
-        EasyMock.verify(el);
         Set<String> expectedEndpoints = new HashSet<>(Arrays.asList("org.example.ClassA", "org.example.ClassB"));
         assertEquals(expectedEndpoints, actualEndpoints);
 
-        // Remove the EndpointListener Service
+        // now change the scope via updated service properties on a registered service
+
+        EasyMock.reset(el);
+
+        ServiceReference<EndpointEventListener> sr3 = epListenerWithScope("(objectClass=org.example.ClassC)");
+        actualEndpoints.clear();
+        el.endpointChanged(EasyMock.anyObject(EndpointEvent.class),
+            EasyMock.eq("(objectClass=org.example.ClassC)"));
+        EasyMock.expectLastCall().andThrow(new AssertionError()).anyTimes();
+
+        EasyMock.replay(el);
+
+        ld.updatedListener(sr3, el);
+
+        EasyMock.verify(el);
+
+        assertEquals(1, ld.listenerToFilters.size());
+        assertEquals(Collections.singletonList("(objectClass=org.example.ClassC)"), ld.listenerToFilters.get(el));
+        assertEquals(1, ld.filterToListeners.size());
+        assertEquals(Collections.singletonList(el), ld.filterToListeners.get("(objectClass=org.example.ClassC)"));
+
+        // remove the EndpointListener service
         ld.unbindListener(el);
         assertEquals(0, ld.listenerToFilters.size());
         assertEquals(0, ld.filterToListeners.size());