X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fimpl%2Fconnect%2Fdom%2FBindingIndependentConnector.java;h=37c0dfa60750280b9fe0963bf223a131b0e64753;hb=1f14b44c584f97e7c992e611e6227e262fe0089e;hp=0a769921d80410742cb22b4ad7ee8cc0e9920f0a;hpb=56af902306c727ef1db5185c101b878b5cb386a7;p=controller.git 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 0a769921d8..f63ce10165 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 @@ -1,128 +1,104 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ package org.opendaylight.controller.sal.binding.impl.connect.dom; -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + import java.util.Collection; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.WeakHashMap; -import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - - -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.routing.RouteChange; -import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; + +import org.opendaylight.controller.md.sal.binding.impl.AbstractForwardedDataBroker; +import org.opendaylight.controller.md.sal.common.api.data.DataReader; +import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.controller.sal.binding.api.data.DataProviderService; -import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider; +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.spi.RpcContextIdentifier; -import org.opendaylight.controller.sal.binding.spi.RpcRouter; -import org.opendaylight.controller.sal.common.util.Rpcs; -import org.opendaylight.controller.sal.core.api.Provider; import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; -import org.opendaylight.controller.sal.core.api.RpcImplementation; +import org.opendaylight.controller.sal.core.api.Provider; import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; -import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService; import org.opendaylight.yangtools.concepts.ListenerRegistration; 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; -import org.opendaylight.yangtools.yang.binding.BindingMapping; -import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.RpcInput; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.binding.util.BindingReflections; -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.impl.codec.BindingIndependentMappingService; +import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; import org.slf4j.Logger; 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.ImmutableSet; - -import static com.google.common.base.Preconditions.*; -import static org.opendaylight.yangtools.concepts.util.ClassLoaderUtils.*; - public class BindingIndependentConnector implements // - RuntimeDataProvider, // + DataReader, DataObject>, // Provider, // AutoCloseable { - private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class); - - 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 + private static final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class); + private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier .builder().toInstance(); private BindingIndependentMappingService mappingService; - private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService; - private DataProviderService baDataService; - private ConcurrentMap domOpenedTransactions = new ConcurrentHashMap<>(); - private ConcurrentMap bindingOpenedTransactions = new ConcurrentHashMap<>(); + private final ConcurrentMap domOpenedTransactions; + private final ConcurrentMap bindingOpenedTransactions; + private final BindingToDomCommitHandler bindingToDomCommitHandler; + private final DomToBindingCommitHandler domToBindingCommitHandler; - private BindingToDomCommitHandler bindingToDomCommitHandler = new BindingToDomCommitHandler(); - private DomToBindingCommitHandler domToBindingCommitHandler = new DomToBindingCommitHandler(); + private Registration biCommitHandlerRegistration; + private RpcProvisionRegistry biRpcRegistry; + private RpcProviderRegistry baRpcRegistry; - private Registration, DataObject>> baCommitHandlerRegistration; + private ListenerRegistration domToBindingRpcManager; - private Registration> biCommitHandlerRegistration; + private boolean rpcForwarding; + private boolean dataForwarding; + private boolean notificationForwarding; - private RpcProvisionRegistry biRpcRegistry; - private RpcProviderRegistryImpl baRpcRegistry; + private RpcProviderRegistryImpl baRpcRegistryImpl; - private ListenerRegistration domToBindingRpcManager; - // private ListenerRegistration - // bindingToDomRpcManager; + private NotificationProviderService baNotifyService; - private Function, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> toDOMInstanceIdentifier = new Function, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier>() { + private NotificationPublishService domNotificationService; - @Override - public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier apply(InstanceIdentifier input) { - return mappingService.toDataDom(input); - } + public BindingIndependentConnector() { + domOpenedTransactions = new ConcurrentHashMap<>(); + bindingOpenedTransactions = new ConcurrentHashMap<>(); - }; + bindingToDomCommitHandler = new BindingToDomCommitHandler(bindingOpenedTransactions, domOpenedTransactions); + domToBindingCommitHandler = new DomToBindingCommitHandler(bindingOpenedTransactions, domOpenedTransactions); + rpcForwarding = false; + dataForwarding = false; + notificationForwarding = false; + } @Override - public DataObject readOperationalData(InstanceIdentifier path) { + public DataObject readOperationalData(final InstanceIdentifier path) { try { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); + org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath = mappingService.toDataDom(path); CompositeNode result = biDataService.readOperationalData(biPath); - return potentialAugmentationRead(path,biPath,result); + return potentialAugmentationRead(path, biPath, result); } catch (DeserializationException e) { throw new IllegalStateException(e); } } - private DataObject potentialAugmentationRead(InstanceIdentifier path, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) throws DeserializationException { + private DataObject potentialAugmentationRead(InstanceIdentifier path, + final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath, final CompositeNode result) + throws DeserializationException { Class targetType = path.getTargetType(); if (Augmentation.class.isAssignableFrom(targetType)) { path = mappingService.fromDataDom(biPath); @@ -136,126 +112,106 @@ 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); + org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath = mappingService.toDataDom(path); CompositeNode result = biDataService.readConfigurationData(biPath); - return potentialAugmentationRead(path,biPath,result); + return potentialAugmentationRead(path, biPath, result); } catch (DeserializationException e) { throw new IllegalStateException(e); } } - private DataModificationTransaction createBindingToDomTransaction( - DataModification, DataObject> source) { - DataModificationTransaction target = biDataService.beginTransaction(); - for (Entry, DataObject> entry : source.getUpdatedConfigurationData() - .entrySet()) { - Entry biEntry = mappingService - .toDataDom(entry); - target.putConfigurationData(biEntry.getKey(), biEntry.getValue()); - } - for (Entry, DataObject> entry : source.getUpdatedOperationalData() - .entrySet()) { - Entry biEntry = mappingService - .toDataDom(entry); - target.putOperationalData(biEntry.getKey(), biEntry.getValue()); - } - for (InstanceIdentifier entry : source.getRemovedConfigurationData()) { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry); - target.removeConfigurationData(biEntry); - } - for (InstanceIdentifier entry : source.getRemovedOperationalData()) { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry); - target.removeOperationalData(biEntry); - } - return target; - } - - private org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction createDomToBindingTransaction( - DataModification source) { - org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction target = baDataService - .beginTransaction(); - for (Entry entry : source - .getUpdatedConfigurationData().entrySet()) { - try { - InstanceIdentifier baKey = mappingService.fromDataDom(entry.getKey()); - DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue()); - target.putConfigurationData(baKey, baData); - } catch (DeserializationException e) { - LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e); - } - } - for (Entry entry : source - .getUpdatedOperationalData().entrySet()) { - try { - - InstanceIdentifier baKey = mappingService.fromDataDom(entry.getKey()); - DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue()); - target.putOperationalData(baKey, baData); - } catch (DeserializationException e) { - 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; - } - public org.opendaylight.controller.sal.core.api.data.DataProviderService getBiDataService() { return biDataService; } - public void setBiDataService(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; + bindingToDomCommitHandler.setBindingIndependentDataService(this.biDataService); } public DataProviderService getBaDataService() { return baDataService; } - public void setBaDataService(DataProviderService baDataService) { + protected void setBindingDataService(final DataProviderService baDataService) { this.baDataService = baDataService; + domToBindingCommitHandler.setBindingAwareDataService(this.baDataService); } public RpcProviderRegistry getRpcRegistry() { return baRpcRegistry; } - public void setRpcRegistry(RpcProviderRegistryImpl rpcRegistry) { + protected void setBindingRpcRegistry(final RpcProviderRegistry rpcRegistry) { this.baRpcRegistry = rpcRegistry; } - public void start() { - baDataService.registerDataReader(ROOT, this); - baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler); - biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler); - baDataService.registerCommitHandlerListener(domToBindingCommitHandler); + public void startDataForwarding() { + 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 (baRpcRegistry != null && biRpcRegistry != null) { - domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager()); + 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; + } + + //WTF? - cycle references to biFwdManager - need to solve :-/ + public void startRpcForwarding() { + checkNotNull(mappingService, "Unable to start Rpc forwarding. Reason: Mapping Service is not initialized properly!"); + if (biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher) { + checkState(!rpcForwarding, "Connector is already forwarding RPCs"); + final DomToBindingRpcForwardingManager biFwdManager = new DomToBindingRpcForwardingManager(mappingService, biRpcRegistry, baRpcRegistry); + + domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(biFwdManager); + biRpcRegistry.addRpcRegistrationListener(biFwdManager); + if (baRpcRegistry instanceof RpcProviderRegistryImpl) { + baRpcRegistryImpl = (RpcProviderRegistryImpl) baRpcRegistry; + baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance()); + baRpcRegistryImpl.registerGlobalRpcRegistrationListener(domToBindingRpcManager.getInstance()); + biFwdManager.setRegistryImpl(baRpcRegistryImpl); + } + rpcForwarding = true; + } + } + public void startNotificationForwarding() { + checkState(!notificationForwarding, "Connector is already forwarding notifications."); + if (mappingService == null) { + LOG.warn("Unable to start Notification forwarding. Reason: Mapping Service is not initialized properly!"); + } else if (baNotifyService == null) { + LOG.warn("Unable to start Notification forwarding. Reason: Binding Aware Notify Service is not initialized properly!"); + } else if (domNotificationService == null) { + LOG.warn("Unable to start Notification forwarding. Reason: DOM Notification Service is not initialized properly!"); + } else { + baNotifyService.registerInterestListener( + new DomToBindingNotificationForwarder(mappingService, baNotifyService, domNotificationService)); + notificationForwarding = true; } } - public void setMappingService(BindingIndependentMappingService mappingService) { + protected void setMappingService(final BindingIndependentMappingService mappingService) { this.mappingService = mappingService; + bindingToDomCommitHandler.setMappingService(this.mappingService); + domToBindingCommitHandler.setMappingService(this.mappingService); } @Override @@ -264,370 +220,45 @@ public class BindingIndependentConnector implements // } @Override - public void onSessionInitiated(ProviderSession session) { - setBiDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class)); - start(); - } - - public void onRpcRouterCreated(Class serviceType, RpcRouter router) { + 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 setDomRpcRegistry(RpcProvisionRegistry registry) { + public void setDomRpcRegistry(final RpcProvisionRegistry registry) { biRpcRegistry = registry; } @Override public void close() throws Exception { - if (baCommitHandlerRegistration != null) { - baCommitHandlerRegistration.close(); - } if (biCommitHandlerRegistration != null) { biCommitHandlerRegistration.close(); } - } - private class DomToBindingTransaction implements - DataCommitTransaction { - - private final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing; - private final DataModification modification; - - public DomToBindingTransaction( - org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing, - DataModification modification) { - super(); - this.backing = backing; - this.modification = modification; - bindingOpenedTransactions.put(backing.getIdentifier(), this); - } - - @Override - public DataModification getModification() { - return modification; - } - - @Override - public RpcResult rollback() throws IllegalStateException { - // backing.cancel(); - return Rpcs. getRpcResult(true, null, Collections. emptySet()); - } - - @Override - public RpcResult finish() throws IllegalStateException { - Future> result = backing.commit(); - try { - RpcResult baResult = result.get(); - return Rpcs. getRpcResult(baResult.isSuccessful(), null, baResult.getErrors()); - } catch (InterruptedException e) { - throw new IllegalStateException("", e); - } catch (ExecutionException e) { - throw new IllegalStateException("", e); - } - } + public boolean isRpcForwarding() { + return rpcForwarding; } - private class BindingToDomTransaction implements - DataCommitTransaction, DataObject> { - - private DataModificationTransaction backing; - private DataModification, DataObject> modification; - - public BindingToDomTransaction(DataModificationTransaction backing, - DataModification, DataObject> modification) { - this.backing = backing; - this.modification = modification; - domOpenedTransactions.put(backing.getIdentifier(), this); - } - - @Override - public DataModification, DataObject> getModification() { - return modification; - } - - @Override - public RpcResult finish() throws IllegalStateException { - Future> result = backing.commit(); - try { - RpcResult biResult = result.get(); - return Rpcs. getRpcResult(biResult.isSuccessful(), null, biResult.getErrors()); - } catch (InterruptedException e) { - throw new IllegalStateException("", e); - } catch (ExecutionException e) { - throw new IllegalStateException("", e); - } finally { - domOpenedTransactions.remove(backing.getIdentifier()); - } - } - - @Override - public RpcResult rollback() throws IllegalStateException { - domOpenedTransactions.remove(backing.getIdentifier()); - return Rpcs. getRpcResult(true, null, Collections. emptySet()); - } + public boolean isDataForwarding() { + return dataForwarding; } - private class BindingToDomCommitHandler implements - DataCommitHandler, DataObject> { - - @Override - public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction, DataObject> requestCommit( - DataModification, DataObject> bindingTransaction) { - - /** - * Transaction was created as DOM transaction, in that case we do - * not need to forward it back. - */ - if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) { - - return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction); - } - DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction); - BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction); - LOG.info("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(), - domTransaction.getIdentifier()); - return wrapped; - } + public boolean isNotificationForwarding() { + return notificationForwarding; } - private class DomToBindingCommitHandler implements // - RegistrationListener, DataObject>>, // - DataCommitHandler { - - @Override - public void onRegister(DataCommitHandlerRegistration, DataObject> registration) { - - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration - .getPath()); - - } - - @Override - public void onUnregister(DataCommitHandlerRegistration, DataObject> registration) { - // NOOP for now - // FIXME: do registration based on only active commit handlers. - } - - public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction requestCommit( - DataModification domTransaction) { - Object identifier = domTransaction.getIdentifier(); - - /** - * We checks if the transcation was originated in this mapper. If it - * was originated in this mapper we are returing allways success - * commit hanlder to prevent creating loop in two-phase commit and - * duplicating data. - */ - if (domOpenedTransactions.containsKey(identifier)) { - return CommitHandlersTransactions.allwaysSuccessfulTransaction(domTransaction); - } - - 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(), - baTransaction.getIdentifier()); - return forwardedTransaction; - } + public BindingIndependentMappingService getMappingService() { + return mappingService; } - private class DomToBindingRpcForwardingManager implements - RouteChangeListener> { - - private final Map, DomToBindingRpcForwarder> forwarders = new WeakHashMap<>(); - - @Override - public void onRouteChange(RouteChange> change) { - for (Entry>> entry : change.getAnnouncements().entrySet()) { - bindingRoutesAdded(entry); - } - } - - private void bindingRoutesAdded(Entry>> entry) { - Class context = entry.getKey().getRoutingContext(); - Class service = entry.getKey().getRpcService(); - if (context != null) { - getRpcForwarder(service, context).registerPaths(context, service, entry.getValue()); - } - } - - private DomToBindingRpcForwarder getRpcForwarder(Class service, - Class context) { - DomToBindingRpcForwarder potential = forwarders.get(service); - if (potential != null) { - return potential; - } - if (context == null) { - potential = new DomToBindingRpcForwarder(service); - } else { - potential = new DomToBindingRpcForwarder(service, context); - } - forwarders.put(service, potential); - return potential; - } + public void setBindingNotificationService(final NotificationProviderService baService) { + this.baNotifyService = baService; } - private class DomToBindingRpcForwarder implements RpcImplementation { - - private final Set supportedRpcs; - private final WeakReference> rpcServiceType; - private Set registrations; - - public DomToBindingRpcForwarder(Class service) { - this.rpcServiceType = new WeakReference>(service); - this.supportedRpcs = mappingService.getRpcQNamesFor(service); - for (QName rpc : supportedRpcs) { - biRpcRegistry.addRpcImplementation(rpc, this); - } - registrations = ImmutableSet.of(); - } - - public DomToBindingRpcForwarder(Class service, Class context) { - this.rpcServiceType = new WeakReference>(service); - this.supportedRpcs = mappingService.getRpcQNamesFor(service); - registrations = new HashSet<>(); - for (QName rpc : supportedRpcs) { - registrations.add(biRpcRegistry.addRoutedRpcImplementation(rpc, this)); - } - registrations = ImmutableSet.copyOf(registrations); - } - - public void registerPaths(Class context, Class service, - Set> set) { - QName ctx = BindingReflections.findQName(context); - for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform( - toDOMInstanceIdentifier)) { - for (org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration reg : registrations) { - reg.registerPath(ctx, path); - } - } - } - - public void removePaths(Class context, Class service, - Set> set) { - QName ctx = BindingReflections.findQName(context); - for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform( - toDOMInstanceIdentifier)) { - for (org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration reg : registrations) { - reg.unregisterPath(ctx, path); - } - } - } - - @Override - public Set getSupportedRpcs() { - return supportedRpcs; - } - - @Override - public RpcResult invokeRpc(QName rpc, CompositeNode domInput) { - checkArgument(rpc != null); - checkArgument(domInput != null); - - Class rpcType = rpcServiceType.get(); - checkState(rpcType != null); - RpcService rpcService = baRpcRegistry.getRpcService(rpcType); - checkState(rpcService != null); - CompositeNode domUnwrappedInput = domInput.getFirstCompositeByName(QName.create(rpc, "input")); - try { - return resolveInvocationStrategy(rpc, rpcType).invokeOn(rpcService, domUnwrappedInput); - } catch (Exception e) { - throw new IllegalStateException(e); - } - } - - private RpcInvocationStrategy resolveInvocationStrategy(final QName rpc, - final Class rpcType) throws Exception { - return ClassLoaderUtils.withClassLoader(rpcType.getClassLoader(), new Callable() { - @Override - public RpcInvocationStrategy call() throws Exception { - String methodName = BindingMapping.getMethodName(rpc); - Method targetMethod = null; - for (Method possibleMethod : rpcType.getMethods()) { - if (possibleMethod.getName().equals(methodName) - && BindingReflections.isRpcMethod(possibleMethod)) { - targetMethod = possibleMethod; - break; - } - } - 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(targetMethod, outputClass.get(), inputClass.get()); - } else { - strategy = new NoInputNoOutputInvocationStrategy(targetMethod); - } - } else { - strategy = null; - } - return strategy; - } - - }); - } - } - - private abstract class RpcInvocationStrategy { - - protected final Method targetMethod; - - public RpcInvocationStrategy(Method targetMethod) { - this.targetMethod = targetMethod; - } - - 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 WeakReference inputClass; - - @SuppressWarnings("rawtypes") - private WeakReference outputClass; - - public DefaultInvocationStrategy(Method targetMethod, Class outputClass, - Class inputClass) { - super(targetMethod); - this.outputClass = new WeakReference(outputClass); - 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); - } - - } - - private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy { - - public NoInputNoOutputInvocationStrategy(Method targetMethod) { - super(targetMethod); - } - - public RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception { - Future> result = (Future>) targetMethod.invoke(rpcService); - RpcResult bindingResult = result.get(); - return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors()); - } - + public void setDomNotificationService(final NotificationPublishService domService) { + this.domNotificationService = domService; } }