/* * 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 WARRANTIESOR 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.jndi.url; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.Arrays; import java.util.HashSet; import java.util.Hashtable; import java.util.Properties; import java.util.Set; import javax.naming.Binding; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameClassPair; import javax.naming.NameNotFoundException; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import org.apache.aries.mocks.BundleContextMock; import org.apache.aries.mocks.BundleMock; import org.apache.aries.unittest.mocks.Skeleton; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.service.blueprint.container.BlueprintContainer; import org.osgi.service.blueprint.container.NoSuchComponentException; public class BlueprintURLContextTest { private static Bundle bundle; static class SimpleComponent { String id; public SimpleComponent (String i) { id = i; } public String getIdMessage () { return id + "_message"; } } static class AnotherComponent extends SimpleComponent { public AnotherComponent (String i) { super(i); } @Override public String getIdMessage () { return "AnotherComponent with id " + id; } } static class BlueprintContainerStub { SimpleComponent comp1 = new SimpleComponent ("comp1"); AnotherComponent comp2 = new AnotherComponent ("comp2"); public Object getComponentInstance (String compId) throws NoSuchComponentException { if (compId.equals("comp1")) { return comp1; } else if (compId.equals("comp2")) { return comp2; } throw new NoSuchComponentException("Component does not exist", compId); } public Set<String> getComponentIds() { return new HashSet<String>(Arrays.asList("comp1", "comp2")); } } @BeforeClass public static void setup() { bundle = Skeleton.newMock(new BundleMock("aBundle", new Hashtable<String, String>()), Bundle.class); BundleContext bc = bundle.getBundleContext(); new org.apache.aries.jndi.startup.Activator().start(bc); Activator a = new Activator(); a.start(bc); a.serviceFound(); // Register a BlueprintContainer mock that will answer getComponentInstance(String id) calls BlueprintContainer bpc = Skeleton.newMock(new BlueprintContainerStub(), BlueprintContainer.class); bc.registerService("org.osgi.service.blueprint.container.BlueprintContainer", bpc, new Hashtable<String, String>()); } @AfterClass public static void teardown() { BundleContextMock.clear(); } @Before public void setupClassLoader() { BundleMock mock = new BundleMock("bundle.for.new.initial.context", new Properties()); Thread.currentThread().setContextClassLoader(mock.getClassLoader()); } @After public void restoreClassLoader() { Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); } /** * Check that we can directly address a blueprint component */ @Test public void testSimpleComponentLookup() throws Exception { BlueprintURLContext bpURLc = new BlueprintURLContext (bundle, new Hashtable<String, String>()); SimpleComponent sc = (SimpleComponent) bpURLc.lookup("blueprint:comp/comp1"); assertNotNull (sc); String msg = sc.getIdMessage(); assertEquals ("comp1 message wrong", "comp1_message", msg); } /** * Validate that we can create an InitialContext at blueprint:comp scope, and then * look components up within it */ @Test public void testTwoLevelComponentLookup() throws Exception { InitialContext ctx = new InitialContext(); Context ctx2 = (Context) ctx.lookup("blueprint:comp"); SimpleComponent sc = (SimpleComponent) ctx2.lookup("comp2"); assertNotNull (sc); String msg = sc.getIdMessage(); assertEquals ("comp2 message wrong", "AnotherComponent with id comp2", msg); } /** * Check that we get a NameNotFoundException if we lookup something not in the * registry. * * @throws NamingException */ @Test(expected=NameNotFoundException.class) public void testLookupForServiceWeNeverHad() throws NamingException { InitialContext ctx = new InitialContext(); ctx.lookup("blueprint:comp/this.is.not.a.component"); } /** * Validate that list() function works for BlueprintURLContext. * This returns an enumeration of component id -> component class name pairs */ @Test public void testList() throws Exception { InitialContext ctx = new InitialContext(); NamingEnumeration<NameClassPair> compList = ctx.list("blueprint:comp"); Set<String> expectedCompIds = new BlueprintContainerStub().getComponentIds(); while (compList.hasMore()) { NameClassPair ncp = compList.next(); String compId = ncp.getName(); String compClass = ncp.getClassName(); if (compId.equals("comp1")) { assertEquals ("comp1 class wrong in list", SimpleComponent.class.getName(), compClass); } else if (compId.equals("comp2")) { assertEquals ("comp2 class wrong in list", AnotherComponent.class.getName(), compClass); } expectedCompIds.remove(compId); } assertEquals ("Not all expected components were found", expectedCompIds.size(), 0); } /** * Test BlueprintURLContext.listBindings() * This returns an enumeration of component id -> component pairs */ @Test public void testListBindings() throws Exception { InitialContext ctx = new InitialContext(); NamingEnumeration<Binding> bindings = ctx.listBindings("blueprint:comp"); Set<String> expectedCompIds = new BlueprintContainerStub().getComponentIds(); while (bindings.hasMore()) { Binding b = bindings.next(); String compId = b.getName(); Object component = b.getObject(); if (compId.equals("comp1")) { SimpleComponent sc = (SimpleComponent) component; assertEquals ("comp1 message wrong", "comp1_message", sc.getIdMessage()); } else if (compId.equals("comp2")) { AnotherComponent ac = (AnotherComponent) component; assertEquals ("comp2 message wrong", "AnotherComponent with id comp2", ac.getIdMessage()); } expectedCompIds.remove(compId); } assertEquals ("Not all expected components were found", expectedCompIds.size(), 0); } @Test public void testBlueprintTimeoutExtractionBothSpecified() { Bundle b = bundleMock ("bundle.name;x=y;p:=q;blueprint.graceperiod:=true;blueprint.timeout:=10000;a=b;c:=d"); int timeout = BlueprintURLContext.getGracePeriod(b); assertEquals ("graceperiod wrong", 10000, timeout); } @Test public void testGracePeriodFalseHandled() throws Exception { Bundle b = bundleMock ("bundle.name;x=y;p:=q;blueprint.graceperiod:=false;blueprint.timeout:=10000;a=b;c:=d"); int timeout = BlueprintURLContext.getGracePeriod(b); assertEquals ("graceperiod wrong", -1, timeout); b = bundleMock ("bundle.name;x=y;p:=q;blueprint.graceperiod:=false;a=b;c:=d"); timeout = BlueprintURLContext.getGracePeriod(b); assertEquals ("graceperiod wrong", -1, timeout); } @Test public void testDefaultsReturnedByDefault() throws Exception { Bundle b = bundleMock("bundle.name;x=y;p:=q;blueprint.graceperiod:=true;a=b;c:=d"); int timeout = BlueprintURLContext.getGracePeriod(b); assertEquals ("graceperiod wrong", 300000, timeout); b = bundleMock ("bundle.name;x=y;p:=q;a=b;c:=d"); timeout = BlueprintURLContext.getGracePeriod(b); assertEquals ("graceperiod wrong", 300000, timeout); } Bundle bundleMock (String bundleSymbolicNameHeader) { Hashtable<String, String> props = new Hashtable<String, String>(); props.put(Constants.BUNDLE_SYMBOLICNAME, bundleSymbolicNameHeader); Bundle result = Skeleton.newMock(new BundleMock("aBundle", props), Bundle.class); return result; } }