/****************************************************************************** * 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.iandt.bundleScope; import java.security.AllPermission; import java.util.List; import java.util.Properties; import org.eclipse.gemini.blueprint.iandt.BaseIntegrationTest; import org.osgi.framework.AdminPermission; import org.osgi.framework.ServiceReference; import org.springframework.context.ConfigurableApplicationContext; import org.eclipse.gemini.blueprint.context.ConfigurableOsgiBundleApplicationContext; import org.eclipse.gemini.blueprint.iandt.scope.common.ScopeTestService; import org.eclipse.gemini.blueprint.util.OsgiFilterUtils; import org.eclipse.gemini.blueprint.util.OsgiServiceReferenceUtils; import org.springframework.util.ObjectUtils; /** * Integration tests for 'bundle' scoped beans. * * @author Costin Leau * */ public class ScopingTest extends BaseIntegrationTest { protected String[] getTestBundlesNames() { return new String[] { "net.sourceforge.cglib, com.springsource.net.sf.cglib, 2.2.0", "org.eclipse.gemini.blueprint.iandt, scoped.bundle.common," + getSpringDMVersion(), "org.eclipse.gemini.blueprint.iandt, scoped.bundle.a," + getSpringDMVersion(), "org.eclipse.gemini.blueprint.iandt, scoped.bundle.b," + getSpringDMVersion() }; } protected String getManifestLocation() { return "org/eclipse/gemini/blueprint/iandt/bundleScope/ScopingTest.MF"; } protected String[] getConfigLocations() { return new String[] { "/org/eclipse/gemini/blueprint/iandt/bundleScope/scope-context.xml" }; } public void testEnvironmentValidity() throws Exception { assertNotNull(getServiceA()); assertNotNull(getServiceB()); } public void testServiceAScopeForCurrentBundle() throws Exception { ScopeTestService serviceAcopy1 = getServiceA(); ScopeTestService serviceAcopy2 = getServiceA(); assertEquals("different bean instances given for the same bundle", serviceAcopy1, serviceAcopy2); } public void testServiceAScopeForBundleA() throws Exception { ScopeTestService serviceAInBundleA = (ScopeTestService) org.eclipse.gemini.blueprint.iandt.scope.a.BeanReference.BEAN; System.out.println(serviceAInBundleA.getServiceIdentity()); System.out.println(getServiceA().getServiceIdentity()); assertFalse("same bean instance used for different bundles", serviceAInBundleA.getServiceIdentity().equals( getServiceA().getServiceIdentity())); } public void testServiceAScopeForBundleB() throws Exception { String symName = "org.eclipse.gemini.blueprint.iandt.scope.b"; ScopeTestService serviceAInBundleB = (ScopeTestService) getAppCtx(symName).getBean("serviceFromA"); assertFalse("same bean instance used for different bundles", serviceAInBundleB.getServiceIdentity().equals( getServiceA().getServiceIdentity())); } public void testServiceBInBundleBAndTestBundle() throws Exception { ScopeTestService serviceAInBundleB = (ScopeTestService) org.eclipse.gemini.blueprint.iandt.scope.b.BeanReference.BEAN; assertFalse("same bean instance used for different bundles", serviceAInBundleB.getServiceIdentity().equals( getServiceB().getServiceIdentity())); } public void testScopedBeanNotExported() throws Exception { Properties props = (Properties) applicationContext.getBean("props"); // ask for it again Properties another = (Properties) applicationContext.getBean("props"); assertSame("different instances returned for the same scope", props, another); } public void testBeanReferenceAndLocalScopeInstanceForBundleA() throws Exception { String symName = "org.eclipse.gemini.blueprint.iandt.scope.a"; assertSame("local references are different", getAppCtx(symName).getBean("a.service"), org.eclipse.gemini.blueprint.iandt.scope.a.BeanReference.BEAN); } public void testBeanReferenceAndLocalScopeInstanceForBundleB() throws Exception { String symName = "org.eclipse.gemini.blueprint.iandt.scope.b"; assertSame("local references are different", getAppCtx(symName).getBean("b.service"), org.eclipse.gemini.blueprint.iandt.scope.b.BeanReference.BEAN); } public void testScopedBeanDestructionCallbackDuringContextRefresh() throws Exception { Properties props = (Properties) applicationContext.getBean("props"); // add some content props.put("foo", "bar"); // check by asking again for the bean Properties another = (Properties) applicationContext.getBean("props"); assertSame(props, another); assertTrue(another.containsKey("foo")); // refresh context applicationContext.refresh(); Properties refreshed = (Properties) applicationContext.getBean("props"); assertNotSame("context refresh does not clean scoped objects", props, refreshed); assertTrue(refreshed.isEmpty()); // check that props object has been cleaned also assertTrue("destroy callback wasn't called/applied", props.isEmpty()); } public void testExportedScopedBeansDestructionCallbackCalled() throws Exception { Object rawServiceA = getServiceA(); assertTrue(rawServiceA instanceof Properties); Properties props = (Properties) rawServiceA; // modify properties props.put("service", "a"); // check service again assertTrue(((Properties) getServiceA()).containsKey("service")); // refresh opposite service getAppCtx("org.eclipse.gemini.blueprint.iandt.scope.a").refresh(); // wait for the context to refresh Thread.sleep(1000); // get service a again assertTrue("scoped bean a did not have its callback called", ((Properties) getServiceA()).isEmpty()); } protected ScopeTestService getServiceA() throws Exception { return getService("a"); } protected ScopeTestService getServiceB() throws Exception { return getService("b"); } protected ScopeTestService getService(String bundleName) { ServiceReference ref = OsgiServiceReferenceUtils.getServiceReference(bundleContext, ScopeTestService.class.getName(), "(Bundle-SymbolicName=org.eclipse.gemini.blueprint.iandt.scope." + bundleName + ")"); if (ref == null) { String filter = OsgiFilterUtils.unifyFilter(ScopeTestService.class, null); System.out.println(ObjectUtils.nullSafeToString(OsgiServiceReferenceUtils.getServiceReferences( bundleContext, filter))); throw new IllegalStateException("cannot find service with owning bundle " + bundleName); } return (ScopeTestService) bundleContext.getService(ref); } private ConfigurableApplicationContext getAppCtx(String symBundle) { ServiceReference ref = OsgiServiceReferenceUtils.getServiceReference(bundleContext, "(" + ConfigurableOsgiBundleApplicationContext.APPLICATION_CONTEXT_SERVICE_PROPERTY_NAME + "=" + symBundle + ")"); if (ref == null) throw new IllegalArgumentException("cannot find appCtx for bundle " + symBundle); return (ConfigurableApplicationContext) bundleContext.getService(ref); } /** * Since the test is creating some application contexts, give it some * privileges. */ protected List getTestPermissions() { List perms = super.getTestPermissions(); perms.add(new AdminPermission("(name=org.eclipse.gemini.blueprint.iandt.scope.a)", "*")); perms.add(new AllPermission()); return perms; } }