/* * 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.aries.blueprint.itests; import static org.apache.aries.blueprint.itests.Helper.mvnBundle; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.List; import org.apache.aries.blueprint.BeanProcessor; import org.apache.aries.blueprint.testbundlea.NSHandlerOne; import org.apache.aries.blueprint.testbundlea.NSHandlerTwo; import org.apache.aries.blueprint.testbundlea.ProcessableBean; import org.apache.aries.blueprint.testbundlea.ProcessableBean.Phase; import org.apache.aries.blueprint.testbundleb.OtherBean; import org.apache.aries.blueprint.testbundleb.TestBean; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.osgi.framework.Bundle; import org.osgi.service.blueprint.container.BlueprintContainer; @RunWith(PaxExam.class) public class ASMMultiBundleTest extends AbstractBlueprintIntegrationTest { private void checkInterceptorLog(String []expected, List<String> log){ assertNotNull("interceptor log should not be null",log); System.out.println("Log:"); for(String entry: log){ System.out.println(""+entry); } assertEquals("interceptor log size does not match expected size",expected.length,log.size()); List<String> extra=new ArrayList<String>(); boolean[] found = new boolean[expected.length]; for(String s : log){ boolean used=false; for(int i=0; i<expected.length; i++){ if(s.startsWith(expected[i])){ found[i]=true; used=true; } } if(!used){ extra.add(s); } } if(extra.size()!=0){ String extraFormatted="{"; for(String e:extra){ extraFormatted+=e+" "; } extraFormatted+="}"; fail("surplus interceptor invocations present in invocation log "+extraFormatted); } for(int i=0; i<found.length; i++){ assertTrue("interceptor invocation "+expected[i]+" not found",found[i]); } } // TODO This test seems to fail on some runs. Need to stabilize and reenable @Test @Ignore public void multiBundleTest() throws Exception { //bundlea provides the ns handlers, bean processors, interceptors etc for this test. Bundle bundlea = context().getBundleByName("org.apache.aries.blueprint.testbundlea"); assertNotNull(bundlea); bundlea.start(); //bundleb makes use of the extensions provided by bundlea Bundle bundleb = context().getBundleByName("org.apache.aries.blueprint.testbundleb"); assertNotNull(bundleb); bundleb.start(); //bundleb's container will hold the beans we need to query to check the function //provided by bundlea functioned as expected BlueprintContainer beanContainer = Helper.getBlueprintContainerForBundle(context(), "org.apache.aries.blueprint.testbundleb"); assertNotNull(beanContainer); //TestBeanA should have the values below, no interference should be present from other sources. Object obj1 = beanContainer.getComponentInstance("TestBeanA"); assertTrue(obj1 instanceof TestBean); TestBean testBeanA = (TestBean)obj1; org.junit.Assert.assertEquals("RED", testBeanA.getRed()); org.junit.Assert.assertEquals("GREEN", testBeanA.getGreen()); org.junit.Assert.assertEquals("BLUE", testBeanA.getBlue()); //TestBeanB tests that a custom ns handler is able to inject custom components to the blueprint, //and modify existing components, and use injected components as modifications. Object obj2 = beanContainer.getComponentInstance("TestBeanB"); assertTrue(obj2 instanceof TestBean); TestBean testBeanB = (TestBean)obj2; //value should be set in via the added passthroughmetadata via the nshandler. org.junit.Assert.assertEquals("ONE_VALUE", testBeanB.getRed()); org.junit.Assert.assertEquals("GREEN", testBeanB.getGreen()); org.junit.Assert.assertEquals("BLUE", testBeanB.getBlue()); //TestBeanC tests that custom ns handlers can add interceptors to beans. Object obj3 = beanContainer.getComponentInstance("TestBeanC"); assertTrue(obj3 instanceof TestBean); TestBean testBeanC = (TestBean)obj3; //handlers are in bundlea, with its own container. BlueprintContainer handlerContainer = Helper.getBlueprintContainerForBundle( context(), "org.apache.aries.blueprint.testbundlea"); assertNotNull(handlerContainer); Object ns1 = handlerContainer.getComponentInstance("NSHandlerOne"); assertTrue(ns1 instanceof NSHandlerOne); Object ns2 = handlerContainer.getComponentInstance("NSHandlerTwo"); assertTrue(ns2 instanceof NSHandlerTwo); NSHandlerTwo nstwo = (NSHandlerTwo)ns2; //now we have a handle to the nshandler2, we can query what it 'saw', and ensure //that the interceptors are functioning as expected. List<String> log = nstwo.getLog(); //TestBeanC has the interceptor configured, and is injected to OtherBeanA & OtherBeanB //which then uses the injected bean during their init method call, to invoke a method checkInterceptorLog(new String[] { "PRECALL:TestBeanC:methodToInvoke:[RED]:", "POSTCALL[true]:TestBeanC:methodToInvoke:[RED]:", "PRECALL:TestBeanC:methodToInvoke:[BLUE]:", "POSTCALL[false]:TestBeanC:methodToInvoke:[BLUE]:" }, log); //invoking GREEN is hardwired to cause an exception response, we do this //from here to ensure the exception occurs and is visible as expected RuntimeException re=null; try{ testBeanC.methodToInvoke("GREEN"); }catch(RuntimeException e){ re=e; } assertNotNull("invocation of Green did not cause an exception as expected",re); //Exception responses should be intercepted too, test for the POSTCALLWITHEXCEPTION log entry. log = nstwo.getLog(); checkInterceptorLog(new String[] { "PRECALL:TestBeanC:methodToInvoke:[RED]:", "POSTCALL[true]:TestBeanC:methodToInvoke:[RED]:", "PRECALL:TestBeanC:methodToInvoke:[BLUE]:", "POSTCALL[false]:TestBeanC:methodToInvoke:[BLUE]:", "PRECALL:TestBeanC:methodToInvoke:[GREEN]:", "POSTCALLEXCEPTION[java.lang.RuntimeException: MATCHED ON GREEN (GREEN)]:TestBeanC:methodToInvoke:[GREEN]:" }, log); //ProcessedBean is a test to ensure that BeanProcessors are called.. //The test has the BeanProcessor look for ProcessableBeans, and log itself with them Object obj4 = beanContainer.getComponentInstance("ProcessedBean"); assertTrue(obj4 instanceof ProcessableBean); ProcessableBean pb = (ProcessableBean)obj4; //Note, the BeanProcessor exists in the same container as the beans it processes!! Object bp = beanContainer.getComponentInstance("http://ns.handler.three/BeanProcessor"); assertNotNull(bp); assertTrue(bp instanceof BeanProcessor); assertEquals(1,pb.getProcessedBy().size()); //check we were invoked.. assertEquals(pb.getProcessedBy().get(0),bp); //check invocation for each phase. assertEquals(pb.getProcessedBy(Phase.BEFORE_INIT).get(0),bp); assertEquals(pb.getProcessedBy(Phase.AFTER_INIT).get(0),bp); //destroy invocation will only occur at tear down.. TODO, how to test after teardown. //assertEquals(pb.getProcessedBy(Phase.BEFORE_DESTROY).get(0),bp); //assertEquals(pb.getProcessedBy(Phase.AFTER_DESTROY).get(0),bp); Object objOther = beanContainer.getComponentInstance("PlaceHolderTestBean"); assertTrue(objOther instanceof OtherBean); assertEquals("test1value", ((OtherBean)objOther).getTestValue()); } @Configuration public Option[] configuration() { return new Option[] { baseOptions(), Helper.blueprintBundles(), mvnBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.testbundlea", false), mvnBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.testbundleb", false) }; } }