X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fimpl%2Fconnect%2Fdom%2FBindingIndependentConnector.java;h=fe8c4a151c1691495ea4e5f00bf443b77878d930;hp=e48ebbc0577f1b6101a772284ba9e07b3e6580cf;hb=b15ad095a13977fad81fabd266cb5d832164d3a7;hpb=2e7347fdc0eb7734ff59a4f902227a93ab6afece diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java index e48ebbc057..fe8c4a151c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java @@ -28,13 +28,13 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import org.opendaylight.controller.md.sal.binding.impl.AbstractForwardedDataBroker; import org.opendaylight.controller.md.sal.common.api.RegistrationListener; import org.opendaylight.controller.md.sal.common.api.TransactionStatus; import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler; import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction; import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration; import org.opendaylight.controller.md.sal.common.api.data.DataModification; -import org.opendaylight.controller.md.sal.common.api.data.DataReader; import org.opendaylight.controller.md.sal.common.api.routing.RouteChange; import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher; @@ -45,6 +45,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.controller.sal.binding.impl.DataBrokerImpl; +import org.opendaylight.controller.sal.binding.impl.MountPointManagerImpl.BindingMountPointImpl; 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; @@ -55,12 +57,15 @@ import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration; import org.opendaylight.controller.sal.core.api.Provider; import org.opendaylight.controller.sal.core.api.RpcImplementation; import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; +import org.opendaylight.controller.sal.core.api.RpcRegistrationListener; import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction; import org.opendaylight.controller.sal.core.api.notify.NotificationListener; import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService; +import org.opendaylight.yangtools.concepts.CompositeObjectRegistration; +import org.opendaylight.yangtools.concepts.CompositeObjectRegistration.CompositeObjectRegistrationBuilder; import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.ObjectRegistration; import org.opendaylight.yangtools.concepts.Registration; -import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils; import org.opendaylight.yangtools.yang.binding.Augmentable; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.BaseIdentity; @@ -71,12 +76,11 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.Notification; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.binding.util.BindingReflections; +import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.Node; -import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; import org.slf4j.Logger; @@ -85,23 +89,18 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; public class BindingIndependentConnector implements // RuntimeDataProvider, // Provider, // AutoCloseable { - - private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class); - @SuppressWarnings("deprecation") - private static final InstanceIdentifier ROOT = InstanceIdentifier.builder().toInstance(); - private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier .builder().toInstance(); @@ -133,14 +132,12 @@ public class BindingIndependentConnector implements // private final Function, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> toDOMInstanceIdentifier = new Function, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier>() { @Override - public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier apply(InstanceIdentifier input) { + public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier apply(final InstanceIdentifier input) { return mappingService.toDataDom(input); } }; - private Registration, DataObject>> baDataReaderRegistration; - private boolean rpcForwarding = false; private boolean dataForwarding = false; @@ -162,7 +159,7 @@ public class BindingIndependentConnector implements // } @Override - public DataObject readOperationalData(InstanceIdentifier path) { + public DataObject readOperationalData(final InstanceIdentifier path) { try { org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); CompositeNode result = biDataService.readOperationalData(biPath); @@ -173,7 +170,7 @@ public class BindingIndependentConnector implements // } private DataObject potentialAugmentationRead(InstanceIdentifier path, - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) + final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, final CompositeNode result) throws DeserializationException { Class targetType = path.getTargetType(); if (Augmentation.class.isAssignableFrom(targetType)) { @@ -188,7 +185,7 @@ public class BindingIndependentConnector implements // } @Override - public DataObject readConfigurationData(InstanceIdentifier path) { + public DataObject readConfigurationData(final InstanceIdentifier path) { try { org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); CompositeNode result = biDataService.readConfigurationData(biPath); @@ -199,40 +196,59 @@ public class BindingIndependentConnector implements // } private DataModificationTransaction createBindingToDomTransaction( - DataModification, DataObject> source) { + final DataModification, DataObject> source) { DataModificationTransaction target = biDataService.beginTransaction(); - LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(),source.getIdentifier()); + LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(), source.getIdentifier()); + for (InstanceIdentifier entry : source.getRemovedConfigurationData()) { + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry); + target.removeConfigurationData(biEntry); + LOG.debug("Delete of Binding Configuration Data {} is translated to {}", entry, biEntry); + } + for (InstanceIdentifier entry : source.getRemovedOperationalData()) { + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry); + target.removeOperationalData(biEntry); + LOG.debug("Delete of Binding Operational Data {} is translated to {}", entry, biEntry); + } for (Entry, DataObject> entry : source.getUpdatedConfigurationData() .entrySet()) { Entry biEntry = mappingService .toDataDom(entry); target.putConfigurationData(biEntry.getKey(), biEntry.getValue()); - LOG.debug("Update of Binding Configuration Data {} is translated to {}",entry,biEntry); + LOG.debug("Update of Binding Configuration Data {} is translated to {}", entry, biEntry); } for (Entry, DataObject> entry : source.getUpdatedOperationalData() .entrySet()) { Entry biEntry = mappingService .toDataDom(entry); target.putOperationalData(biEntry.getKey(), biEntry.getValue()); - LOG.debug("Update of Binding Operational Data {} is translated to {}",entry,biEntry); - } - for (InstanceIdentifier entry : source.getRemovedConfigurationData()) { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry); - target.removeConfigurationData(biEntry); - LOG.debug("Delete of Binding Configuration Data {} is translated to {}",entry,biEntry); - } - for (InstanceIdentifier entry : source.getRemovedOperationalData()) { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry); - target.removeOperationalData(biEntry); - LOG.debug("Delete of Binding Operational Data {} is translated to {}",entry,biEntry); + LOG.debug("Update of Binding Operational Data {} is translated to {}", entry, biEntry); } + return target; } private org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction createDomToBindingTransaction( - DataModification source) { + final DataModification source) { org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction target = baDataService .beginTransaction(); + for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) { + try { + + InstanceIdentifier baEntry = mappingService.fromDataDom(entry); + target.removeConfigurationData(baEntry); + } catch (DeserializationException e) { + LOG.error("Ommiting from BA transaction: {}.", entry, e); + } + } + for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) { + try { + + InstanceIdentifier baEntry = mappingService.fromDataDom(entry); + target.removeOperationalData(baEntry); + } catch (DeserializationException e) { + LOG.error("Ommiting from BA transaction: {}.", entry, e); + } + } for (Entry entry : source .getUpdatedConfigurationData().entrySet()) { try { @@ -254,24 +270,6 @@ public class BindingIndependentConnector implements // LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e); } } - for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) { - try { - - InstanceIdentifier baEntry = mappingService.fromDataDom(entry); - target.removeConfigurationData(baEntry); - } catch (DeserializationException e) { - LOG.error("Ommiting from BA transaction: {}.", entry, e); - } - } - for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) { - try { - - InstanceIdentifier baEntry = mappingService.fromDataDom(entry); - target.removeOperationalData(baEntry); - } catch (DeserializationException e) { - LOG.error("Ommiting from BA transaction: {}.", entry, e); - } - } return target; } @@ -279,7 +277,8 @@ public class BindingIndependentConnector implements // return biDataService; } - protected void setDomDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) { + protected void setDomDataService( + final org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) { this.biDataService = biDataService; } @@ -287,7 +286,7 @@ public class BindingIndependentConnector implements // return baDataService; } - protected void setBindingDataService(DataProviderService baDataService) { + protected void setBindingDataService(final DataProviderService baDataService) { this.baDataService = baDataService; } @@ -295,23 +294,42 @@ public class BindingIndependentConnector implements // return baRpcRegistry; } - protected void setBindingRpcRegistry(RpcProviderRegistry rpcRegistry) { + protected void setBindingRpcRegistry(final RpcProviderRegistry rpcRegistry) { this.baRpcRegistry = rpcRegistry; } public void startDataForwarding() { - checkState(!dataForwarding, "Connector is already forwarding data."); - baDataReaderRegistration = baDataService.registerDataReader(ROOT, this); - baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler); - biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler); - baDataService.registerCommitHandlerListener(domToBindingCommitHandler); + if (baDataService instanceof AbstractForwardedDataBroker) { + dataForwarding = true; + return; + } + + final DataProviderService baData; + if (baDataService instanceof BindingMountPointImpl) { + baData = ((BindingMountPointImpl) baDataService).getDataBrokerImpl(); + LOG.debug("Extracted BA Data provider {} from mount point {}", baData, baDataService); + } else { + baData = baDataService; + } + + if (baData instanceof DataBrokerImpl) { + checkState(!dataForwarding, "Connector is already forwarding data."); + ((DataBrokerImpl) baData).setDataReadDelegate(this); + ((DataBrokerImpl) baData).setRootCommitHandler(bindingToDomCommitHandler); + biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler); + baDataService.registerCommitHandlerListener(domToBindingCommitHandler); + } + dataForwarding = true; } public void startRpcForwarding() { - if (baRpcRegistry != null && biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher) { + if (biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher) { checkState(!rpcForwarding, "Connector is already forwarding RPCs"); - domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager()); + final DomToBindingRpcForwardingManager biFwdManager = new DomToBindingRpcForwardingManager(); + + domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(biFwdManager); + biRpcRegistry.addRpcRegistrationListener(biFwdManager); if (baRpcRegistry instanceof RpcProviderRegistryImpl) { baRpcRegistryImpl = (RpcProviderRegistryImpl) baRpcRegistry; baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance()); @@ -330,7 +348,7 @@ public class BindingIndependentConnector implements // } } - protected void setMappingService(BindingIndependentMappingService mappingService) { + protected void setMappingService(final BindingIndependentMappingService mappingService) { this.mappingService = mappingService; } @@ -340,17 +358,17 @@ public class BindingIndependentConnector implements // } @Override - public void onSessionInitiated(ProviderSession session) { + public void onSessionInitiated(final ProviderSession session) { setDomDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class)); setDomRpcRegistry(session.getService(RpcProvisionRegistry.class)); } - public void onRpcRouterCreated(Class serviceType, RpcRouter router) { + public void onRpcRouterCreated(final Class serviceType, final RpcRouter router) { } - public void setDomRpcRegistry(RpcProvisionRegistry registry) { + public void setDomRpcRegistry(final RpcProvisionRegistry registry) { biRpcRegistry = registry; } @@ -372,8 +390,8 @@ public class BindingIndependentConnector implements // private final DataModification modification; public DomToBindingTransaction( - org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing, - DataModification modification) { + final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing, + final DataModification modification) { super(); this.backing = backing; this.modification = modification; @@ -411,8 +429,8 @@ public class BindingIndependentConnector implements // private final DataModificationTransaction backing; private final DataModification, DataObject> modification; - public BindingToDomTransaction(DataModificationTransaction backing, - DataModification, DataObject> modification) { + public BindingToDomTransaction(final DataModificationTransaction backing, + final DataModification, DataObject> modification) { this.backing = backing; this.modification = modification; domOpenedTransactions.put(backing.getIdentifier(), this); @@ -450,7 +468,7 @@ public class BindingIndependentConnector implements // @Override public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction, DataObject> requestCommit( - DataModification, DataObject> bindingTransaction) { + final DataModification, DataObject> bindingTransaction) { /** * Transaction was created as DOM transaction, in that case we do @@ -462,8 +480,8 @@ public class BindingIndependentConnector implements // } DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction); BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction); - LOG.trace("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(), - domTransaction.getIdentifier()); + LOG.trace("Forwarding Binding Transaction: {} as DOM Transaction: {} .", + bindingTransaction.getIdentifier(), domTransaction.getIdentifier()); return wrapped; } } @@ -473,22 +491,24 @@ public class BindingIndependentConnector implements // DataCommitHandler { @Override - public void onRegister(DataCommitHandlerRegistration, DataObject> registration) { + public void onRegister( + final DataCommitHandlerRegistration, DataObject> registration) { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration + mappingService.toDataDom(registration .getPath()); } @Override - public void onUnregister(DataCommitHandlerRegistration, DataObject> registration) { + public void onUnregister( + final DataCommitHandlerRegistration, DataObject> registration) { // NOOP for now // FIXME: do registration based on only active commit handlers. } @Override public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction requestCommit( - DataModification domTransaction) { + final DataModification domTransaction) { Object identifier = domTransaction.getIdentifier(); /** @@ -515,9 +535,8 @@ public class BindingIndependentConnector implements // * */ private class DomToBindingRpcForwardingManager implements - RouteChangeListener>, - RouterInstantiationListener, - GlobalRpcRegistrationListener { + RouteChangeListener>, RouterInstantiationListener, + GlobalRpcRegistrationListener, RpcRegistrationListener { private final Map, DomToBindingRpcForwarder> forwarders = new WeakHashMap<>(); private RpcProviderRegistryImpl registryImpl; @@ -526,34 +545,34 @@ public class BindingIndependentConnector implements // return registryImpl; } - public void setRegistryImpl(RpcProviderRegistryImpl registryImpl) { + public void setRegistryImpl(final RpcProviderRegistryImpl registryImpl) { this.registryImpl = registryImpl; } @Override - public void onGlobalRpcRegistered(Class cls) { - getRpcForwarder(cls, null); + public void onGlobalRpcRegistered(final Class cls) { + getRpcForwarder(cls, null).registerToDOMBroker(); } @Override - public void onGlobalRpcUnregistered(Class cls) { + public void onGlobalRpcUnregistered(final Class cls) { // NOOP } @Override - public void onRpcRouterCreated(RpcRouter router) { + public void onRpcRouterCreated(final RpcRouter router) { Class ctx = router.getContexts().iterator().next(); getRpcForwarder(router.getServiceType(), ctx); } @Override - public void onRouteChange(RouteChange> change) { + public void onRouteChange(final RouteChange> change) { for (Entry>> entry : change.getAnnouncements().entrySet()) { bindingRoutesAdded(entry); } } - private void bindingRoutesAdded(Entry>> entry) { + private void bindingRoutesAdded(final Entry>> entry) { Class context = entry.getKey().getRoutingContext(); Class service = entry.getKey().getRpcService(); if (context != null) { @@ -561,8 +580,8 @@ public class BindingIndependentConnector implements // } } - private DomToBindingRpcForwarder getRpcForwarder(Class service, - Class context) { + private DomToBindingRpcForwarder getRpcForwarder(final Class service, + final Class context) { DomToBindingRpcForwarder potential = forwarders.get(service); if (potential != null) { return potential; @@ -577,31 +596,40 @@ public class BindingIndependentConnector implements // return potential; } + @Override + public void onRpcImplementationAdded(final QName name) { + + final Optional> rpcInterface = mappingService.getRpcServiceClassFor( + name.getNamespace().toString(), name.getFormattedRevision()); + if (rpcInterface.isPresent()) { + getRpcForwarder(rpcInterface.get(), null).registerToBidningBroker(); + } + } + + @Override + public void onRpcImplementationRemoved(final QName name) { + + } } private class DomToBindingRpcForwarder implements RpcImplementation, InvocationHandler { private final Set supportedRpcs; private final WeakReference> rpcServiceType; - private final Set registrations; + private Set registrations; private final Map strategiesByQName = new HashMap<>(); private final WeakHashMap strategiesByMethod = new WeakHashMap<>(); + private final RpcService proxy; + private ObjectRegistration forwarderRegistration; - public DomToBindingRpcForwarder(Class service) { + public DomToBindingRpcForwarder(final Class service) { this.rpcServiceType = new WeakReference>(service); this.supportedRpcs = mappingService.getRpcQNamesFor(service); - try { - for (QName rpc : supportedRpcs) { - RpcInvocationStrategy strategy = createInvocationStrategy(rpc, service); - strategiesByMethod.put(strategy.targetMethod, strategy); - strategiesByQName.put(rpc, strategy); - biRpcRegistry.addRpcImplementation(rpc, this); - } - } catch (Exception e) { - LOG.error("Could not forward Rpcs of type {}", service.getName(),e); - } - registrations = ImmutableSet.of(); + Class cls = rpcServiceType.get(); + ClassLoader clsLoader = cls.getClassLoader(); + proxy =(RpcService) Proxy.newProxyInstance(clsLoader, new Class[] { cls }, this); + createStrategies(); } /** @@ -610,16 +638,13 @@ public class BindingIndependentConnector implements // * @param service * @param context */ - public DomToBindingRpcForwarder(Class service, Class context) { - this.rpcServiceType = new WeakReference>(service); - this.supportedRpcs = mappingService.getRpcQNamesFor(service); + public DomToBindingRpcForwarder(final Class service, + final Class context) { + this(service); Builder registrationsBuilder = ImmutableSet . builder(); try { for (QName rpc : supportedRpcs) { - RpcInvocationStrategy strategy = createInvocationStrategy(rpc, service); - strategiesByMethod.put(strategy.targetMethod, strategy); - strategiesByQName.put(rpc, strategy); registrationsBuilder.add(biRpcRegistry.addRoutedRpcImplementation(rpc, this)); } createDefaultDomForwarder(); @@ -629,8 +654,48 @@ public class BindingIndependentConnector implements // registrations = registrationsBuilder.build(); } - public void registerPaths(Class context, Class service, - Set> set) { + + + private void createStrategies() { + try { + for (QName rpc : supportedRpcs) { + RpcInvocationStrategy strategy = createInvocationStrategy(rpc, rpcServiceType.get()); + strategiesByMethod.put(strategy.targetMethod, strategy); + strategiesByQName.put(rpc, strategy); + } + } catch (Exception e) { + LOG.error("Could not forward Rpcs of type {}", rpcServiceType.get(), e); + } + + } + + /** + * Registers RPC Forwarder to DOM Broker, + * this means Binding Aware Broker has implementation of RPC + * which is registered to it. + * + * If RPC Forwarder was previously registered to DOM Broker + * or to Bidning Broker this method is noop to prevent + * creating forwarding loop. + * + */ + public void registerToDOMBroker() { + if(forwarderRegistration == null) { + CompositeObjectRegistrationBuilder builder = CompositeObjectRegistration.builderFor(this); + try { + for (QName rpc : supportedRpcs) { + builder.add(biRpcRegistry.addRpcImplementation(rpc, this)); + } + } catch (Exception e) { + LOG.error("Could not forward Rpcs of type {}", rpcServiceType.get(), e); + } + this.forwarderRegistration = builder.toInstance(); + } + } + + + public void registerPaths(final Class context, + final Class service, final Set> set) { QName ctx = BindingReflections.findQName(context); for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform( toDOMInstanceIdentifier)) { @@ -640,9 +705,8 @@ public class BindingIndependentConnector implements // } } - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { if (EQUALS_METHOD.equals(method)) { return false; } @@ -656,8 +720,8 @@ public class BindingIndependentConnector implements // return strategy.forwardToDomBroker(null); } - public void removePaths(Class context, Class service, - Set> set) { + public void removePaths(final Class context, final Class service, + final Set> set) { QName ctx = BindingReflections.findQName(context); for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform( toDOMInstanceIdentifier)) { @@ -685,7 +749,7 @@ public class BindingIndependentConnector implements // } @Override - public RpcResult invokeRpc(QName rpc, CompositeNode domInput) { + public ListenableFuture> invokeRpc(final QName rpc, final CompositeNode domInput) { checkArgument(rpc != null); checkArgument(domInput != null); @@ -694,14 +758,15 @@ public class BindingIndependentConnector implements // RpcService rpcService = baRpcRegistry.getRpcService(rpcType); checkState(rpcService != null); CompositeNode domUnwrappedInput = domInput.getFirstCompositeByName(QName.create(rpc, "input")); + try { - return resolveInvocationStrategy(rpc).invokeOn(rpcService, domUnwrappedInput); + return Futures.immediateFuture(resolveInvocationStrategy(rpc).invokeOn(rpcService, domUnwrappedInput)); } catch (Exception e) { - throw new IllegalStateException(e); + return Futures.immediateFailedFuture(e); } } - private RpcInvocationStrategy resolveInvocationStrategy(QName rpc) { + private RpcInvocationStrategy resolveInvocationStrategy(final QName rpc) { return strategiesByQName.get(rpc); } @@ -720,159 +785,31 @@ public class BindingIndependentConnector implements // } } checkState(targetMethod != null, "Rpc method not found"); - Optional> outputClass = BindingReflections.resolveRpcOutputClass(targetMethod); - Optional> inputClass = BindingReflections - .resolveRpcInputClass(targetMethod); - - RpcInvocationStrategy strategy = null; - if (outputClass.isPresent()) { - if (inputClass.isPresent()) { - strategy = new DefaultInvocationStrategy(rpc, targetMethod, outputClass.get(), inputClass - .get()); - } else { - strategy = new NoInputNoOutputInvocationStrategy(rpc, targetMethod); - } - } else if(inputClass.isPresent()){ - strategy = new NoOutputInvocationStrategy(rpc,targetMethod, inputClass.get()); - } else { - strategy = new NoInputNoOutputInvocationStrategy(rpc,targetMethod); - } - return strategy; + return new RpcInvocationStrategy(rpc,targetMethod, mappingService, biRpcRegistry); } }); } - } - - private abstract class RpcInvocationStrategy { - - protected final Method targetMethod; - protected final QName rpc; - - public RpcInvocationStrategy(QName rpc, Method targetMethod) { - this.targetMethod = targetMethod; - this.rpc = rpc; - } - - public abstract Future> forwardToDomBroker(DataObject input); - - public abstract RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) - throws Exception; - - public RpcResult invokeOn(RpcService rpcService, CompositeNode domInput) throws Exception { - return uncheckedInvoke(rpcService, domInput); - } - } - - private class DefaultInvocationStrategy extends RpcInvocationStrategy { - - @SuppressWarnings("rawtypes") - private final WeakReference inputClass; - - @SuppressWarnings("rawtypes") - private final WeakReference outputClass; - @SuppressWarnings({ "rawtypes", "unchecked" }) - public DefaultInvocationStrategy(QName rpc, Method targetMethod, Class outputClass, - Class inputClass) { - super(rpc, targetMethod); - this.outputClass = new WeakReference(outputClass); - this.inputClass = new WeakReference(inputClass); - } - - @SuppressWarnings("unchecked") - @Override - public RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception { - DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); - Future> futureResult = (Future>) targetMethod.invoke(rpcService, bindingInput); - if (futureResult == null) { - return Rpcs.getRpcResult(false); - } - RpcResult bindingResult = futureResult.get(); - final Object resultObj = bindingResult.getResult(); - if (resultObj instanceof DataObject) { - final CompositeNode output = mappingService.toDataDom((DataObject)resultObj); - return Rpcs.getRpcResult(true, output, Collections.emptySet()); - } - return Rpcs.getRpcResult(true); - } - - @Override - public Future> forwardToDomBroker(DataObject input) { - if(biRpcRegistry != null) { - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); - RpcResult result = biRpcRegistry.invokeRpc(rpc, wrappedXml); - Object baResultValue = null; - if (result.getResult() != null) { - baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), result.getResult()); - } - RpcResult baResult = Rpcs.getRpcResult(result.isSuccessful(), baResultValue, result.getErrors()); - return Futures.> immediateFuture(baResult); - } - return Futures.> immediateFuture(Rpcs.getRpcResult(false)); - } - - } - - private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy { - - public NoInputNoOutputInvocationStrategy(QName rpc, Method targetMethod) { - super(rpc, targetMethod); - } - - @Override - public RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception { - @SuppressWarnings("unchecked") - Future> result = (Future>) targetMethod.invoke(rpcService); - RpcResult bindingResult = result.get(); - return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors()); - } - - @Override - public Future> forwardToDomBroker(DataObject input) { - return Futures.immediateFuture(null); - } - } - - private class NoOutputInvocationStrategy extends RpcInvocationStrategy { - - - @SuppressWarnings("rawtypes") - private final WeakReference inputClass; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public NoOutputInvocationStrategy(QName rpc, Method targetMethod, - Class inputClass) { - super(rpc,targetMethod); - this.inputClass = new WeakReference(inputClass); - } - - - @Override - public RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception { - DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); - Future> result = (Future>) targetMethod.invoke(rpcService, bindingInput); - if (result == null) { - return Rpcs.getRpcResult(false); - } - RpcResult bindingResult = result.get(); - return Rpcs.getRpcResult(true); - } - - @Override - public Future> forwardToDomBroker(DataObject input) { - if(biRpcRegistry != null) { - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.>of(xml)); - RpcResult result = biRpcRegistry.invokeRpc(rpc, wrappedXml); - Object baResultValue = null; - RpcResult baResult = Rpcs.getRpcResult(result.isSuccessful(), null, result.getErrors()); - return Futures.>immediateFuture(baResult); + /** + * Registers RPC Forwarder to Binding Broker, + * this means DOM Broekr has implementation of RPC + * which is registered to it. + * + * If RPC Forwarder was previously registered to DOM Broker + * or to Bidning Broker this method is noop to prevent + * creating forwarding loop. + * + */ + public void registerToBidningBroker() { + if(forwarderRegistration == null) { + try { + this.forwarderRegistration = baRpcRegistry.addRpcImplementation((Class)rpcServiceType.get(), proxy); + } catch (Exception e) { + LOG.error("Unable to forward RPCs for {}",rpcServiceType.get(),e); + } } - return Futures.>immediateFuture(Rpcs.getRpcResult(false)); } - } public boolean isRpcForwarding() { @@ -891,12 +828,12 @@ public class BindingIndependentConnector implements // return mappingService; } - public void setBindingNotificationService(NotificationProviderService baService) { + public void setBindingNotificationService(final NotificationProviderService baService) { this.baNotifyService = baService; } - public void setDomNotificationService(NotificationPublishService domService) { + public void setDomNotificationService(final NotificationPublishService domService) { this.domNotificationService = domService; } @@ -911,7 +848,7 @@ public class BindingIndependentConnector implements // } @Override - public void onNotification(CompositeNode notification) { + public void onNotification(final CompositeNode notification) { QName qname = notification.getNodeType(); WeakReference> potential = notifications.get(qname); if (potential != null) { @@ -928,7 +865,7 @@ public class BindingIndependentConnector implements // } @Override - public void onNotificationSubscribtion(Class notificationType) { + public void onNotificationSubscribtion(final Class notificationType) { QName qname = BindingReflections.findQName(notificationType); if (qname != null) { WeakReference> already = notifications.putIfAbsent(qname,