/******************************************************************************
* Copyright (c) 2006, 2010 VMware Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
* is available at http://www.opensource.org/licenses/apache2.0.php.
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
* VMware Inc.
*****************************************************************************/
package org.eclipse.gemini.blueprint.internal.service.interceptor;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.Hashtable;
import junit.framework.TestCase;
import org.eclipse.gemini.blueprint.service.importer.OsgiServiceLifecycleListener;
import org.eclipse.gemini.blueprint.service.importer.ServiceReferenceProxy;
import org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceDynamicInterceptor;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.eclipse.gemini.blueprint.mock.MockBundleContext;
import org.eclipse.gemini.blueprint.mock.MockServiceReference;
/**
* Test for the listener rebinding behavior. Makes sure the bind/unbind contract is properly respected.
*
* @author Costin Leau
*
*/
public class OsgiServiceDynamicInterceptorListenerTest extends TestCase {
private ServiceDynamicInterceptor interceptor;
private OsgiServiceLifecycleListener listener;
private MockBundleContext bundleContext;
private ServiceReference[] refs;
protected void setUp() throws Exception {
listener = new SimpleTargetSourceLifecycleListener();
refs = new ServiceReference[] { new MockServiceReference() };
bundleContext = new MockBundleContext() {
public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
return refs;
}
};
interceptor = new ServiceDynamicInterceptor(bundleContext, null, null, getClass().getClassLoader());
interceptor.setListeners(new OsgiServiceLifecycleListener[] { listener });
interceptor.setMandatoryService(false);
interceptor.setProxy(new Object());
interceptor.setServiceImporter(new Object());
interceptor.setSticky(false);
interceptor.setRetryTimeout(1);
SimpleTargetSourceLifecycleListener.BIND = 0;
SimpleTargetSourceLifecycleListener.UNBIND = 0;
}
protected void tearDown() throws Exception {
interceptor = null;
listener = null;
bundleContext = null;
}
public void testBind() {
assertEquals(0, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
interceptor.afterPropertiesSet();
assertEquals(1, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
}
public void testUnbind() {
interceptor.afterPropertiesSet();
assertEquals(1, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
ServiceListener sl = (ServiceListener) bundleContext.getServiceListeners().iterator().next();
// save old ref and invalidate it so new services are not found
ServiceReference oldRef = refs[0];
refs = null;
sl.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, oldRef));
assertEquals(1, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(1, SimpleTargetSourceLifecycleListener.UNBIND);
}
public void testRebindWhenNewServiceAppears() {
interceptor.afterPropertiesSet();
ServiceListener sl = (ServiceListener) bundleContext.getServiceListeners().iterator().next();
Dictionary props = new Hashtable();
// increase service ranking
props.put(Constants.SERVICE_RANKING, new Integer(10));
ServiceReference ref = new MockServiceReference(null, props, null);
ServiceEvent event = new ServiceEvent(ServiceEvent.REGISTERED, ref);
assertEquals(1, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
sl.serviceChanged(event);
assertEquals(2, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
}
public void testRebindWhenServiceGoesDownButAReplacementIsFound() {
interceptor.afterPropertiesSet();
assertEquals(1, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
ServiceListener sl = (ServiceListener) bundleContext.getServiceListeners().iterator().next();
// unregister the old service
sl.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, refs[0]));
// a new one is found since the mock context will return one again
assertEquals(2, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
}
public void testStickinessWhenABetterServiceIsAvailable() throws Exception {
interceptor.setSticky(true);
interceptor.afterPropertiesSet();
ServiceListener sl = (ServiceListener) bundleContext.getServiceListeners().iterator().next();
Dictionary props = new Hashtable();
// increase service ranking
props.put(Constants.SERVICE_RANKING, new Integer(10));
ServiceReference ref = new MockServiceReference(null, props, null);
ServiceEvent event = new ServiceEvent(ServiceEvent.REGISTERED, ref);
assertEquals(1, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
sl.serviceChanged(event);
assertEquals("the proxy is not sticky", 1, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
}
public void testStickinessWhenServiceGoesDown() throws Exception {
interceptor.setSticky(true);
interceptor.afterPropertiesSet();
ServiceListener sl = (ServiceListener) bundleContext.getServiceListeners().iterator().next();
Dictionary props = new Hashtable();
// increase service ranking
props.put(Constants.SERVICE_RANKING, new Integer(10));
ServiceReference higherRankingRef = new MockServiceReference(null, props, null);
refs = new ServiceReference[] { new MockServiceReference(), higherRankingRef };
assertTrue(Arrays.equals(bundleContext.getServiceReferences(null, null), refs));
assertEquals(1, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
sl.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, refs[0]));
assertEquals(2, SimpleTargetSourceLifecycleListener.BIND);
assertEquals(0, SimpleTargetSourceLifecycleListener.UNBIND);
assertSame("incorrect backing reference selected", higherRankingRef, ((ServiceReferenceProxy) interceptor
.getServiceReference()).getTargetServiceReference());
}
}