Java tutorial
/* * 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.brooklyn.core.mgmt.osgi; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Enumeration; import java.util.List; import java.util.jar.JarInputStream; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.test.support.TestResourceUnavailableException; import org.apache.brooklyn.util.collections.MutableSet; import org.apache.brooklyn.util.core.ResourceUtils; import org.apache.brooklyn.util.core.osgi.Osgis; import org.apache.brooklyn.util.core.osgi.Osgis.ManifestHelper; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.maven.MavenArtifact; import org.apache.brooklyn.util.maven.MavenRetriever; import org.apache.brooklyn.util.net.Urls; import org.apache.brooklyn.util.os.Os; import org.apache.brooklyn.util.stream.Streams; import org.apache.commons.io.FileUtils; import org.osgi.framework.Bundle; import org.osgi.framework.BundleException; import org.osgi.framework.FrameworkEvent; import org.osgi.framework.launch.Framework; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; /** * Tests some assumptions about OSGi behaviour, in standalone mode (not part of brooklyn). * See {@link OsgiTestResources} for description of test resources. */ public class OsgiStandaloneTest { private static final Logger log = LoggerFactory.getLogger(OsgiStandaloneTest.class); public static final String BROOKLYN_OSGI_TEST_A_0_1_0_PATH = OsgiTestResources.BROOKLYN_OSGI_TEST_A_0_1_0_PATH; public static final String BROOKLYN_OSGI_TEST_A_0_1_0_URL = "classpath:" + BROOKLYN_OSGI_TEST_A_0_1_0_PATH; public static final String BROOKLYN_TEST_OSGI_ENTITIES_PATH = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH; public static final String BROOKLYN_TEST_OSGI_ENTITIES_URL = "classpath:" + BROOKLYN_TEST_OSGI_ENTITIES_PATH; public static final String BROOKLYN_TEST_OSGI_ENTITIES_NAME = "org.apache.brooklyn.test.resources.osgi.brooklyn-test-osgi-entities"; public static final String BROOKLYN_TEST_OSGI_ENTITIES_VERSION = "0.1.0"; protected Framework framework = null; private File storageTempDir; @BeforeMethod(alwaysRun = true) public void setUp() throws Exception { storageTempDir = Os.newTempDir("osgi-standalone"); framework = Osgis.newFrameworkStarted(storageTempDir.getAbsolutePath(), true, null); } @AfterMethod(alwaysRun = true) public void tearDown() throws BundleException, IOException, InterruptedException { tearDownOsgiFramework(framework, storageTempDir); } public static void tearDownOsgiFramework(Framework framework, File storageTempDir) throws BundleException, InterruptedException, IOException { if (framework != null) { framework.stop(); Assert.assertEquals(framework.waitForStop(1000).getType(), FrameworkEvent.STOPPED); framework = null; } if (storageTempDir != null) { FileUtils.deleteDirectory(storageTempDir); storageTempDir = null; } } protected Bundle install(String url) throws BundleException { try { return Osgis.install(framework, url); } catch (Exception e) { throw new IllegalStateException( "test resources not available; may be an IDE issue, so try a mvn rebuild of this project", e); } } protected Bundle installFromClasspath(String resourceName) throws BundleException { TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), resourceName); try { return Osgis.install(framework, String.format("classpath:%s", resourceName)); } catch (Exception e) { throw Exceptions.propagate(e); } } @Test public void testInstallBundle() throws Exception { Bundle bundle = installFromClasspath(BROOKLYN_OSGI_TEST_A_0_1_0_PATH); checkMath(bundle, 3, 6); } @Test public void testBootBundle() throws Exception { Bundle bundle = installFromClasspath(BROOKLYN_TEST_OSGI_ENTITIES_PATH); Class<?> bundleCls = bundle.loadClass("org.apache.brooklyn.test.osgi.entities.SimpleEntity"); Assert.assertEquals(Entity.class, bundle.loadClass(Entity.class.getName())); Assert.assertEquals(Entity.class, bundleCls.getClassLoader().loadClass(Entity.class.getName())); } @Test public void testDuplicateBundle() throws Exception { MavenArtifact artifact = new MavenArtifact("org.apache.brooklyn", "brooklyn-api", "jar", "0.9.0-SNAPSHOT"); // BROOKLYN_VERSION String localUrl = MavenRetriever.localUrl(artifact); if ("file".equals(Urls.getProtocol(localUrl))) { helperDuplicateBundle(localUrl); } else { log.warn("Skipping test OsgiStandaloneTest.testDuplicateBundle due to " + artifact + " not available in local repo."); } } @Test(groups = "Integration") public void testRemoteDuplicateBundle() throws Exception { helperDuplicateBundle(MavenRetriever .hostedUrl(new MavenArtifact("org.apache.brooklyn", "brooklyn-api", "jar", "0.9.0-SNAPSHOT"))); // BROOKLYN_VERSION } public void helperDuplicateBundle(String url) throws Exception { //The bundle is already installed from the boot path. //Make sure that we still get the initially loaded //bundle after trying to install the same version. Bundle bundle = install(url); Assert.assertTrue(Osgis.isExtensionBundle(bundle)); } @Test public void testAMultiplier() throws Exception { Bundle bundle = installFromClasspath(BROOKLYN_OSGI_TEST_A_0_1_0_PATH); checkMath(bundle, 3, 6); setAMultiplier(bundle, 5); checkMath(bundle, 3, 15); } /** run two multiplier tests to ensure that irrespective of order the tests run in, * on a fresh install the multiplier is reset */ @Test public void testANOtherMultiple() throws Exception { Bundle bundle = installFromClasspath(BROOKLYN_OSGI_TEST_A_0_1_0_PATH); checkMath(bundle, 3, 6); setAMultiplier(bundle, 14); checkMath(bundle, 3, 42); } @Test public void testGetBundle() throws Exception { Bundle bundle = installFromClasspath(BROOKLYN_OSGI_TEST_A_0_1_0_PATH); setAMultiplier(bundle, 3); // can look it up based on the same location string (no other "location identifier" reference string seems to work here, however) Bundle bundle2 = installFromClasspath(BROOKLYN_OSGI_TEST_A_0_1_0_PATH); checkMath(bundle2, 3, 9); } @Test public void testUninstallAndReinstallBundle() throws Exception { Bundle bundle = installFromClasspath(BROOKLYN_OSGI_TEST_A_0_1_0_PATH); checkMath(bundle, 3, 6); setAMultiplier(bundle, 3); checkMath(bundle, 3, 9); bundle.uninstall(); Bundle bundle2 = installFromClasspath(BROOKLYN_OSGI_TEST_A_0_1_0_PATH); checkMath(bundle2, 3, 6); } protected void checkMath(Bundle bundle, int input, int output) throws Exception { Assert.assertNotNull(bundle); Class<?> aClass = bundle.loadClass("brooklyn.test.osgi.TestA"); Object aInst = aClass.newInstance(); Object result = aClass.getMethod("times", int.class).invoke(aInst, input); Assert.assertEquals(result, output); } protected void setAMultiplier(Bundle bundle, int newMultiplier) throws Exception { Assert.assertNotNull(bundle); Class<?> aClass = bundle.loadClass("brooklyn.test.osgi.TestA"); aClass.getField("multiplier").set(null, newMultiplier); } @Test public void testReadAManifest() throws Exception { Enumeration<URL> manifests = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF"); log.info("Bundles and exported packages:"); MutableSet<String> allPackages = MutableSet.of(); while (manifests.hasMoreElements()) { ManifestHelper mf = Osgis.ManifestHelper .forManifestContents(Streams.readFullyString(manifests.nextElement().openStream())); List<String> mfPackages = mf.getExportedPackages(); log.info(" " + mf.getSymbolicNameVersion() + ": " + mfPackages); allPackages.addAll(mfPackages); } log.info("Total export package count: " + allPackages.size()); Assert.assertTrue(allPackages.size() > 20, "did not find enough packages"); // probably much larger Assert.assertTrue(allPackages.contains(Osgis.class.getPackage().getName())); } @Test public void testReadKnownManifest() throws Exception { TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_OSGI_ENTITIES_PATH); InputStream in = this.getClass().getResourceAsStream(BROOKLYN_TEST_OSGI_ENTITIES_PATH); JarInputStream jarIn = new JarInputStream(in); ManifestHelper helper = Osgis.ManifestHelper.forManifest(jarIn.getManifest()); jarIn.close(); Assert.assertEquals(helper.getVersion().toString(), "0.1.0"); Assert.assertTrue(helper.getExportedPackages().contains("org.apache.brooklyn.test.osgi.entities")); } @Test public void testLoadOsgiBundleDependencies() throws Exception { Bundle bundle = installFromClasspath(BROOKLYN_TEST_OSGI_ENTITIES_PATH); Assert.assertNotNull(bundle); Class<?> aClass = bundle.loadClass("org.apache.brooklyn.test.osgi.entities.SimpleApplicationImpl"); Object aInst = aClass.newInstance(); Assert.assertNotNull(aInst); } @Test public void testLoadAbsoluteWindowsResourceWithInstalledOSGi() { //Felix installs an additional URL to the system classloader //which throws an IllegalArgumentException when passed a //windows path. See ExtensionManager.java static initializer. String context = "mycontext"; String dummyPath = "C:\\dummypath"; ResourceUtils utils = ResourceUtils.create(this, context); try { utils.getResourceFromUrl(dummyPath); Assert.fail("Non-reachable, should throw an exception for non-existing resource."); } catch (RuntimeException e) { Assert.assertTrue( e.getMessage().startsWith("Error getting resource '" + dummyPath + "' for " + context)); } } }