Author: gnodet Date: Tue Jun 8 08:45:08 2010 New Revision: 952570 URL: http://svn.apache.org/viewvc?rev=952570&view=rev Log: Add some blueprint integration tests
Added: camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/ camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/AbstractIntegrationTest.java camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/ camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-1.xml camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-2.xml camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-3.xml Modified: camel/trunk/parent/pom.xml camel/trunk/tests/camel-itest-osgi/pom.xml Modified: camel/trunk/parent/pom.xml URL: http://svn.apache.org/viewvc/camel/trunk/parent/pom.xml?rev=952570&r1=952569&r2=952570&view=diff ============================================================================== --- camel/trunk/parent/pom.xml (original) +++ camel/trunk/parent/pom.xml Tue Jun 8 08:45:08 2010 @@ -1306,6 +1306,14 @@ <artifactId>org.apache.aries.blueprint</artifactId> <version>${aries-blueprint-version}</version> </dependency> + + <!-- OSGi ConfigAdmin service --> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.configadmin</artifactId> + <version>1.2.4</version> + </dependency> + </dependencies> </dependencyManagement> Modified: camel/trunk/tests/camel-itest-osgi/pom.xml URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/pom.xml?rev=952570&r1=952569&r2=952570&view=diff ============================================================================== --- camel/trunk/tests/camel-itest-osgi/pom.xml (original) +++ camel/trunk/tests/camel-itest-osgi/pom.xml Tue Jun 8 08:45:08 2010 @@ -144,6 +144,14 @@ <artifactId>junit</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.aries.blueprint</groupId> + <artifactId>org.apache.aries.blueprint</artifactId> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.configadmin</artifactId> + </dependency> </dependencies> Added: camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/AbstractIntegrationTest.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/AbstractIntegrationTest.java?rev=952570&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/AbstractIntegrationTest.java (added) +++ camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/AbstractIntegrationTest.java Tue Jun 8 08:45:08 2010 @@ -0,0 +1,147 @@ +/* + * 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.camel.itest.osgi.blueprint; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Dictionary; +import java.util.Enumeration; + +import org.apache.camel.test.junit4.TestSupport; +import org.ops4j.pax.exam.CoreOptions; +import org.ops4j.pax.exam.Inject; +import org.ops4j.pax.exam.options.MavenArtifactProvisionOption; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.Filter; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; + +public abstract class AbstractIntegrationTest extends TestSupport { + + public static final long DEFAULT_TIMEOUT = 30000; + + @Inject + protected BundleContext bundleContext; + + protected <T> T getOsgiService(Class<T> type, long timeout) { + return getOsgiService(type, null, timeout); + } + + protected <T> T getOsgiService(Class<T> type) { + return getOsgiService(type, null, DEFAULT_TIMEOUT); + } + + protected <T> T getOsgiService(Class<T> type, String filter, long timeout) { + ServiceTracker tracker = null; + try { + String flt; + if (filter != null) { + if (filter.startsWith("(")) { + flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")" + filter + ")"; + } else { + flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")(" + filter + "))"; + } + } else { + flt = "(" + Constants.OBJECTCLASS + "=" + type.getName() + ")"; + } + Filter osgiFilter = FrameworkUtil.createFilter(flt); + tracker = new ServiceTracker(bundleContext, osgiFilter, null); + tracker.open(true); + // Note that the tracker is not closed to keep the reference + // This is buggy, as the service reference may change i think + Object svc = type.cast(tracker.waitForService(timeout)); + if (svc == null) { + Dictionary dic = bundleContext.getBundle().getHeaders(); + System.err.println("Test bundle headers: " + explode(dic)); + + for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, null))) { + System.err.println("ServiceReference: " + ref); + } + + for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, flt))) { + System.err.println("Filtered ServiceReference: " + ref); + } + + throw new RuntimeException("Gave up waiting for service " + flt); + } + return type.cast(svc); + } catch (InvalidSyntaxException e) { + throw new IllegalArgumentException("Invalid filter", e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + protected Bundle installBundle(String groupId, String artifactId) throws Exception { + MavenArtifactProvisionOption mvnUrl = mavenBundle(groupId, artifactId); + return bundleContext.installBundle(mvnUrl.getURL()); + } + + protected Bundle getInstalledBundle(String symbolicName) { + for (Bundle b : bundleContext.getBundles()) { + if (b.getSymbolicName().equals(symbolicName)) { + return b; + } + } + for (Bundle b : bundleContext.getBundles()) { + System.err.println("Bundle: " + b.getSymbolicName()); + } + throw new RuntimeException("Bundle " + symbolicName + " does not exist"); + } + + /* + * Explode the dictionary into a ,-delimited list of key=value pairs + */ + private static String explode(Dictionary dictionary) { + Enumeration keys = dictionary.keys(); + StringBuffer result = new StringBuffer(); + while (keys.hasMoreElements()) { + Object key = keys.nextElement(); + result.append(String.format("%s=%s", key, dictionary.get(key))); + if (keys.hasMoreElements()) { + result.append(", "); + } + } + return result.toString(); + } + + /* + * Provides an iterable collection of references, even if the original array is null + */ + private static final Collection<ServiceReference> asCollection(ServiceReference[] references) { + return references != null ? Arrays.asList(references) : Collections.<ServiceReference>emptyList(); + } + + /** + * Create an provisioning option for the specified maven artifact + * (groupId and artifactId), using the version found in the list + * of dependencies of this maven project. + * + * @param groupId the groupId of the maven bundle + * @param artifactId the artifactId of the maven bundle + * @return the provisioning option for the given bundle + */ + protected static MavenArtifactProvisionOption mavenBundle(String groupId, String artifactId) { + return CoreOptions.mavenBundle(groupId, artifactId).versionAsInProject(); + } + +} \ No newline at end of file Added: camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java?rev=952570&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java (added) +++ camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java Tue Jun 8 08:45:08 2010 @@ -0,0 +1,181 @@ +/** + * 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.camel.itest.osgi.blueprint; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.junit.Configuration; +import org.ops4j.pax.exam.junit.JUnit4TestRunner; +import org.ops4j.pax.exam.options.UrlProvisionOption; +import org.ops4j.store.Store; +import org.ops4j.store.StoreFactory; +import org.osgi.framework.Constants; +import org.osgi.service.blueprint.container.BlueprintContainer; + +import static org.ops4j.pax.exam.CoreOptions.equinox; +import static org.ops4j.pax.exam.CoreOptions.felix; +import static org.ops4j.pax.exam.CoreOptions.options; +import static org.ops4j.pax.exam.CoreOptions.wrappedBundle; +import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.profile; +import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanFeatures; +import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.workingDirectory; +import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.newBundle; +import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.withBnd; + +...@runwith(JUnit4TestRunner.class) +public class OSGiBlueprintTestSupport extends AbstractIntegrationTest { + + @Test + public void testRouteWithAllComponents() throws Exception { + try { + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle1)", 1000); + fail("The blueprint container should not be available"); + } catch (Exception e) { + } + getInstalledBundle("CamelBlueprintTestBundle1").start(); + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle1)", 5000); + } + + @Test + public void testRouteWithMissingComponent() throws Exception { + getInstalledBundle("org.apache.camel.camel-mail").stop(); + try { + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle2)", 1000); + fail("The blueprint container should not be available"); + } catch (Exception e) { + } + getInstalledBundle("CamelBlueprintTestBundle2").start(); + try { + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle2)", 1000); + fail("The blueprint container should not be available"); + } catch (Exception e) { + } + getInstalledBundle("org.apache.camel.camel-mail").start(); + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle2)", 5000); + } + + @Test + public void testRouteWithMissingDataFormat() throws Exception { + getInstalledBundle("org.apache.camel.camel-jaxb").stop(); + try { + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle3)", 1000); + fail("The blueprint container should not be available"); + } catch (Exception e) { + } + getInstalledBundle("CamelBlueprintTestBundle3").start(); + try { + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle3)", 1000); + fail("The blueprint container should not be available"); + } catch (Exception e) { + } + getInstalledBundle("org.apache.camel.camel-jaxb").start(); + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle3)", 5000); + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Configuration + public static Option[] configure() throws Exception { + + Option[] options = options( + + bundle(newBundle() + .add("OSGI-INF/blueprint/test.xml", OSGiBlueprintTestSupport.class.getResource("blueprint-1.xml")) + .set( Constants.BUNDLE_SYMBOLICNAME, "CamelBlueprintTestBundle1" ) + .build()).noStart(), + + bundle(newBundle() + .add("OSGI-INF/blueprint/test.xml", OSGiBlueprintTestSupport.class.getResource("blueprint-2.xml")) + .set( Constants.BUNDLE_SYMBOLICNAME, "CamelBlueprintTestBundle2" ) + .build()).noStart(), + + bundle(newBundle() + .add("OSGI-INF/blueprint/test.xml", OSGiBlueprintTestSupport.class.getResource("blueprint-3.xml")) + .set( Constants.BUNDLE_SYMBOLICNAME, "CamelBlueprintTestBundle3" ) + .build()).noStart(), + + // install the spring dm profile + profile("spring.dm").version("1.2.0"), + // this is how you set the default log level when using pax logging (logProfile) + org.ops4j.pax.exam.CoreOptions.systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("TRACE"), + + // install blueprint requirements + mavenBundle("org.apache.felix", "org.apache.felix.configadmin"), + // install tiny bundles + mavenBundle("org.ops4j.base", "ops4j-base-store"), + wrappedBundle(mavenBundle("org.ops4j.pax.swissbox", "pax-swissbox-bnd")), + mavenBundle("org.ops4j.pax.swissbox", "pax-swissbox-tinybundles"), + + // using the features to install the camel components + scanFeatures(mavenBundle("org.apache.camel.karaf", "apache-camel").type("xml/features"), + "camel-core", "camel-blueprint", "camel-test", "camel-mail", "camel-jaxb"), + + workingDirectory("target/paxrunner/"), + + felix(), equinox()); + + return options; + } + + private static void copy(InputStream input, OutputStream output, boolean close) throws IOException { + try { + byte[] buf = new byte[8192]; + int bytesRead = input.read(buf); + while (bytesRead != -1) { + output.write(buf, 0, bytesRead); + bytesRead = input.read(buf); + } + output.flush(); + } finally { + if (close) { + close(input, output); + } + } + } + + private static void close(Closeable... closeables) { + if (closeables != null) { + for (Closeable c : closeables) { + try { + c.close(); + } catch (IOException e) { + } + } + } + } + + private static UrlProvisionOption bundle(final InputStream stream) throws IOException { + Store<InputStream> store = StoreFactory.defaultStore(); + return new UrlProvisionOption( store.getLocation( store.store( stream ) ).toURL().toExternalForm() ) ; + } + + +} Added: camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-1.xml URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-1.xml?rev=952570&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-1.xml (added) +++ camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-1.xml Tue Jun 8 08:45:08 2010 @@ -0,0 +1,10 @@ +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> + + <camelContext xmlns="http://camel.apache.org/schema/blueprint"> + <route> + <from uri="direct:start"/> + <to uri="mock:result"/> + </route> + </camelContext> + +</blueprint> Added: camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-2.xml URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-2.xml?rev=952570&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-2.xml (added) +++ camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-2.xml Tue Jun 8 08:45:08 2010 @@ -0,0 +1,10 @@ +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> + + <camelContext xmlns="http://camel.apache.org/schema/blueprint"> + <route> + <from uri="direct:start"/> + <to uri="smtp://ja...@localhost"/> + </route> + </camelContext> + +</blueprint> Added: camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-3.xml URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-3.xml?rev=952570&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-3.xml (added) +++ camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-3.xml Tue Jun 8 08:45:08 2010 @@ -0,0 +1,13 @@ +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> + + <camelContext xmlns="http://camel.apache.org/schema/blueprint"> + <route> + <from uri="direct:start"/> + <marshal> + <jaxb /> + </marshal> + <to uri="mock:result"/> + </route> + </camelContext> + +</blueprint>