blob: ccbaca7a568d1c7d8eddf19854af9f66c9431014 [file] [log] [blame]
/**
* 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.cxf.dosgi.discovery.local.internal;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import junit.framework.TestCase;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
import org.osgi.service.remoteserviceadmin.EndpointListener;
public class LocalDiscoveryTest extends TestCase {
public void testLocalDiscovery() throws Exception {
Filter filter = EasyMock.createMock(Filter.class);
EasyMock.replay(filter);
BundleContext bc = EasyMock.createMock(BundleContext.class);
EasyMock.expect(bc.createFilter("(objectClass=org.osgi.service.remoteserviceadmin.EndpointListener)"))
.andReturn(filter);
bc.addServiceListener((ServiceListener) EasyMock.anyObject(),
EasyMock.eq("(objectClass=org.osgi.service.remoteserviceadmin.EndpointListener)"));
EasyMock.expectLastCall();
EasyMock.expect(bc.getServiceReferences("org.osgi.service.remoteserviceadmin.EndpointListener", null))
.andReturn(null);
bc.addBundleListener((BundleListener) EasyMock.anyObject());
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
public Object answer() throws Throwable {
assertEquals(LocalDiscovery.class, EasyMock.getCurrentArguments()[0].getClass());
return null;
}
});
EasyMock.expect(bc.getBundles()).andReturn(null);
EasyMock.replay(bc);
LocalDiscovery ld = new LocalDiscovery(bc);
assertSame(bc, ld.bundleContext);
assertNotNull(ld.listenerTracker);
EasyMock.verify(bc);
EasyMock.reset(bc);
bc.removeBundleListener(ld);
EasyMock.expectLastCall();
bc.removeServiceListener((ServiceListener) EasyMock.anyObject());
EasyMock.expectLastCall();
EasyMock.replay(bc);
ld.shutDown();
EasyMock.verify(bc);
}
public void testPreExistingBundles() throws Exception {
Filter filter = EasyMock.createMock(Filter.class);
EasyMock.replay(filter);
BundleContext bc = EasyMock.createMock(BundleContext.class);
EasyMock.expect(bc.createFilter("(objectClass=org.osgi.service.remoteserviceadmin.EndpointListener)"))
.andReturn(filter);
bc.addServiceListener((ServiceListener) EasyMock.anyObject(),
EasyMock.eq("(objectClass=org.osgi.service.remoteserviceadmin.EndpointListener)"));
EasyMock.expectLastCall();
EasyMock.expect(bc.getServiceReferences("org.osgi.service.remoteserviceadmin.EndpointListener", null))
.andReturn(null);
bc.addBundleListener((BundleListener) EasyMock.anyObject());
EasyMock.expectLastCall();
Bundle b1 = EasyMock.createMock(Bundle.class);
EasyMock.expect(b1.getState()).andReturn(Bundle.RESOLVED);
EasyMock.replay(b1);
Bundle b2 = EasyMock.createMock(Bundle.class);
EasyMock.expect(b2.getState()).andReturn(Bundle.ACTIVE);
Dictionary<String, String> headers = new Hashtable<String, String>();
headers.put("Remote-Service", "OSGI-INF/remote-service/");
EasyMock.expect(b2.getHeaders()).andReturn(headers);
URL rs3URL = getClass().getResource("/ed3.xml");
URL rs4URL = getClass().getResource("/ed4.xml");
List<URL> urls = Arrays.asList(rs3URL, rs4URL);
EasyMock.expect(b2.findEntries("OSGI-INF/remote-service", "*.xml", false))
.andReturn(Collections.enumeration(urls));
EasyMock.replay(b2);
EasyMock.expect(bc.getBundles()).andReturn(new Bundle[] {b1, b2});
EasyMock.replay(bc);
LocalDiscovery ld = new LocalDiscovery(bc);
assertEquals(3, ld.endpointDescriptions.size());
Set<String> expected = new HashSet<String>(
Arrays.asList("http://somewhere:12345", "http://somewhere:1", "http://somewhere"));
Set<String> actual = new HashSet<String>();
for (Map.Entry<EndpointDescription, Bundle> entry : ld.endpointDescriptions.entrySet()) {
assertSame(b2, entry.getValue());
actual.add(entry.getKey().getId());
}
assertEquals(expected, actual);
}
public void testBundleChanged() throws Exception {
LocalDiscovery ld = getLocalDiscovery();
Bundle bundle = EasyMock.createMock(Bundle.class);
EasyMock.expect(bundle.getSymbolicName()).andReturn("testing.bundle").anyTimes();
EasyMock.expect(bundle.getState()).andReturn(Bundle.ACTIVE);
Dictionary<String, String> headers = new Hashtable<String, String>();
headers.put("Remote-Service", "OSGI-INF/rsa/");
EasyMock.expect(bundle.getHeaders()).andReturn(headers);
EasyMock.expect(bundle.findEntries("OSGI-INF/rsa", "*.xml", false))
.andReturn(Collections.enumeration(
Collections.singleton(getClass().getResource("/ed3.xml"))));
EasyMock.replay(bundle);
BundleEvent be0 = new BundleEvent(BundleEvent.INSTALLED, bundle);
ld.bundleChanged(be0);
assertEquals(0, ld.endpointDescriptions.size());
// Create an EndpointListener
final Map<String, Object> props = new Hashtable<String, Object>();
props.put(EndpointListener.ENDPOINT_LISTENER_SCOPE, "(objectClass=*)");
@SuppressWarnings("unchecked")
ServiceReference<EndpointListener> sr = EasyMock.createMock(ServiceReference.class);
EasyMock.expect(sr.getPropertyKeys()).andReturn(props.keySet().toArray(new String[] {})).anyTimes();
EasyMock.expect(sr.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
public Object answer() throws Throwable {
return props.get(EasyMock.getCurrentArguments()[0]);
}
}).anyTimes();
EasyMock.replay(sr);
EndpointListener endpointListener = EasyMock.createMock(EndpointListener.class);
endpointListener.endpointAdded((EndpointDescription) EasyMock.anyObject(), EasyMock.eq("(objectClass=*)"));
EasyMock.expectLastCall();
EasyMock.replay(endpointListener);
ld.addListener(sr, endpointListener);
// Start the bundle
BundleEvent be = new BundleEvent(BundleEvent.STARTED, bundle);
ld.bundleChanged(be);
assertEquals(1, ld.endpointDescriptions.size());
EndpointDescription endpoint = ld.endpointDescriptions.keySet().iterator().next();
assertEquals("http://somewhere:12345", endpoint.getId());
assertSame(bundle, ld.endpointDescriptions.get(endpoint));
EasyMock.verify(endpointListener);
// Stop the bundle
EasyMock.reset(endpointListener);
endpointListener.endpointRemoved((EndpointDescription) EasyMock.anyObject(), EasyMock.eq("(objectClass=*)"));
EasyMock.expectLastCall();
EasyMock.replay(endpointListener);
BundleEvent be1 = new BundleEvent(BundleEvent.STOPPED, bundle);
ld.bundleChanged(be1);
assertEquals(0, ld.endpointDescriptions.size());
EasyMock.verify(endpointListener);
}
public void testEndpointListenerService() throws Exception {
LocalDiscovery ld = getLocalDiscovery();
Bundle bundle = EasyMock.createMock(Bundle.class);
EasyMock.expect(bundle.getState()).andReturn(Bundle.ACTIVE);
Dictionary<String, String> headers = new Hashtable<String, String>();
headers.put("Remote-Service", "OSGI-INF/rsa/ed4.xml");
EasyMock.expect(bundle.getHeaders()).andReturn(headers);
EasyMock.expect(bundle.findEntries("OSGI-INF/rsa", "ed4.xml", false))
.andReturn(Collections.enumeration(
Collections.singleton(getClass().getResource("/ed4.xml"))));
EasyMock.replay(bundle);
BundleEvent be = new BundleEvent(BundleEvent.STARTED, bundle);
ld.bundleChanged(be);
assertEquals(2, ld.endpointDescriptions.size());
final Map<String, Object> props = new Hashtable<String, Object>();
props.put(EndpointListener.ENDPOINT_LISTENER_SCOPE, new String[] {"(objectClass=org.example.ClassA)"});
@SuppressWarnings("unchecked")
ServiceReference<EndpointListener> sr = EasyMock.createMock(ServiceReference.class);
EasyMock.expect(sr.getPropertyKeys()).andReturn(props.keySet().toArray(new String[] {})).anyTimes();
EasyMock.expect(sr.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
public Object answer() throws Throwable {
return props.get(EasyMock.getCurrentArguments()[0]);
}
}).anyTimes();
EasyMock.replay(sr);
EasyMock.reset(ld.bundleContext);
EndpointListener el = EasyMock.createMock(EndpointListener.class);
EasyMock.expect(ld.bundleContext.getService(sr)).andReturn(el);
EasyMock.expect(ld.bundleContext.ungetService(sr)).andReturn(true);
EasyMock.expect(ld.bundleContext.createFilter((String) EasyMock.anyObject())).andAnswer(new IAnswer<Filter>() {
public Filter answer() throws Throwable {
return FrameworkUtil.createFilter((String) EasyMock.getCurrentArguments()[0]);
}
}).anyTimes();
EasyMock.replay(ld.bundleContext);
el.endpointAdded((EndpointDescription) EasyMock.anyObject(),
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());
assertSame(el, ld.listenerTracker.addingService(sr));
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...
props.put(EndpointListener.ENDPOINT_LISTENER_SCOPE,
"(|(objectClass=org.example.ClassA)(objectClass=org.example.ClassB))");
EasyMock.reset(el);
final Set<String> actualEndpoints = new HashSet<String>();
el.endpointAdded((EndpointDescription) EasyMock.anyObject(),
EasyMock.eq("(|(objectClass=org.example.ClassA)(objectClass=org.example.ClassB))"));
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
public Object answer() throws Throwable {
EndpointDescription endpoint = (EndpointDescription) EasyMock.getCurrentArguments()[0];
actualEndpoints.addAll(endpoint.getInterfaces());
return null;
}
}).times(2);
EasyMock.replay(el);
ld.listenerTracker.modifiedService(sr, el);
assertEquals(1, ld.listenerToFilters.size());
assertEquals(Arrays.asList("(|(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<String>(Arrays.asList("org.example.ClassA", "org.example.ClassB"));
assertEquals(expectedEndpoints, actualEndpoints);
// Remove the EndpointListener Service
ld.listenerTracker.removedService(sr, el);
assertEquals(0, ld.listenerToFilters.size());
assertEquals(0, ld.filterToListeners.size());
}
public void testRegisterTracker() throws Exception {
LocalDiscovery ld = getLocalDiscovery();
final Map<String, Object> props = new Hashtable<String, Object>();
props.put(EndpointListener.ENDPOINT_LISTENER_SCOPE, "(objectClass=Aaaa)");
@SuppressWarnings("unchecked")
ServiceReference<EndpointListener> sr = EasyMock.createMock(ServiceReference.class);
EasyMock.expect(sr.getPropertyKeys()).andReturn(props.keySet().toArray(new String[] {})).anyTimes();
EasyMock.expect(sr.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
public Object answer() throws Throwable {
return props.get(EasyMock.getCurrentArguments()[0]);
}
}).anyTimes();
EasyMock.replay(sr);
EndpointListener endpointListener = EasyMock.createMock(EndpointListener.class);
EasyMock.replay(endpointListener);
assertEquals("Precondition failed", 0, ld.listenerToFilters.size());
assertEquals("Precondition failed", 0, ld.filterToListeners.size());
ld.addListener(sr, endpointListener);
assertEquals(1, ld.listenerToFilters.size());
assertEquals(Collections.singletonList("(objectClass=Aaaa)"), ld.listenerToFilters.get(endpointListener));
assertEquals(1, ld.filterToListeners.size());
assertEquals(Collections.singletonList(endpointListener), ld.filterToListeners.get("(objectClass=Aaaa)"));
// Add another one with the same scope filter
@SuppressWarnings("unchecked")
ServiceReference<EndpointListener> sr2 = EasyMock.createMock(ServiceReference.class);
EasyMock.expect(sr2.getPropertyKeys()).andReturn(props.keySet().toArray(new String[] {})).anyTimes();
EasyMock.expect(sr2.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
public Object answer() throws Throwable {
return props.get(EasyMock.getCurrentArguments()[0]);
}
}).anyTimes();
EasyMock.replay(sr2);
EndpointListener endpointListener2 = EasyMock.createMock(EndpointListener.class);
EasyMock.replay(endpointListener2);
ld.addListener(sr2, endpointListener2);
assertEquals(2, ld.listenerToFilters.size());
assertEquals(Collections.singletonList("(objectClass=Aaaa)"), ld.listenerToFilters.get(endpointListener));
assertEquals(Collections.singletonList("(objectClass=Aaaa)"), ld.listenerToFilters.get(endpointListener2));
assertEquals(1, ld.filterToListeners.size());
List<EndpointListener> endpointListeners12 = Arrays.asList(endpointListener, endpointListener2);
assertEquals(endpointListeners12, ld.filterToListeners.get("(objectClass=Aaaa)"));
// Add another listener with a multi-value scope
final Map<String, Object> props2 = new Hashtable<String, Object>();
props2.put(EndpointListener.ENDPOINT_LISTENER_SCOPE, Arrays.asList("(objectClass=X)", "(objectClass=Y)"));
@SuppressWarnings("unchecked")
ServiceReference<EndpointListener> sr3 = EasyMock.createMock(ServiceReference.class);
EasyMock.expect(sr3.getPropertyKeys()).andReturn(props2.keySet().toArray(new String[] {})).anyTimes();
EasyMock.expect(sr3.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
public Object answer() throws Throwable {
return props2.get(EasyMock.getCurrentArguments()[0]);
}
}).anyTimes();
EasyMock.replay(sr3);
EndpointListener endpointListener3 = EasyMock.createMock(EndpointListener.class);
EasyMock.replay(endpointListener3);
ld.addListener(sr3, endpointListener3);
assertEquals(3, ld.listenerToFilters.size());
assertEquals(Collections.singletonList("(objectClass=Aaaa)"), ld.listenerToFilters.get(endpointListener));
assertEquals(Collections.singletonList("(objectClass=Aaaa)"), ld.listenerToFilters.get(endpointListener2));
assertEquals(Arrays.asList("(objectClass=X)", "(objectClass=Y)"), ld.listenerToFilters.get(endpointListener3));
assertEquals(3, ld.filterToListeners.size());
assertEquals(endpointListeners12, ld.filterToListeners.get("(objectClass=Aaaa)"));
assertEquals(Collections.singletonList(endpointListener3), ld.filterToListeners.get("(objectClass=X)"));
assertEquals(Collections.singletonList(endpointListener3), ld.filterToListeners.get("(objectClass=Y)"));
}
public void testClearTracker() throws Exception {
LocalDiscovery ld = getLocalDiscovery();
EndpointListener endpointListener = EasyMock.createMock(EndpointListener.class);
ld.listenerToFilters.put(endpointListener,
new ArrayList<String>(Arrays.asList("(a=b)", "(objectClass=foo.bar.Bheuaark)")));
ld.filterToListeners.put("(a=b)", new ArrayList<EndpointListener>(Arrays.asList(endpointListener)));
ld.filterToListeners.put("(objectClass=foo.bar.Bheuaark)",
new ArrayList<EndpointListener>(Arrays.asList(endpointListener)));
assertEquals(1, ld.listenerToFilters.size());
assertEquals(2, ld.filterToListeners.size());
assertEquals(1, ld.filterToListeners.values().iterator().next().size());
ld.removeListener(EasyMock.createMock(EndpointListener.class));
assertEquals(1, ld.listenerToFilters.size());
assertEquals(2, ld.filterToListeners.size());
assertEquals(1, ld.filterToListeners.values().iterator().next().size());
ld.removeListener(endpointListener);
assertEquals(0, ld.listenerToFilters.size());
assertEquals(0, ld.filterToListeners.size());
}
private LocalDiscovery getLocalDiscovery() throws InvalidSyntaxException {
BundleContext bc = EasyMock.createMock(BundleContext.class);
EasyMock.expect(bc.createFilter((String) EasyMock.anyObject())).andAnswer(new IAnswer<Filter>() {
public Filter answer() throws Throwable {
return FrameworkUtil.createFilter((String) EasyMock.getCurrentArguments()[0]);
}
}).anyTimes();
bc.addServiceListener((ServiceListener) EasyMock.anyObject(),
EasyMock.eq("(objectClass=org.osgi.service.remoteserviceadmin.EndpointListener)"));
EasyMock.expectLastCall();
EasyMock.expect(bc.getServiceReferences("org.osgi.service.remoteserviceadmin.EndpointListener", null))
.andReturn(null);
bc.addBundleListener((BundleListener) EasyMock.anyObject());
EasyMock.expectLastCall();
EasyMock.expect(bc.getBundles()).andReturn(null);
EasyMock.replay(bc);
return new LocalDiscovery(bc);
}
}