Fix RPC forwarding related bugs in Binding Independent Connector
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / sal / binding / impl / connect / dom / BindingIndependentConnector.java
index 1d6c271f9f4d0188a594ae603437d566585f583a..aaed12f740ea7224c540fdc936f544308ccb1a3e 100644 (file)
@@ -42,6 +42,8 @@ import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
 import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
 import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.GlobalRpcRegistrationListener;
 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.RouterInstantiationListener;
@@ -87,6 +89,8 @@ public class BindingIndependentConnector implements //
         Provider, //
         AutoCloseable {
 
+
+
     private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
 
     @SuppressWarnings( "deprecation")
@@ -96,8 +100,8 @@ public class BindingIndependentConnector implements //
             .builder().toInstance();
 
     private final static Method EQUALS_METHOD;
-    
-    
+
+
     private BindingIndependentMappingService mappingService;
 
     private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
@@ -141,8 +145,8 @@ public class BindingIndependentConnector implements //
     private RpcProviderRegistryImpl baRpcRegistryImpl;
 
     private org.opendaylight.controller.sal.dom.broker.spi.RpcRouter biRouter;
-    
-    
+
+
     static {
         try {
         EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
@@ -451,18 +455,18 @@ public class BindingIndependentConnector implements //
             }
             DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
             BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
-            LOG.info("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
+            LOG.trace("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
                     domTransaction.getIdentifier());
             return wrapped;
         }
     }
 
     private class DomToBindingCommitHandler implements //
-            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject>>, //
+            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>>, //
             DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
 
         @Override
-        public void onRegister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
+        public void onRegister(DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
 
             org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration
                     .getPath());
@@ -470,7 +474,7 @@ public class BindingIndependentConnector implements //
         }
 
         @Override
-        public void onUnregister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
+        public void onUnregister(DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
             // NOOP for now
             // FIXME: do registration based on only active commit handlers.
         }
@@ -491,7 +495,7 @@ public class BindingIndependentConnector implements //
 
             org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
             DomToBindingTransaction forwardedTransaction = new DomToBindingTransaction(baTransaction, domTransaction);
-            LOG.info("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
+            LOG.trace("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
                     baTransaction.getIdentifier());
             return forwardedTransaction;
         }
@@ -500,7 +504,7 @@ public class BindingIndependentConnector implements //
     /**
      * Manager responsible for instantiating forwarders responsible for
      * forwarding of RPC invocations from DOM Broker to Binding Aware Broker
-     * 
+     *
      */
     private class DomToBindingRpcForwardingManager implements
             RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>,
@@ -517,17 +521,17 @@ public class BindingIndependentConnector implements //
         public void setRegistryImpl(RpcProviderRegistryImpl registryImpl) {
             this.registryImpl = registryImpl;
         }
-        
+
         @Override
         public void onGlobalRpcRegistered(Class<? extends RpcService> cls) {
             getRpcForwarder(cls, null);
         }
-        
+
         @Override
         public void onGlobalRpcUnregistered(Class<? extends RpcService> cls) {
             // NOOP
         }
-        
+
         @Override
         public void onRpcRouterCreated(RpcRouter<?> router) {
             Class<? extends BaseIdentity> ctx = router.getContexts().iterator().next();
@@ -587,14 +591,14 @@ public class BindingIndependentConnector implements //
                 }
 
             } catch (Exception e) {
-                LOG.error("Could not forward Rpcs of type {}", service.getName());
+                LOG.error("Could not forward Rpcs of type {}", service.getName(),e);
             }
             registrations = ImmutableSet.of();
         }
 
         /**
          * Constructor for Routed RPC Forwareder.
-         * 
+         *
          * @param service
          * @param context
          */
@@ -628,7 +632,7 @@ public class BindingIndependentConnector implements //
             }
         }
 
-        
+
         @Override
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
             if(EQUALS_METHOD.equals(method)) {
@@ -666,7 +670,7 @@ public class BindingIndependentConnector implements //
                 Class<?> cls = rpcServiceType.get();
                 ClassLoader clsLoader = cls.getClassLoader();
                 RpcService proxy = (RpcService) Proxy.newProxyInstance(clsLoader, new Class<?>[] { cls }, this);
-                
+
                 RpcRouter rpcRouter = baRpcRegistryImpl.getRpcRouter(rpcServiceType.get());
                 rpcRouter.registerDefaultService(proxy);
             }
@@ -719,8 +723,10 @@ public class BindingIndependentConnector implements //
                         } else {
                             strategy = new NoInputNoOutputInvocationStrategy(rpc,targetMethod);
                         }
+                    } else if(inputClass.isPresent()){
+                        strategy = new NoOutputInvocationStrategy(rpc,targetMethod, inputClass.get());
                     } else {
-                        strategy = null;
+                        strategy = new NoInputNoOutputInvocationStrategy(rpc,targetMethod);
                     }
                     return strategy;
                 }
@@ -775,10 +781,10 @@ public class BindingIndependentConnector implements //
             RpcResult<?> bindingResult = result.get();
             return Rpcs.getRpcResult(true);
         }
-        
+
         @Override
         public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
-            if(biRouter != null) { 
+            if(biRouter != null) {
                 CompositeNode xml = mappingService.toDataDom(input);
                 CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
                 RpcResult<CompositeNode> result = biRouter.invokeRpc(rpc, wrappedXml);
@@ -806,12 +812,52 @@ public class BindingIndependentConnector implements //
             RpcResult<Void> bindingResult = result.get();
             return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors());
         }
-        
+
         @Override
         public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
             return Futures.immediateFuture(null);
         }
     }
+    
+    private class NoOutputInvocationStrategy extends RpcInvocationStrategy {
+
+        
+        @SuppressWarnings("rawtypes")
+        private WeakReference<Class> inputClass;
+
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        public NoOutputInvocationStrategy(QName rpc, Method targetMethod, 
+                Class<? extends DataContainer> inputClass) {
+            super(rpc,targetMethod);
+            this.inputClass = new WeakReference(inputClass);
+        }
+        
+        
+        @Override
+        public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
+            DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
+            Future<RpcResult<?>> result = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
+            if (result == null) {
+                return Rpcs.getRpcResult(false);
+            }
+            RpcResult<?> bindingResult = result.get();
+            return Rpcs.getRpcResult(true);
+        }
+
+        @Override
+        public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
+            if(biRouter != null) {
+                CompositeNode xml = mappingService.toDataDom(input);
+                CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
+                RpcResult<CompositeNode> result = biRouter.invokeRpc(rpc, wrappedXml);
+                Object baResultValue = null;
+                RpcResult<?> baResult = Rpcs.<Void>getRpcResult(result.isSuccessful(), null, result.getErrors());
+                return Futures.<RpcResult<?>>immediateFuture(baResult);
+            }
+            return Futures.<RpcResult<?>>immediateFuture(Rpcs.getRpcResult(false));
+        }
+
+    }
 
     public boolean isRpcForwarding() {
         return rpcForwarding;
@@ -822,7 +868,6 @@ public class BindingIndependentConnector implements //
     }
 
     public boolean isNotificationForwarding() {
-        // TODO Auto-generated method stub
         return notificationForwarding;
     }