felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pde...@apache.org
Subject svn commit: r1759769 - in /felix/trunk/dependencymanager: org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ org.apache.felix.dependencymanager/src/org/apache/felix/dm/ org.apache.felix.dependencymanager/src/org/apache/felix/dm...
Date Thu, 08 Sep 2016 09:08:07 GMT
Author: pderop
Date: Thu Sep  8 09:08:07 2016
New Revision: 1759769

URL: http://svn.apache.org/viewvc?rev=1759769&view=rev
Log:
FELIX-5238: ConfigurationDependency should provide the setRequired() method.

Added:
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java
Modified:
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo

Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java?rev=1759769&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java
(added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java
Thu Sep  8 09:08:07 2016
@@ -0,0 +1,110 @@
+/*
+ * 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 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;
+
+/**
+ * Integration test for Optional ConfigurationDependency.
+ * The following behaviors are tested:
+ * 
+ * 1) an OptionalConfigurationConsumer component defines an optional configuration dependency.
+ * 2) then the component is activated: since there is no currently an available configuration,
the component is called in its
+ *    updated callback with a type-safe config, and the component can then be initialized
using the default methods from the type-safe config interface.
+ * 3) then the configuration is registered: at this point the OptionalConfigurationConsumer
is called again in its updated callback , but
+ *    with the real just registered configuration. So, the component can be updated with
the newly just registered config.
+ * 4) then the configuration is unregistered: at this point, the OptionalConfigurationConsumer
is called again in updated callback, like in step 2).
+ *    So, the component is re-initilized using the default methods from the type-safe config.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class OptionalConfigurationDependencyTest extends TestBase {
+    final static String PID = "ConfigurationDependencyTest.pid";
+    
+    public void testOptionalConfigurationConsumer() {
+        DependencyManager m = getDM();
+        Ensure e = new Ensure();
+        Component c1 = m.createComponent().setImplementation(new ConfigurationCreator(e,
PID, 3))
+        		.add(m.createServiceDependency().setService(ConfigurationAdmin.class).setRequired(true));
+        Component c2 = m.createComponent().setImplementation(new OptionalConfigurationConsumer(e))
+        		.add(m.createConfigurationDependency().setCallback("updated", MyConfig.class).setPid(PID).setPropagate(true).setRequired(false));
+        m.add(c2);
+        e.waitForStep(1, 5000);  // c2 called in updated with testKey="default" config
+        e.waitForStep(2,  5000); // c2 called in start()
+        m.add(c1);               // c1 registers a "testKey=testvalue" configuration, using
config admin.
+        e.waitForStep(3, 5000);  // c1 created the conf.
+        e.waitForStep(4, 5000);  // c2 called in updated with testKey="testvalue"
+        m.remove(c1);            // remove configuration.
+        e.waitForStep(5, 5000);  // c2 called in updated with default "testkey=default" property
(using the default method from the config interface.        
+        m.remove(c2);            // stop the OptionalConfigurationConsumer component
+        e.waitForStep(6, 5000);  // c2 stopped
+    }
+
+    
+    public static interface MyConfig {
+        public default String getTestkey() { return "default"; }
+    }
+
+    static class OptionalConfigurationConsumer {
+        protected final Ensure m_ensure;
+        protected volatile int m_updateCount;
+
+        public OptionalConfigurationConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void updated(MyConfig cnf) { // optional configuration, called after start(),
like any other optional dependency callbacks.
+        	if (cnf != null) {
+        		m_updateCount ++;
+        		if (m_updateCount == 1) {
+        			if (!"default".equals(cnf.getTestkey())) {
+        				Assert.fail("Could not find the configured property.");
+        			}
+            		m_ensure.step(1);
+        		} else if (m_updateCount == 2) {
+        			if (!"testvalue".equals(cnf.getTestkey())) {
+        				Assert.fail("Could not find the configured property.");
+        			}
+            		m_ensure.step(4);
+        		} else if (m_updateCount == 3) {
+        			if (!"default".equals(cnf.getTestkey())) {
+        				Assert.fail("Could not find the configured property.");
+        			}
+            		m_ensure.step(5);
+        		}
+        	} else {
+        		// configuration destroyed: should never happen
+        		m_ensure.throwable(new Exception("lost configuration"));
+        	}
+        }
+
+        public void start() {
+        	m_ensure.step(2);
+        }
+        
+        public void stop() {
+        	m_ensure.step(6);
+        }
+    }
+}

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java?rev=1759769&r1=1759768&r2=1759769&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java
(original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java
Thu Sep  8 09:08:07 2016
@@ -26,10 +26,12 @@ import aQute.bnd.annotation.ProviderType
 
 /**
  * Configuration dependency that can track the availability of a (valid) configuration. To
use
- * it, specify a PID for the configuration. The dependency is always required, because if
it is
- * not, it does not make sense to use the dependency manager. In that scenario, simply register
- * your component as a <code>ManagedService(Factory)</code> and handle everything
yourself. Also,
- * only managed services are supported, not factories. If you need support for factories,
then
+ * it, specify a PID for the configuration. The dependency is required by default. If you
define
+ * an optional configuration dependency, the updated callback will be invoked with an empty
Dictionary,
+ * or with a type-safe configuration (which in this case can provide some default methods
that you can
+ * use to inialize your component).
+ * <p>
+ * Also, only managed services are supported, not factories. If you need support for factories,
then
  * you can use 
  * {@link DependencyManager#createFactoryConfigurationAdapterService(String, String, boolean)}.
  * There are a couple of things you need to be aware of when implementing the 
@@ -41,9 +43,6 @@ import aQute.bnd.annotation.ProviderType
  * and implicitly assume you keep working with your old configuration.</li>
  * <li>This method will be called before all required dependencies are available. Make
sure you
  * do not depend on these to parse your settings.</li>
- * <li>unlike all other DM dependency callbacks, the update method is called from the
CM configuration
- * update thread, and is not serialized with the internal queue maintained by the DM component.
- * So, take care to concurrent calls between updated callback and your other lifecycle callbacks.
  * <li>When the configuration is lost, updated callback is invoked with a null dictionary
parameter,
  * and then the component stop lifecycle callback is invoked.
  * <li>When the DM component is stopped, then updated(null) is not invoked.
@@ -240,4 +239,13 @@ public interface ConfigurationDependency
      * Adds a MetaData regarding a given configuration property.
      */
 	ConfigurationDependency add(PropertyMetaData properties);
+	
+    /**
+     * Sets the required flag which determines if this configuration dependency is required
or not.
+     * A configuration dependency is required by default.
+     * 
+     * @param required the required flag
+     * @return this service dependency
+     */
+	ConfigurationDependency setRequired(boolean required);
 }

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java?rev=1759769&r1=1759768&r2=1759769&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java
(original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java
Thu Sep  8 09:08:07 2016
@@ -20,6 +20,7 @@ package org.apache.felix.dm.impl;
 
 import java.util.Arrays;
 import java.util.Dictionary;
+import java.util.Hashtable;
 import java.util.Objects;
 import java.util.Properties;
 import java.util.stream.Stream;
@@ -54,6 +55,7 @@ public class ConfigurationDependencyImpl
 	private final Logger m_logger;
 	private final BundleContext m_context;
 	private volatile boolean m_needsInstance = true;
+	private volatile boolean m_optional;
 
     public ConfigurationDependencyImpl() {
         this(null, null);
@@ -76,6 +78,13 @@ public class ConfigurationDependencyImpl
         m_configType = prototype.m_configType;
 	}
 		
+	@Override
+	public ConfigurationDependencyImpl setRequired(boolean required) {
+			m_optional = ! required;
+			super.setRequired(true); // always required
+			return this;
+	}
+	
     @Override
     public Class<?> getAutoConfigType() {
         return null; // we don't support auto config mode.
@@ -269,9 +278,15 @@ public class ConfigurationDependencyImpl
             return;
         }        
 
+    	if (settings == null && m_optional) {
+    		// Provide a default empty configuration
+    		settings = new Hashtable<>();
+    		settings.put(Constants.SERVICE_PID, m_pid);
+    	}
+
         if (oldSettings == null && settings == null) {
             // CM has started but our configuration is not still present in the CM database.
-            return;
+        	return;        		
         }
 
         // If this is initial settings, or a configuration update, we handle it synchronously.

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo?rev=1759769&r1=1759768&r2=1759769&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo
(original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo
Thu Sep  8 09:08:07 2016
@@ -1 +1 @@
-version 4.3.0
\ No newline at end of file
+version 4.4.0
\ No newline at end of file



Mime
View raw message