Author: pderop
Date: Fri Jan 15 00:01:43 2016
New Revision: 1724713
URL: http://svn.apache.org/viewvc?rev=1724713&view=rev
Log:
Added FactoryConfigurationAdapter test.
Added:
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryConfigurationAdapterTest.java
Modified:
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/DependencyActivatorBase.java
Added:
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryConfigurationAdapterTest.java
URL:
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryConfigurationAdapterTest.java?rev=1724713&view=auto
==============================================================================
---
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryConfigurationAdapterTest.java
(added)
+++
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryConfigurationAdapterTest.java
Fri Jan 15 00:01:43 2016
@@ -0,0 +1,233 @@
+/*
+ * 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.builder.lambda.itest;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.junit.Assert;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.service.cm.ConfigurationAdmin;
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.builder.lambda.Cb;
+import org.junit.Assert;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+/**
+ * @author <a href="mailto:[email protected]">Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes", "serial"})
+public class FactoryConfigurationAdapterTest extends TestBase
+{
+ private static Ensure m_ensure;
+
+ public void testFactoryConfigurationAdapter() {
+ testFactoryConfigurationAdapter(Adapter.class, "updated");
+ }
+
+ public void
testFactoryConfigurationAdapterWithUpdatedCallbackThatTakesComponentAsParameter()
{
+
testFactoryConfigurationAdapter(AdapterWithUpdateMethodThatTakesComponentAsParameter.class,
"updatedWithComponent");
+ }
+
+ public void testFactoryConfigurationAdapter(Class<?> adapterImplClass,
String adapterUpdate) {
+ DependencyManager m = getDM();
+ // helper class that ensures certain steps get executed in sequence
+ m_ensure = new Ensure();
+
+ // Create a Configuration instance, which will create/update/remove a
configuration for factoryPid "MyFactoryPid"
+ ConfigurationCreator configurator = new
ConfigurationCreator("MyFactoryPid", "key", "value1");
+ Component s1 =
component(m).impl(configurator).withService(ConfigurationAdmin.class).build();
+
+ // Create an Adapter that will be instantiated, once the configuration
is created.
+ // This Adapter provides an AdapterService, and depends on an
AdapterExtraDependency service.
+ Component s2 = factoryPidAdapter(m)
+
.factoryPid("MyFactoryPid").impl(adapterImplClass).cb(adapterUpdate).propagate().provides(AdapterService.class,
"foo", "bar")
+ .withService(AdapterExtraDependency.class)
+ .build();
+
+ // Create extra adapter service dependency upon which our adapter
depends on.
+ Component s3 = component(m)
+ .impl(new
AdapterExtraDependency()).provides(AdapterExtraDependency.class).build();
+
+ // Create an AdapterService Consumer
+ Component s4 = component(m)
+
.impl(AdapterServiceConsumer.class).withService(AdapterService.class, srv ->
srv.cb("bind", "change", "remove")).build();
+
+ // Start services
+ m.add(s1);
+ m.add(s2);
+ m.add(s3);
+ m.add(s4);
+
+ // Wait for step 8: the AdapterService consumer has been injected with
the AdapterService, and has called the doService method.
+ m_ensure.waitForStep(8, 10000);
+
+ // Modify configuration.
+ configurator.update("key", "value2");
+
+ // Wait for step 13: the AdapterService has been updated, and the
AdapterService consumer has seen the change
+ m_ensure.waitForStep(13, 10000);
+
+ // Remove the configuration
+ m.remove(s1); // The stop method will remove the configuration
+ m_ensure.waitForStep(16, 10000);
+ m.clear();
+ }
+
+ public static class ConfigurationCreator {
+ private volatile ConfigurationAdmin m_ca;
+ private String m_key;
+ private String m_value;
+ private org.osgi.service.cm.Configuration m_conf;
+ private String m_factoryPid;
+
+ public ConfigurationCreator(String factoryPid, String key, String
value) {
+ m_factoryPid = factoryPid;
+ m_key = key;
+ m_value = value;
+ }
+
+ public void start() {
+ try {
+ m_ensure.step(1);
+ m_conf = m_ca.createFactoryConfiguration(m_factoryPid, null);
+ Hashtable props = new Hashtable();
+ props.put(m_key, m_value);
+ m_conf.update(props);
+ }
+ catch (IOException e) {
+ Assert.fail("Could not create configuration: " +
e.getMessage());
+ }
+ }
+
+ public void update(String key, String val) {
+ Hashtable props = new Hashtable();
+ props.put(key, val);
+ try {
+ m_conf.update(props);
+ }
+ catch (IOException e) {
+ Assert.fail("Could not update configuration: " +
e.getMessage());
+ }
+ }
+
+ public void stop() {
+ try
+ {
+ m_conf.delete();
+ }
+ catch (IOException e)
+ {
+ Assert.fail("Could not remove configuration: " + e.toString());
+ }
+ }
+ }
+
+ public interface AdapterService {
+ public void doService();
+ }
+
+ public static class AdapterExtraDependency {
+ }
+
+ public static class Adapter implements AdapterService {
+ volatile AdapterExtraDependency m_extraDependency; // extra dependency.
+ private int updateCount;
+
+ void updated(Dictionary settings) {
+ updateCount ++;
+ if (updateCount == 1) {
+ m_ensure.step(2);
+ Assert.assertEquals(true,
"value1".equals(settings.get("key")));
+ m_ensure.step(3);
+ } else if (updateCount == 2) {
+ m_ensure.step(9);
+ Assert.assertEquals(true,
"value2".equals(settings.get("key")));
+ m_ensure.step(10);
+ } else {
+ Assert.fail("wrong call to updated method: count=" +
updateCount);
+ }
+ }
+
+ public void doService() {
+ m_ensure.step(8);
+ }
+
+ public void start() {
+ m_ensure.step(4);
+ Assert.assertNotNull(m_extraDependency);
+ m_ensure.step(5);
+ }
+
+ public void stop() {
+ m_ensure.step(16);
+ }
+ }
+
+ public static class AdapterWithUpdateMethodThatTakesComponentAsParameter
extends Adapter {
+ void updatedWithComponent(Component component, Dictionary settings) {
+ Assert.assertNotNull(component);
+ Assert.assertEquals(this, component.getInstance());
+ super.updated(settings);
+ }
+ }
+
+ public static class AdapterServiceConsumer {
+ private AdapterService m_adapterService;
+ private Map m_adapterServiceProperties;
+
+ void bind(Map serviceProperties, AdapterService adapterService) {
+ m_ensure.step(6);
+ m_adapterService = adapterService;
+ m_adapterServiceProperties = serviceProperties;
+ }
+
+ void change(Map serviceProperties, AdapterService adapterService) {
+ m_ensure.step(11);
+ Assert.assertEquals(true,
"value2".equals(m_adapterServiceProperties.get("key")));
+ m_ensure.step(12);
+ Assert.assertEquals(true,
"bar".equals(m_adapterServiceProperties.get("foo")));
+ m_ensure.step(13);
+ }
+
+ public void start() {
+ m_ensure.step(7);
+ Assert.assertNotNull(m_adapterService);
+ Assert.assertEquals(true,
"value1".equals(m_adapterServiceProperties.get("key")));
+ Assert.assertEquals(true,
"bar".equals(m_adapterServiceProperties.get("foo")));
+ m_adapterService.doService();
+ }
+
+ public void stop() {
+ m_ensure.step(14);
+ }
+
+ void remove(AdapterService adapterService) {
+ m_ensure.step(15);
+ }
+ }
+}
Modified:
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/DependencyActivatorBase.java
URL:
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/DependencyActivatorBase.java?rev=1724713&r1=1724712&r2=1724713&view=diff
==============================================================================
---
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/DependencyActivatorBase.java
(original)
+++
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/DependencyActivatorBase.java
Fri Jan 15 00:01:43 2016
@@ -172,6 +172,15 @@ public abstract class DependencyActivato
}
/**
+ * Creates a factory pid adapter that can be used to create a factory
adapter Component.
+ * @param dm the DependencyManager object used to register the built
component
+ * @return a factory pid adapter that can be used to create a factory
adapter Component.
+ */
+ public static FactoryPidAdapterBuilder<?>
factoryPidAdapter(DependencyManager dm) {
+ return new FactoryPidAdapterBuilderImpl<>(dm);
+ }
+
+ /**
* Builds a component using a lambda and a component builder
* @param dm the DependencyManager where the component is auto-added
(unless the component.autoAdd(false) is called)
* @param consumer a lambda that is called to build the component. When
the lambda is called, it will be provided with a