You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2014/10/30 22:37:02 UTC

svn commit: r1635622 - in /felix/sandbox/pderop/dependencymanager-prototype: org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/b...

Author: pderop
Date: Thu Oct 30 21:37:01 2014
New Revision: 1635622

URL: http://svn.apache.org/r1635622
Log:
FELIX-4600: Cherrypicking of propagated properties. Added a propagate flag in adapter factory methods, and
in the @AdapterService annotation.
Added a AdapterWithoutPropagationTest.java testcase.


Added:
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithoutPropagationTest.java
Modified:
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithCallbackInstanceTest.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java?rev=1635622&r1=1635621&r2=1635622&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java Thu Oct 30 21:37:01 2014
@@ -115,4 +115,9 @@ public @interface AdapterService
      * must also be used.
      */
     String removed() default "";
+    
+    /**
+     * Specifies if adaptee service properties should be propagated to the adapter service.
+     */
+    boolean propagate() default true;
 }

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java?rev=1635622&r1=1635621&r2=1635622&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java Thu Oct 30 21:37:01 2014
@@ -659,6 +659,10 @@ public class AnnotationCollector extends
         // Parse factoryMethod attribute
         writer.putString(annotation, EntryParam.factoryMethod, null);
         
+        // Parse propagate flag.
+        // Parse factoryMethod attribute
+        writer.putString(annotation, EntryParam.propagate, null);
+
         // Parse field/added/changed/removed attributes
         parseAspectOrAdapterCallbackMethods(annotation, writer);
     }

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithCallbackInstanceTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithCallbackInstanceTest.java?rev=1635622&r1=1635621&r2=1635622&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithCallbackInstanceTest.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithCallbackInstanceTest.java Thu Oct 30 21:37:01 2014
@@ -47,7 +47,8 @@ public class AdapterWithCallbackInstance
             );
 
         ServiceAdapterCallbackInstance callbackInstance = new ServiceAdapterCallbackInstance(e);
-        Component adapter = m.createAdapterService(OriginalService.class, null, "m_originalService", callbackInstance, "set", "changed","unset", null)
+        Component adapter = m.createAdapterService(OriginalService.class, null, "m_originalService", 
+                                                   callbackInstance, "set", "changed","unset", null, true)
             .setInterface(AdaptedService.class.getName(), null)
             .setImplementation(new ServiceAdapter(e));
         

Added: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithoutPropagationTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithoutPropagationTest.java?rev=1635622&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithoutPropagationTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/AdapterWithoutPropagationTest.java Thu Oct 30 21:37:01 2014
@@ -0,0 +1,136 @@
+/*
+ * 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;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import junit.framework.Assert;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.ServiceRegistration;
+
+public class AdapterWithoutPropagationTest extends TestBase {
+    
+    public void testAdapterNoPropagate() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+
+        // The provider has a "foo=bar" property
+        Hashtable<String, String> props = new Hashtable<>();
+        props.put("foo", "bar");
+        ServiceProvider serviceProvider = new ServiceProvider(e);
+        Component provider = m.createComponent()
+            .setInterface(OriginalService.class.getName(), props).setImplementation(serviceProvider);
+
+        // The Adapter will see the "foo=bar" property from the adaptee
+        Component adapter = m.createAdapterService(OriginalService.class, null, null,
+                                                   null, "set", "change", null, null, false)
+            .setInterface(AdaptedService.class.getName(), null)
+            .setImplementation(new ServiceAdapter(e));
+
+        // The consumer depends on the AdaptedService, but won't see foo=bar property from the adaptee 
+        Component consumer = m.createComponent()
+            .setImplementation(new ServiceConsumer(e))
+            .add(m.createServiceDependency()
+                .setService(AdaptedService.class)
+                .setRequired(true)
+                .setCallbacks("set", "change", null)
+            );
+        
+        // add the provider and the adapter
+        m.add(provider);
+        m.add(adapter);
+        // Checks if the adapter has been started and has seen the adaptee properties
+        e.waitForStep(1, 5000);
+        
+        // add a consumer that must not see the adaptee service properties
+        m.add(consumer);
+        e.waitForStep(2, 5000);
+        
+        // change the service properties of the provider, and check that the adapter callback instance is caled.
+        serviceProvider.changeServiceProperties();
+        e.waitForStep(3, 5000);
+        
+        // cleanup
+        m.clear();
+    }
+
+    static interface OriginalService {
+    }
+    
+    static interface AdaptedService {
+    }
+    
+    static class ServiceProvider implements OriginalService {
+        private final Ensure m_ensure;
+        private volatile ServiceRegistration m_registration; // auto injected when started.
+        public ServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+        public void changeServiceProperties() {
+            Hashtable<String, String> props = new Hashtable<>();
+            props.put("foo", "bar2");
+            m_registration.setProperties(props);
+        }
+    }
+    
+    public static class ServiceAdapter implements AdaptedService {
+        private volatile OriginalService m_originalService;
+        private final Ensure m_ensure;
+        
+        public ServiceAdapter(Ensure e) {
+            m_ensure = e;
+        }
+
+        public void set(OriginalService adaptee, Dictionary<String, String> props) {
+            m_originalService = adaptee;
+            Assert.assertEquals("bar", props.get("foo"));
+            m_ensure.step(1);
+        }
+        
+        void change(OriginalService adapted, Dictionary<String, String> props) {
+            Assert.assertEquals("bar2", props.get("foo"));
+            m_ensure.step(3);
+        }
+    }
+
+    static class ServiceConsumer {
+        private volatile AdaptedService m_service;
+        private final Ensure m_ensure;
+        
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        void set(AdaptedService adapted, Dictionary<String, String> props) {
+            Assert.assertNull(props.get("foo"));
+            m_ensure.step(2);
+        }
+        
+        void change(AdaptedService adapted, Dictionary<String, String> props) {
+            Assert.assertNull(props.get("foo"));
+            Assert.fail("Change callback should not be called");
+        }
+    }
+}
+
+

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/AdapterServiceBuilder.java?rev=1635622&r1=1635621&r2=1635622&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/AdapterServiceBuilder.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/AdapterServiceBuilder.java Thu Oct 30 21:37:01 2014
@@ -55,7 +55,8 @@ public class AdapterServiceBuilder exten
         String changed = srvMeta.getString(Params.changed, null);
         String removed = srvMeta.getString(Params.removed, null);
         String swap = srvMeta.getString(Params.swap, null);
-
+        boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "true"));
+        
         if (field != null && (added != null || changed != null || removed != null || swap != null))
         {
             throw new IllegalArgumentException("autoconfig field " + field + " can't be defined with both added/changed/removed/swap calllbacks");
@@ -65,18 +66,18 @@ public class AdapterServiceBuilder exten
         
         if (field != null)
         {
-            c = dm.createAdapterService(adapteeService, adapteeFilter, field);
+            c = dm.createAdapterService(adapteeService, adapteeFilter, field, null, null, null, null, null, propagate);
         }
         else
         {
             if (added != null || changed != null || removed != null || swap != null)
             {
-                c = dm.createAdapterService(adapteeService, adapteeFilter, added, changed, removed, swap);
+                c = dm.createAdapterService(adapteeService, adapteeFilter, null, null, added, changed, removed, swap, propagate);
 
             }
             else
             {
-                c = dm.createAdapterService(adapteeService, adapteeFilter);
+                c = dm.createAdapterService(adapteeService, adapteeFilter, null, null, null, null, null, null, propagate);
             }
         }
         

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java?rev=1635622&r1=1635621&r2=1635622&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java Thu Oct 30 21:37:01 2014
@@ -267,12 +267,22 @@ public abstract class DependencyActivato
      * @return the adapter service
      * @see DependencyManager#createAdapterService(Class, String, String, Object, String, String, String, String)
      */
-   public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, 
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, 
         String autoConfig, Object callbackInstance, String add, String change, String remove, String swap) {
-       return m_manager.createAdapterService(serviceInterface, serviceFilter, autoConfig, callbackInstance, add, change, remove, swap);
+       return m_manager.createAdapterService(serviceInterface, serviceFilter, autoConfig, callbackInstance, add, change, remove, swap, true);
     }
 
     /**
+     * Creates a new adapter service.
+     * @return the adapter service
+     * @see DependencyManager#createAdapterService(Class, String, String, Object, String, String, String, String, boolean)
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, 
+        String autoConfig, Object callbackInstance, String add, String change, String remove, String swap, boolean propagate) {
+       return m_manager.createAdapterService(serviceInterface, serviceFilter, autoConfig, callbackInstance, add, change, remove, swap, propagate);
+    }
+
+   /**
      * Creates a new resource adapter service.
      * 
      * @return the resource adapter service

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java?rev=1635622&r1=1635621&r2=1635622&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java Thu Oct 30 21:37:01 2014
@@ -263,7 +263,7 @@ public class DependencyManager {    
      * @return a service that acts as a factory for generating adapters
      */
     public Component createAdapterService(Class<?> serviceInterface, String serviceFilter) {
-        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, null, null, null, null);
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, null, null, null, null, true);
     }
 
     /**
@@ -289,7 +289,7 @@ public class DependencyManager {    
      * @return a service that acts as a factory for generating adapters
      */
     public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String autoConfig) {
-        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, null, null, null, null, null);
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, null, null, null, null, null, true);
     }
 
     /**
@@ -319,7 +319,7 @@ public class DependencyManager {    
     public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String add, String change,
         String remove)
     {
-        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, add, change, remove, null);
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, add, change, remove, null, true);
     }
 
     /**
@@ -350,15 +350,15 @@ public class DependencyManager {    
     public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String add, String change,
         String remove, String swap)
     {
-        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, add, change, remove, swap);
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, add, change, remove, swap, true);
     }
 
     /**
      * Creates a new adapter. The adapter will be applied to any service that
      * matches the specified interface and filter. For each matching service
      * an adapter will be created based on the adapter implementation class.
-     * The adapter will be registered with the specified interface and existing properties
-     * from the original service plus any extra properties you supply here.
+     * The adapter will be registered with the specified interface (and existing properties
+     * from the original service if you set the propagate flag) plus any extra properties you supply here.
      * It will also inherit all dependencies, and if you declare the original
      * service as a member it will be injected.
      * 
@@ -378,12 +378,14 @@ public class DependencyManager {    
      * @param change name of the callback method to invoke on change
      * @param remove name of the callback method to invoke on remove
      * @param swap name of the callback method to invoke on swap
+     * @param propagate true if the adaptee service properties should be propagated to the adapter service consumers
      * @return a service that acts as a factory for generating adapters
      */
     public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, 
-        String autoConfig, Object callbackInstance, String add, String change, String remove, String swap)
+        String autoConfig, Object callbackInstance, String add, String change, String remove, 
+        String swap, boolean propagate)
     {
-        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, callbackInstance, add, change, remove, swap);
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, callbackInstance, add, change, remove, swap, propagate);
     }
 
     /**

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java?rev=1635622&r1=1635621&r2=1635622&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java Thu Oct 30 21:37:01 2014
@@ -51,12 +51,14 @@ public class AdapterServiceImpl extends 
      * @param change name of the callback method to invoke on change
      * @param remove name of the callback method to invoke on remove
      * @param swap name of the callback method to invoke on swap
+     * @param propagate true if the adaptee service properties should be propagated to the adapter service consumers
      */
     public AdapterServiceImpl(DependencyManager dm, Class<?> adapteeInterface, String adapteeFilter, String autoConfig, 
-        Object callbackInstance, String add, String change, String remove, String swap)
+        Object callbackInstance, String add, String change, String remove, String swap, boolean propagate)
     {
         super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
-        m_component.setImplementation(new AdapterImpl(adapteeInterface, adapteeFilter, autoConfig, callbackInstance, add, change, remove, swap))
+        m_component.setImplementation(new AdapterImpl(adapteeInterface, adapteeFilter, autoConfig, callbackInstance, add, 
+            change, remove, swap, propagate))
                  .add(dm.createServiceDependency()
                       .setService(adapteeInterface, adapteeFilter)
                       .setAutoConfig(false)
@@ -73,8 +75,10 @@ public class AdapterServiceImpl extends 
         private final String m_remove;
         private final String m_swap;
         private final String m_autoConfig;
+        private final boolean m_propagate;
         
-        public AdapterImpl(Class<?> adapteeInterface, String adapteeFilter, String autoConfig, Object callbackInstance, String add, String change, String remove, String swap) {
+        public AdapterImpl(Class<?> adapteeInterface, String adapteeFilter, String autoConfig, Object callbackInstance, String add, 
+            String change, String remove, String swap, boolean propagate) {
             m_adapteeInterface = adapteeInterface;
             m_adapteeFilter = adapteeFilter;
             m_autoConfig = autoConfig;
@@ -83,6 +87,7 @@ public class AdapterServiceImpl extends 
             m_change = change;
             m_swap = swap;
             m_remove = remove;
+            m_propagate = propagate;
         }
         
         public Component createService(Object[] properties) {
@@ -105,7 +110,10 @@ public class AdapterServiceImpl extends 
                 // enable auto configuration if there is no add callback or if there is one on a callbackInstance
                 dependency.setAutoConfig(m_add == null || (m_add != null && m_dependencyCallbackInstance != null));
             }
-            dependency.setPropagate(this, "propagateAdapteeProperties");
+            
+            if (m_propagate) {
+                dependency.setPropagate(this, "propagateAdapteeProperties");
+            }
             
 //            dependency.setDebug("AdapterDependency#" + m_adapteeInterface.getSimpleName());