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 <[email protected]>
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());

Reply via email to