Fixed bug in discovering JVM loaded case classes during code generation 46/3846/1
authorTony Tkacik <ttkacik@cisco.com>
Thu, 19 Dec 2013 11:15:18 +0000 (12:15 +0100)
committerTony Tkacik <ttkacik@cisco.com>
Thu, 19 Dec 2013 11:15:18 +0000 (12:15 +0100)
  - Added debug logging
       - routing table updates
       - rpc router creation, non-routed service registration
         proxy instantiation.

Change-Id: Iab0ad7451382ab8179cff2febf17c19e96daf464
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RuntimeCodeGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/XtendHelper.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java

index 48c33ad..c46b0dd 100644 (file)
@@ -36,7 +36,7 @@ public final class BindingBrokerImplModule extends org.opendaylight.controller.c
 \r
     @Override\r
     public java.lang.AutoCloseable createInstance() {\r
-        BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getBundleContext());\r
+        BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getIdentifier().getInstanceName(),getBundleContext());\r
         broker.setDataBroker(getDataBrokerDependency());\r
         broker.setNotifyBroker(getNotificationServiceDependency());\r
         broker.start();\r
index 6672d95..7789a06 100644 (file)
@@ -86,7 +86,7 @@ public interface RuntimeCodeGenerator {
      * @return Instance of RpcService of provided serviceType which implements
      *         also {@link RpcRouter}<T> and {@link DelegateProxy}
      */
-    <T extends RpcService> RpcRouter<T> getRouterFor(Class<T> serviceType) throws IllegalArgumentException;
+    <T extends RpcService> RpcRouter<T> getRouterFor(Class<T> serviceType,String name) throws IllegalArgumentException;
 
     NotificationInvokerFactory getInvokerFactory();
 }
index 780d0bd..8b2db8b 100644 (file)
@@ -45,16 +45,23 @@ public class RpcRouterCodegenInstance<T extends RpcService> implements //
 
     private final Map<Class<? extends BaseIdentity>, RpcRoutingTableImpl<? extends BaseIdentity, T>> routingTables;
 
-    public RpcRouterCodegenInstance(Class<T> type, T routerImpl, Set<Class<? extends BaseIdentity>> contexts,
+    private final String name;
+
+    @SuppressWarnings("unchecked")
+    public RpcRouterCodegenInstance(String name,Class<T> type, T routerImpl, Set<Class<? extends BaseIdentity>> contexts,
             Set<Class<? extends DataContainer>> inputs) {
+        this.name = name;
         this.listeners = ListenerRegistry.create();
         this.serviceType = type;
         this.invocationProxy = routerImpl;
         this.contexts = ImmutableSet.copyOf(contexts);
         Map<Class<? extends BaseIdentity>, RpcRoutingTableImpl<? extends BaseIdentity, T>> mutableRoutingTables = new HashMap<>();
         for (Class<? extends BaseIdentity> ctx : contexts) {
-            RpcRoutingTableImpl<? extends BaseIdentity, T> table = new RpcRoutingTableImpl<>(ctx);
+            RpcRoutingTableImpl<? extends BaseIdentity, T> table = new RpcRoutingTableImpl<>(name,ctx,type);
+            
+            @SuppressWarnings("rawtypes")
             Map invokerView = table.getRoutes();
+            
             setRoutingTable((RpcService) invocationProxy, ctx, invokerView);
             mutableRoutingTables.put(ctx, table);
             table.registerRouteChangeListener(this);
index f959235..808358f 100644 (file)
@@ -15,8 +15,11 @@ import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublishe
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
 import org.opendaylight.controller.md.sal.common.impl.routing.RoutingUtils;
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Mutable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 class RpcRoutingTableImpl<C extends BaseIdentity, S extends RpcService> //
 implements //
@@ -24,16 +27,22 @@ implements //
         RpcRoutingTable<C, S>, //
         RouteChangePublisher<Class<? extends BaseIdentity>, InstanceIdentifier<?>> {
 
-    private final Class<C> identifier;
+    private static final Logger LOGGER = LoggerFactory.getLogger(RpcRoutingTableImpl.class);
+    private final String routerName;
+    private final Class<S> serviceType;
+
+    private final Class<C> contextType;
     private final ConcurrentMap<InstanceIdentifier<?>, S> routes;
     private final Map<InstanceIdentifier<?>, S> unmodifiableRoutes;
 
     private RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>> listener;
     private S defaultRoute;
-
-    public RpcRoutingTableImpl(Class<C> identifier) {
+    
+    public RpcRoutingTableImpl(String routerName,Class<C> contextType, Class<S> serviceType) {
         super();
-        this.identifier = identifier;
+        this.routerName = routerName;
+        this.serviceType = serviceType;
+        this.contextType = contextType;
         this.routes = new ConcurrentHashMap<>();
         this.unmodifiableRoutes = Collections.unmodifiableMap(routes);
     }
@@ -56,17 +65,19 @@ implements //
         
     @Override
     public Class<C> getIdentifier() {
-        return identifier;
+        return contextType;
     }
 
     @Override
     @SuppressWarnings("unchecked")
     public void updateRoute(InstanceIdentifier<?> path, S service) {
         S previous = this.routes.put(path, service);
+        
+        LOGGER.debug("Route {} updated to {} in routing table {}",path,service,this);
         @SuppressWarnings("rawtypes")
         RouteChangeListener listenerCapture = listener;
         if (previous == null && listenerCapture != null) {
-            listenerCapture.onRouteChange(RoutingUtils.announcementChange(identifier, path));
+            listenerCapture.onRouteChange(RoutingUtils.announcementChange(contextType, path));
         }
     }
 
@@ -75,10 +86,11 @@ implements //
     @SuppressWarnings("unchecked")
     public void removeRoute(InstanceIdentifier<?> path) {
         S previous = this.routes.remove(path);
+        LOGGER.debug("Route {} to {} removed in routing table {}",path,previous,this);
         @SuppressWarnings("rawtypes")
         RouteChangeListener listenerCapture = listener;
         if (previous != null && listenerCapture != null) {
-            listenerCapture.onRouteChange(RoutingUtils.removalChange(identifier, path));
+            listenerCapture.onRouteChange(RoutingUtils.removalChange(contextType, path));
         }
     }
     
@@ -86,7 +98,8 @@ implements //
         @SuppressWarnings("rawtypes")
         RouteChangeListener listenerCapture = listener;
         if (routes.remove(path, service) && listenerCapture != null) {
-            listenerCapture.onRouteChange(RoutingUtils.removalChange(identifier, path));
+            LOGGER.debug("Route {} to {} removed in routing table {}",path,service,this);
+            listenerCapture.onRouteChange(RoutingUtils.removalChange(contextType, path));
         }
     }
 
@@ -107,6 +120,16 @@ implements //
     protected void removeAllReferences(S service) {
         
     }
+    
+    
+
+    @Override
+    public String toString() {
+        return "RpcRoutingTableImpl [router=" + routerName + ", service=" + serviceType.getSimpleName() + ", context="
+                + contextType.getSimpleName() + "]";
+    }
+
+
 
     private class SingletonListenerRegistration<L extends RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>>> extends
             AbstractObjectRegistration<L>
index 8b41552..d9e0983 100644 (file)
@@ -91,7 +91,7 @@ class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.co
         return instance;
     }
 
-    override <T extends RpcService> getRouterFor(Class<T> iface) {
+    override <T extends RpcService> getRouterFor(Class<T> iface,String routerInstanceName) {
         val metadata = withClassLoader(iface.classLoader) [|
             val supertype = iface.asCtClass
             return supertype.rpcMetadata;
@@ -148,7 +148,7 @@ class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.co
             return targetCls.toClass(iface.classLoader,iface.protectionDomain).newInstance as T
             
         ];
-        return new RpcRouterCodegenInstance(iface, instance, metadata.contexts,metadata.supportedInputs);
+        return new RpcRouterCodegenInstance(routerInstanceName,iface, instance, metadata.contexts,metadata.supportedInputs);
     }
 
     private def RpcServiceMetadata getRpcMetadata(CtClass iface) {
index 588bc78..ca1b634 100644 (file)
@@ -9,11 +9,6 @@ import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
 
 public class XtendHelper {
 
-    public static <C extends BaseIdentity> RpcRoutingTableImpl createRoutingTable(
-            Class<C> cls) {
-        return new RpcRoutingTableImpl<>(cls);
-    }
-
     @SuppressWarnings({"rawtypes","unchecked"})
     public static Iterable<TypeDefinition> getTypes(UnionTypeDefinition definition) {
         return (Iterable<TypeDefinition>) (List) definition.getTypes();
index e5bd3e7..5bc2d70 100644 (file)
@@ -145,9 +145,13 @@ class TransformerGenerator {
             if (typeSpecBuilder == null) {
                 typeSpecBuilder = pathToType.get(node.path);
             }
+            var schemaNode = typeToSchemaNode.get(ref);
+            if(schemaNode === null) {
+                schemaNode = node;
+            }
             checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
             val typeSpec = typeSpecBuilder.toInstance();
-            val newret = generateTransformerFor(inputType, typeSpec, node);
+            val newret = generateTransformerFor(inputType, typeSpec, schemaNode);
             listener.onClassProcessed(inputType);
             return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
         ]
@@ -524,7 +528,7 @@ class TransformerGenerator {
                             return null;
                             }
                             java.util.Map _compositeNode = (java.util.Map) $2;
-                            ////System.out.println(_localQName + " " + _compositeNode);
+                            System.out.println(_localQName + " " + _compositeNode);
                             «type.builderName» _builder = new «type.builderName»();
                             boolean _is_empty = true;
                             «FOR child : node.childNodes»
@@ -672,6 +676,7 @@ class TransformerGenerator {
                 return null;
             }
             java.util.Map _compositeNode = (java.util.Map) $2;
+            System.out.println(_localQName + " " + _compositeNode);
             «type.builderName» _builder = new «type.builderName»();
             «deserializeKey(type, node)»
             «deserializeDataNodeContainerBody(type, node)»
@@ -687,6 +692,7 @@ class TransformerGenerator {
                 return null;
             }
             java.util.Map _compositeNode = (java.util.Map) $2;
+            System.out.println(_localQName + " " + _compositeNode);
             «type.builderName» _builder = new «type.builderName»();
             «deserializeDataNodeContainerBody(type, node)»
             «deserializeAugmentations»
@@ -702,7 +708,7 @@ class TransformerGenerator {
                 return null;
             }
             java.util.Map _compositeNode = (java.util.Map) $2;
-            ////System.out.println(_localQName + " " + _compositeNode);
+            System.out.println(_localQName + " " + _compositeNode);
             «type.builderName» _builder = new «type.builderName»();
             «deserializeDataNodeContainerBody(type, node)»
             «deserializeAugmentations»
index 8d3545f..b4bf3f5 100644 (file)
@@ -9,47 +9,16 @@ package org.opendaylight.controller.sal.binding.impl
 
 import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider
-import org.opendaylight.yangtools.yang.binding.RpcService
-import javassist.ClassPool
 import org.osgi.framework.BundleContext
-import java.util.Map
-import javassist.LoaderClassPath
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
-import java.util.Hashtable
-import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.*
-
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService
-import org.osgi.framework.ServiceRegistration
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*
-import static extension org.opendaylight.controller.sal.binding.impl.osgi.PropertiesUtils.*
-import org.opendaylight.controller.sal.binding.api.NotificationService
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-
-import org.slf4j.LoggerFactory
-import org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
-import org.opendaylight.controller.sal.binding.spi.RpcRouter
-import java.util.concurrent.ConcurrentHashMap
-import static com.google.common.base.Preconditions.*
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
-import org.opendaylight.yangtools.yang.binding.BaseIdentity
-import com.google.common.collect.Multimap
-import com.google.common.collect.HashMultimap
-import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*
-import java.util.concurrent.Executors
-import java.util.Collections
 import org.opendaylight.yangtools.yang.binding.DataObject
-import java.util.concurrent.locks.ReentrantLock
-import java.util.concurrent.Callable
-import java.util.WeakHashMap
-import javax.annotation.concurrent.GuardedBy
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry
-import org.opendaylight.yangtools.concepts.ListenerRegistration
-import org.opendaylight.yangtools.concepts.util.ListenerRegistry
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener
+import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.slf4j.LoggerFactory
 
 class BindingAwareBrokerImpl extends RpcProviderRegistryImpl implements BindingAwareBroker, AutoCloseable {
     private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl)
@@ -65,7 +34,8 @@ class BindingAwareBrokerImpl extends RpcProviderRegistryImpl implements BindingA
     @Property
     var BundleContext brokerBundleContext
 
-    public new(BundleContext bundleContext) {
+    public new(String name,BundleContext bundleContext) {
+        super(name);
         _brokerBundleContext = bundleContext;
     }
 
@@ -95,9 +65,12 @@ class BindingAwareBrokerImpl extends RpcProviderRegistryImpl implements BindingA
     private def createContext(BindingAwareProvider provider, BundleContext providerCtx) {
         new OsgiProviderContext(providerCtx, this)
     }
+
+    override <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> registerRouteChangeListener(L listener) {
+        super.<L>registerRouteChangeListener(listener)
+    }
     
     override close() throws Exception {
         
     }
-
 }
\ No newline at end of file
index bc86288..6a17007 100644 (file)
@@ -27,6 +27,8 @@ import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import static com.google.common.base.Preconditions.*;
 
@@ -41,6 +43,19 @@ public class RpcProviderRegistryImpl implements //
     private final ListenerRegistry<RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> routeChangeListeners = ListenerRegistry
             .create();
 
+    private final static Logger LOG = LoggerFactory.getLogger(RpcProviderRegistryImpl.class);
+    
+    private final String name;
+
+    public String getName() {
+        return name;
+    }
+
+    public RpcProviderRegistryImpl(String name) {
+        super();
+        this.name = name;
+    }
+
     @Override
     public final <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type,
             T implementation) throws IllegalStateException {
@@ -50,6 +65,7 @@ public class RpcProviderRegistryImpl implements //
     @Override
     public final <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
             throws IllegalStateException {
+        @SuppressWarnings("unchecked")
         RpcRouter<T> potentialRouter = (RpcRouter<T>) rpcRouters.get(type);
         if (potentialRouter != null) {
             checkState(potentialRouter.getDefaultService() == null,
@@ -59,20 +75,35 @@ public class RpcProviderRegistryImpl implements //
         T publicProxy = getRpcService(type);
         RpcService currentDelegate = RuntimeCodeHelper.getDelegate(publicProxy);
         checkState(currentDelegate == null, "Rpc service is already registered");
+        LOG.debug("Registering {} as global implementation of {} in {}",implementation,type.getSimpleName(),this);
         RuntimeCodeHelper.setDelegate(publicProxy, implementation);
         return new RpcProxyRegistration<T>(type, implementation, this);
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public final <T extends RpcService> T getRpcService(Class<T> type) {
 
-        RpcService potentialProxy = publicProxies.get(type);
+        @SuppressWarnings("unchecked")
+        T potentialProxy = (T) publicProxies.get(type);
         if (potentialProxy != null) {
-            return (T) potentialProxy;
+            return potentialProxy;
+        }
+        synchronized(this) {
+            /**
+             * Potential proxy could be instantiated by other thread while we were
+             * waiting for the lock.
+             */
+            
+            potentialProxy = (T) publicProxies.get(type);
+            if (potentialProxy != null) {
+                return (T) potentialProxy;
+            }
+            T proxy = rpcFactory.getDirectProxyFor(type);
+            LOG.debug("Created {} as public proxy for {} in {}",proxy,type.getSimpleName(),this);
+            publicProxies.put(type, proxy);
+            return proxy;
         }
-        T proxy = rpcFactory.getDirectProxyFor(type);
-        publicProxies.put(type, proxy);
-        return proxy;
     }
 
     private <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
@@ -80,13 +111,25 @@ public class RpcProviderRegistryImpl implements //
         if (potentialRouter != null) {
             return (RpcRouter<T>) potentialRouter;
         }
-        RpcRouter<T> router = rpcFactory.getRouterFor(type);
-        router.registerRouteChangeListener(new RouteChangeForwarder(type));
-        RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy());
-        rpcRouters.put(type, router);
-        return router;
+        synchronized(this) {
+            /**
+             * Potential Router could be instantiated by other thread while we were
+             * waiting for the lock.
+             */
+            potentialRouter = rpcRouters.get(type); 
+            if (potentialRouter != null) {
+                return (RpcRouter<T>) potentialRouter;
+            }
+            RpcRouter<T> router = rpcFactory.getRouterFor(type,name);
+            router.registerRouteChangeListener(new RouteChangeForwarder(type));
+            LOG.debug("Registering router {} as global implementation of {} in {}",router,type.getSimpleName(),this);
+            RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy());
+            rpcRouters.put(type, router);
+            return router;
+        }
     }
 
+    @Override
     public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
             L listener) {
         return (ListenerRegistration<L>) routeChangeListeners.register(listener);
index 9c9841a..6f0db4c 100644 (file)
@@ -61,7 +61,7 @@ public class RuntimeCodeGeneratorTest {
 
     @Test
     public void testGenerateRouter() throws Exception {
-        RpcRouter<FooService> product = codeGenerator.getRouterFor(FooService.class);
+        RpcRouter<FooService> product = codeGenerator.getRouterFor(FooService.class,"test");
         assertNotNull(product);
         assertNotNull(product.getInvocationProxy());
 
index 3217a31..d4d27a1 100644 (file)
@@ -110,7 +110,7 @@ public class BindingTestContext implements AutoCloseable {
         checkState(executor != null,"Executor needs to be set");
         checkState(baDataImpl != null,"Binding Data Broker must be started");
         checkState(baNotifyImpl != null, "Notification Service must be started");
-        baBrokerImpl = new BindingAwareBrokerImpl(null);
+        baBrokerImpl = new BindingAwareBrokerImpl("test",null);
         
         baBrokerImpl.setDataBroker(baDataImpl);
         baBrokerImpl.setNotifyBroker(baNotifyImpl);