/* * 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.felix.dm.itest.api; import java.util.ArrayList; import java.util.Dictionary; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.felix.dm.Component; import org.apache.felix.dm.DependencyManager; import org.apache.felix.dm.itest.util.Ensure; import org.apache.felix.dm.itest.util.TestBase; import org.junit.Assert; import org.osgi.framework.Constants; /** * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> */ @SuppressWarnings({"unchecked", "rawtypes"}) public class AutoConfigTest extends TestBase { private final Ensure m_ensure = new Ensure(); public void testField() throws Exception { final DependencyManager dm = getDM(); // Create a consumer, depending on some providers (autoconfig field). ConsumeWithProviderField consumer = new ConsumeWithProviderField(); Component c = createConsumer(dm, consumer); // Create two providers Component p1 = createProvider(dm, 10, new Provider() { public String toString() { return "provider1"; } public void run() { m_ensure.step(); } }); Component p2 = createProvider(dm, 20, new Provider() { public String toString() { return "provider2"; } public void run() { m_ensure.step(); } }); // add the two providers dm.add(p2); dm.add(p1); // add the consumer, which should have been injected with provider2 (highest rank) dm.add(c); m_ensure.waitForStep(1, 5000); // remove the provider2, the consumer should now be injected with provider1 dm.remove(p2); Assert.assertNotNull(consumer.getProvider()); Assert.assertEquals("provider1", consumer.getProvider().toString()); // remove the provider1, the consumer should have been stopped dm.remove(p1); m_ensure.waitForStep(2, 5000); dm.clear(); } public void testIterableField() throws Exception { final DependencyManager dm = getDM(); ConsumerWithIterableField consumer = new ConsumerWithIterableField(); Component c = createConsumer(dm, consumer); Component p1 = createProvider(dm, 10, new Provider() { public void run() { m_ensure.step(); } public String toString() { return "provider1"; } }); Component p2 = createProvider(dm, 20, new Provider() { public void run() { m_ensure.step();} public String toString() { return "provider2"; } }); dm.add(p2); dm.add(p1); dm.add(c); // the consumer should have been injected with all providers. m_ensure.waitForStep(3, 5000); // check if all providers are there Assert.assertNotNull(consumer.getProvider("provider1")); Assert.assertNotNull(consumer.getProvider("provider2")); // remove provider1 dm.remove(p1); // check if provider1 has been removed and if provider2 is still there Assert.assertNull(consumer.getProvider("provider1")); Assert.assertNotNull(consumer.getProvider("provider2")); // remove provider2, the consumer should be stopped dm.remove(p2); m_ensure.waitForStep(4, 5000); dm.clear(); } public void testMapField() throws Exception { final DependencyManager dm = getDM(); ConsumerWithMapField consumer = new ConsumerWithMapField(); Component c = createConsumer(dm, consumer); Component p1 = createProvider(dm, 10, new Provider() { public void run() { m_ensure.step(); } public String toString() { return "provider1"; } }); Component p2 = createProvider(dm, 20, new Provider() { public void run() { m_ensure.step();} public String toString() { return "provider2"; } }); dm.add(p2); dm.add(p1); dm.add(c); // the consumer should have been injected with all providers. m_ensure.waitForStep(3, 5000); // check if all providers are there Assert.assertNotNull(consumer.getProvider("provider1")); Assert.assertNotNull(consumer.getProvider("provider2")); // remove provider1 dm.remove(p1); // check if provider1 has been removed and if provider2 is still there Assert.assertNull(consumer.getProvider("provider1")); Assert.assertNotNull(consumer.getProvider("provider2")); // remove provider2, the consumer should be stopped dm.remove(p2); m_ensure.waitForStep(4, 5000); dm.clear(); } private Component createProvider(DependencyManager dm, int rank, Provider provider) { Hashtable props = new Hashtable(); props.put(Constants.SERVICE_RANKING, new Integer(rank)); return dm.createComponent() .setImplementation(provider) .setInterface(Provider.class.getName(), props); } private Component createConsumer(DependencyManager dm, Object consumer) { return dm.createComponent() .setImplementation(consumer) .add(dm.createServiceDependency().setService(Provider.class).setRequired(true)); } public static interface Provider extends Runnable { } public class ConsumeWithProviderField { volatile Provider m_provider; void start() { Assert.assertNotNull(m_provider); Assert.assertEquals("provider2", m_provider.toString()); m_ensure.step(1); } public Provider getProvider() { return m_provider; } void stop() { m_ensure.step(2); } } public class ConsumerWithIterableField { final Iterable<Provider> m_providers = new ConcurrentLinkedQueue<>(); final List m_notInjectMe = new ArrayList(); void start() { Assert.assertNotNull(m_providers); int found = 0; for (Provider provider : m_providers) { provider.run(); found ++; } Assert.assertTrue(found == 2); // The "m_notInjectMe" should not be injected with anything Assert.assertEquals(m_notInjectMe.size(), 0); m_ensure.step(3); } public Provider getProvider(String name) { System.out.println("getProvider(" + name + ") : proviers=" + m_providers); for (Provider provider : m_providers) { if (provider.toString().equals(name)) { return provider; } } return null; } void stop() { m_ensure.step(4); } } public class ConsumerWithMapField { final Map<Provider, Dictionary> m_providers = new ConcurrentHashMap<>(); final Map m_notInjectMe = new HashMap<>(); void start() { Assert.assertNotNull(m_providers); System.out.println("ConsumerMap.start: injected providers=" + m_providers); Assert.assertTrue(m_providers.size() == 2); Assert.assertEquals(0, m_notInjectMe.size()); for (Map.Entry<Provider, Dictionary> e : m_providers.entrySet()) { Provider provider = e.getKey(); Dictionary props = e.getValue(); provider.run(); if (provider.toString().equals("provider1")) { Assert.assertEquals(props.get(Constants.SERVICE_RANKING), 10); } else if (provider.toString().equals("provider2")) { Assert.assertEquals(props.get(Constants.SERVICE_RANKING), 20); } else { Assert.fail("Did not find any properties for provider " + provider); } } m_ensure.step(3); } public Provider getProvider(String name) { System.out.println("getProvider(" + name + ") : providers=" + m_providers); for (Provider provider : m_providers.keySet()) { if (provider.toString().equals(name)) { return provider; } } return null; } Map<Provider, Dictionary> getProviders() { return m_providers; } void stop() { m_ensure.step(4); } } }