| /* |
| * 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.io.IOException; |
| import java.util.Dictionary; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.Map; |
| |
| 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.service.cm.ConfigurationAdmin; |
| |
| public class FELIX5305_DirectInjectionShouldSeeServiceUpdates extends TestBase { |
| |
| final static String PID = "my.service.pid"; |
| final static Ensure m_ensure = new Ensure(); |
| |
| public void testFieldInjectionWithFactoryConfigServices() throws InterruptedException { |
| DependencyManager m = getDM(); |
| |
| ConfigurationCreator configurator = new ConfigurationCreator(PID); |
| Component compConfigurator = m.createComponent() |
| .setImplementation(configurator) |
| .add(m.createServiceDependency().setService(ConfigurationAdmin.class).setRequired(true)); |
| m.add(compConfigurator); |
| |
| m_ensure.waitForStep(1, 3000); |
| |
| MyServices myServices = new MyServices(); |
| m.add(m.createComponent() |
| .setImplementation(myServices) |
| .setInterface(MyServices.class.getName(), null) |
| .add(m.createServiceDependency().setService(Service.class, "(provider=*)").setRequired(true))); |
| |
| m.add(m.createFactoryConfigurationAdapterService(PID, "update", false /* propagate */) |
| .setInterface(Service.class.getName(), null) |
| .setImplementation(ServiceImpl.class)); |
| |
| configurator.update("provider", "message1"); |
| Thread.sleep(500); |
| Assert.assertEquals("message1", myServices.getMessages().get("provider")); |
| |
| configurator.update("provider", "message2"); |
| Thread.sleep(500); |
| Assert.assertEquals("message2", myServices.getMessages().get("provider")); |
| } |
| |
| public interface Service { |
| String getMessage(); |
| } |
| |
| public static class ServiceImpl implements Service { |
| // Managed by Felix DM... |
| private volatile Component m_comp; |
| // Locally managed... |
| private volatile String m_msg; |
| |
| @Override |
| public String getMessage() { |
| return m_msg; |
| } |
| |
| /** |
| * Called by Felix DM. |
| */ |
| protected final void start(Component comp) throws Exception { |
| System.out.printf("ServiceImpl@%d started (msg = %s)%n", hashCode(), m_msg); |
| } |
| |
| /** |
| * Called by Felix DM. |
| */ |
| protected final void stop(Component comp) throws Exception { |
| System.out.printf("ServiceImpl@%d stopped (msg = %s)%n", hashCode(), m_msg); |
| } |
| |
| /** |
| * Called by Felix DM. |
| */ |
| protected final void update(Dictionary<String, ?> config) throws Exception { |
| String provider; |
| if (config != null) { |
| m_msg = (String) config.get("msg"); |
| provider = (String) config.get("provider"); |
| } else { |
| m_msg = "<none set>"; |
| provider = "<unknown>"; |
| } |
| |
| System.out.printf("ServiceImpl@%d config updated (msg = %s; provider = %s)%n", hashCode(), m_msg, provider); |
| |
| Dictionary<Object, Object> props = m_comp.getServiceProperties(); |
| if (props == null) { |
| props = new Hashtable<>(); |
| } |
| |
| props.put("provider", provider); |
| m_comp.setServiceProperties(props); |
| } |
| } |
| |
| public static class MyServices { |
| // Injected by Felix DM... |
| private volatile Map<Service, Dictionary<String, ?>> m_services; |
| |
| public Map<String, String> getMessages() { |
| Map<Service, Dictionary<String, ?>> services = m_services; |
| |
| Map<String, String> result = new HashMap<>(services.size()); |
| for (Service srv : services.keySet()) { |
| String provider = (String) services.get(srv).get("provider"); |
| result.put(provider, srv.getMessage()); |
| } |
| return result; |
| } |
| } |
| |
| public static class ConfigurationCreator { |
| private volatile ConfigurationAdmin m_ca; |
| private org.osgi.service.cm.Configuration m_conf; |
| private String m_factoryPid; |
| |
| public ConfigurationCreator(String factoryPid) { |
| m_factoryPid = factoryPid; |
| } |
| |
| public void start() { |
| m_ensure.step(1); |
| } |
| |
| public void update(String provider, String msg) { |
| try { |
| if (m_conf == null) { |
| m_conf = m_ca.createFactoryConfiguration(m_factoryPid, null); |
| } |
| Hashtable<String, String> props = new Hashtable<>(); |
| props.put("msg", msg); |
| props.put("provider", provider); |
| m_conf.update(props); |
| } catch (IOException e) { |
| Assert.fail("Could not update configuration: " + e.getMessage()); |
| } |
| } |
| |
| public void stop() { |
| try { |
| System.out.println("Destroying conf"); |
| m_conf.delete(); |
| } catch (IOException e) { |
| Assert.fail("Could not remove configuration: " + e.toString()); |
| } |
| } |
| } |
| } |