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/08/27 10:56:22 UTC

svn commit: r1620818 - /felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/DynamicProxyAspectTest.java

Author: pderop
Date: Wed Aug 27 08:56:22 2014
New Revision: 1620818

URL: http://svn.apache.org/r1620818
Log:
Ported this missing test from old DM codebase.

Added:
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/DynamicProxyAspectTest.java

Added: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/DynamicProxyAspectTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/DynamicProxyAspectTest.java?rev=1620818&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/DynamicProxyAspectTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/DynamicProxyAspectTest.java Wed Aug 27 08:56:22 2014
@@ -0,0 +1,193 @@
+/**
+ * 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.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import junit.framework.Assert;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+public class DynamicProxyAspectTest extends TestBase {
+    public void testImplementGenericAspectWithDynamicProxy() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create two service providers, each providing a different service interface
+        Component sp1 = m.createComponent().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
+        Component sp2 = m.createComponent().setImplementation(new ServiceProvider2(e)).setInterface(ServiceInterface2.class.getName(), null);
+        
+        // create a dynamic proxy based aspect and hook it up to both services
+        Component a1 = m.createAspectService(ServiceInterface.class, null, 10, "m_service")
+            .setFactory(new Factory(e, ServiceInterface.class, "ServiceInterfaceProxy"), "create");
+        Component a2 = m.createAspectService(ServiceInterface2.class, null, 10, "m_service")
+            .setFactory(new Factory(e, ServiceInterface2.class, "ServiceInterfaceProxy2"), "create");
+
+        // create a client that invokes a method on boths services, validate that it goes
+        // through the proxy twice
+        Component sc = m.createComponent()
+            .setImplementation(new ServiceConsumer(e))
+            .add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true))
+            .add(m.createServiceDependency().setService(ServiceInterface2.class).setRequired(true))
+            ;
+        
+        // register both producers, validate that both services are started
+        m.add(sp1);
+        e.waitForStep(1, 2000);
+        m.add(sp2);
+        e.waitForStep(2, 2000);
+        
+        // add both aspects, and validate that both instances have been created
+        m.add(a1);
+        m.add(a2);
+        e.waitForStep(4, 4000);
+        
+        // add the client, which will automatically invoke both services
+        m.add(sc);
+        
+        // wait until both services have been invoked
+        e.waitForStep(6, 4000);
+        
+        // make sure the proxy has been called twice
+        Assert.assertEquals("Proxy should have been invoked this many times.", 2, DynamicProxyHandler.getCounter());
+        
+        m.remove(sc);
+        m.remove(a2);
+        m.remove(a1);
+        m.remove(sp2);
+        m.remove(sp1);
+        m.remove(a2);
+        m.remove(a1);
+        
+        try {
+            Thread.sleep(2000);
+        }
+        catch (InterruptedException e1) {
+            // TODO Auto-generated catch block
+            e1.printStackTrace();
+        }
+    }
+    
+    static interface ServiceInterface {
+        public void invoke(Runnable run);
+    }
+    
+    static interface ServiceInterface2 {
+        public void invoke(Runnable run);
+    }
+    
+    static class ServiceProvider implements ServiceInterface {
+        private final Ensure m_ensure;
+        public ServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+        public void start() {
+            m_ensure.step(1);
+        }
+        public void invoke(Runnable run) {
+            run.run();
+        }
+    }
+    
+    static class ServiceProvider2 implements ServiceInterface2 {
+        private final Ensure m_ensure;
+        public ServiceProvider2(Ensure ensure) {
+            m_ensure = ensure;
+        }
+        public void start() {
+            m_ensure.step(2);
+        }
+        public void invoke(Runnable run) {
+            run.run();
+        }
+    }
+    
+    static class ServiceConsumer implements Runnable {
+        private volatile ServiceInterface m_service;
+        private volatile ServiceInterface2 m_service2;
+        private final Ensure m_ensure;
+
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void init() {
+            Thread t = new Thread(this);
+            t.start();
+        }
+        
+        public void run() {
+            m_service.invoke(Ensure.createRunnableStep(m_ensure, 5));
+            m_service2.invoke(Ensure.createRunnableStep(m_ensure, 6));
+        }
+    }
+    
+    static class DynamicProxyHandler implements InvocationHandler {
+        public volatile Object m_service; // ISSUE, we cannot inject into "Object" at the moment
+        private final String m_label;
+        private static volatile int m_counter = 0;
+
+        public DynamicProxyHandler(String label) {
+            m_label = label;
+        }
+
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            System.out.println("IIIIIIINVOKE--------------------------" + method.getName());
+            if (m_service == null) {
+                Assert.fail("No service was injected into dynamic proxy handler " + m_label);
+            }
+            Method m = m_service.getClass().getMethod(method.getName(), method.getParameterTypes());
+            if (m == null) {
+                Assert.fail("No method " + method.getName() + " was found in instance " + m_service + " in dynamic proxy handler " + m_label);
+            }
+            if (method.getName().equals("invoke")) {
+                // only count methods called 'invoke' because those are actually the ones
+                // both interfaces implement (and the dynamic proxy might be invoked for
+                // other methods, such as toString() as well)
+                m_counter++;
+            }
+            return m.invoke(m_service, args);
+        }
+        
+        public static int getCounter() {
+            return m_counter;
+        }
+    }
+    
+    static class Factory {
+        private final String m_label;
+        private Class m_class;
+        private final Ensure m_ensure;
+        
+        public Factory(Ensure ensure, Class clazz, String label) {
+            m_ensure = ensure;
+            m_class = clazz;
+            m_label = label;
+        }
+        
+        public Object create() {
+            m_ensure.step();
+            return Proxy.newProxyInstance(m_class.getClassLoader(), new Class[] { m_class }, new DynamicProxyHandler(m_label));
+        }
+    }
+}