From: Tony Tkacik Date: Wed, 15 Jan 2014 13:36:35 +0000 (+0100) Subject: Fixed deployment of mount points (dynamic instances of MD-SAL) X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~89 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=696c988be117c8aa1afa39502ff2e56c9b72e834 Fixed deployment of mount points (dynamic instances of MD-SAL) - Converted some xtend sources into Java classes - Added mount point deployer - service responsible for deploying dynamic instances of MD-SAL, which have separate context and could be created and retrieved via MountService. Change-Id: I9c0798e2f5f0af647d97b22a2da2f6c46bf9b72d Signed-off-by: Tony Tkacik --- diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java index e20640d420..72c6b1d75d 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java @@ -7,7 +7,7 @@ import org.opendaylight.yangtools.yang.binding.RpcService; * version of RpcServices * */ -public interface RpcConsumerRegistry { +public interface RpcConsumerRegistry extends BindingAwareService { /** * Returns a session specific instance (implementation) of requested * YANG module implentation / service provided by consumer. diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java index 972e64faf6..cc764888cc 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java @@ -1,18 +1,22 @@ package org.opendaylight.controller.sal.binding.api; +import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher; 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.rpc.RpcContextIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.RpcService; /** - * Interface defining provider's access to the Rpc Registry - * which could be used to register their implementations of service to the MD-SAL. + * Interface defining provider's access to the Rpc Registry which could be used + * to register their implementations of service to the MD-SAL. * * @author ttkacik - * + * */ -public interface RpcProviderRegistry extends RpcConsumerRegistry { +public interface RpcProviderRegistry extends // + RpcConsumerRegistry, // + RouteChangePublisher> { /** * Registers an global RpcService implementation. * @@ -25,12 +29,16 @@ public interface RpcProviderRegistry extends RpcConsumerRegistry { /** * - * Register an Routed RpcService where routing is determined on annotated (in YANG model) - * context-reference and value of annotated leaf. + * Register an Routed RpcService where routing is determined on annotated + * (in YANG model) context-reference and value of annotated leaf. * - * @param type Type of RpcService, use generated interface class, not your implementation clas - * @param implementation Implementation of RpcService - * @return Registration object for routed Rpc which could be used to close an + * @param type + * Type of RpcService, use generated interface class, not your + * implementation clas + * @param implementation + * Implementation of RpcService + * @return Registration object for routed Rpc which could be used to close + * an * * @throws IllegalStateException */ diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java index d91a216baa..194c431ec0 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java @@ -1,18 +1,36 @@ package org.opendaylight.controller.sal.binding.api.mount; +import java.util.EventListener; + import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /** - * Provider MountProviderService, this version allows access to MD-SAL - * services specific for this mountpoint and registration / provision of - * interfaces for mount point. + * Provider MountProviderService, this version allows access to MD-SAL services + * specific for this mountpoint and registration / provision of interfaces for + * mount point. * * @author ttkacik * */ -public interface MountProviderService extends MountInstance { +public interface MountProviderService extends MountService { + + @Override + public MountProviderInstance getMountPoint(InstanceIdentifier path); MountProviderInstance createMountPoint(InstanceIdentifier path); + + MountProviderInstance createOrGetMountPoint(InstanceIdentifier path); + + ListenerRegistration registerProvisionListener(MountProvisionListener listener); + + public interface MountProvisionListener extends EventListener { + + void onMountPointCreated(InstanceIdentifier path); + + void onMountPointRemoved(InstanceIdentifier path); + + } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcContextIdentifier.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcContextIdentifier.java similarity index 97% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcContextIdentifier.java rename to opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcContextIdentifier.java index 33569eb077..8437c18f09 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcContextIdentifier.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcContextIdentifier.java @@ -1,4 +1,4 @@ -package org.opendaylight.controller.sal.binding.spi; +package org.opendaylight.controller.sal.binding.api.rpc; import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.yang.binding.BaseIdentity; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java similarity index 98% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java rename to opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java index 621d048dfd..31fed62d87 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java @@ -5,7 +5,7 @@ * 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.spi; +package org.opendaylight.controller.sal.binding.api.rpc; import java.util.Set; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingContext.java similarity index 82% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java rename to opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingContext.java index e3a7235652..db93766c3c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingContext.java @@ -1,4 +1,4 @@ -package org.opendaylight.controller.sal.binding.spi; +package org.opendaylight.controller.sal.binding.api.rpc; import org.opendaylight.yangtools.yang.binding.BaseIdentity; import org.opendaylight.yangtools.yang.binding.RpcService; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingTable.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingTable.java similarity index 96% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingTable.java rename to opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingTable.java index 4d9d51b133..cc800b6bbb 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingTable.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingTable.java @@ -5,7 +5,7 @@ * 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.spi; +package org.opendaylight.controller.sal.binding.api.rpc; import java.util.Map; diff --git a/opendaylight/md-sal/sal-binding-broker/pom.xml b/opendaylight/md-sal/sal-binding-broker/pom.xml index 1b0f78384f..29357c0432 100644 --- a/opendaylight/md-sal/sal-binding-broker/pom.xml +++ b/opendaylight/md-sal/sal-binding-broker/pom.xml @@ -163,6 +163,11 @@ sal-binding-api 1.0-SNAPSHOT + + org.opendaylight.controller + sal-binding-util + 1.0-SNAPSHOT + org.slf4j slf4j-api diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java index c46b0dd6b4..cd45f2c8b2 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java @@ -1,48 +1,85 @@ /** -* Generated file + * Generated file -* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Wed Nov 20 17:33:01 CET 2013 -* -* Do not modify this file unless it is present under src/main directory -*/ + * Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl + * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + * Generated at: Wed Nov 20 17:33:01 CET 2013 + * + * Do not modify this file unless it is present under src/main directory + */ package org.opendaylight.controller.config.yang.md.sal.binding.impl; -import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl; +import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; +import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker; +import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl; +import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl; +import org.opendaylight.controller.sal.binding.impl.forward.DomForwardingUtils; import org.osgi.framework.BundleContext; -import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.MoreExecutors; /** * */ -public final class BindingBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule { +public final class BindingBrokerImplModule extends + org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule { private BundleContext bundleContext; - public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, + org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); } - public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) { + public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, + org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, + BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) { super(identifier, dependencyResolver, oldModule, oldInstance); } @Override - public void validate(){ + public void validate() { super.validate(); } @Override public java.lang.AutoCloseable createInstance() { - BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getIdentifier().getInstanceName(),getBundleContext()); - broker.setDataBroker(getDataBrokerDependency()); - broker.setNotifyBroker(getNotificationServiceDependency()); + + RootBindingAwareBroker broker; + if (DomForwardingUtils.isDomForwardedBroker(getDataBrokerDependency())) { + broker = createForwardedBroker(); + } else { + broker = createStandaloneBroker(); + } broker.start(); return broker; } + private RootBindingAwareBroker createStandaloneBroker() { + RootBindingAwareBroker broker = new RootBindingAwareBroker(getIdentifier().getInstanceName()); + + broker.setDataBroker(getDataBrokerDependency()); + broker.setNotificationBroker(getNotificationServiceDependency()); + broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier())); + return broker; + } + + private RootBindingAwareBroker createForwardedBroker() { + DomForwardedBindingBrokerImpl broker = new DomForwardedBindingBrokerImpl(getIdentifier().getInstanceName()); + + broker.setDataBroker(getDataBrokerDependency()); + broker.setNotificationBroker(getNotificationServiceDependency()); + broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier())); + + broker.getMountManager().setDataCommitExecutor(SingletonHolder.getDefaultCommitExecutor()); + broker.getMountManager().setNotificationExecutor(SingletonHolder.getDefaultNotificationExecutor()); + + + DomForwardingUtils.reuseForwardingFrom(broker, broker.getDataBroker()); + broker.startForwarding(); + return broker; + } + public BundleContext getBundleContext() { return bundleContext; } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java index 01dc6b8c0c..185b37bab5 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java @@ -13,12 +13,16 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import org.opendaylight.controller.config.yang.md.sal.binding.statistics.DataBrokerRuntimeMXBeanImpl; import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter; +import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl; +import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer; import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector; import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService; +import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl; import org.opendaylight.controller.sal.core.api.Broker; +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; import org.opendaylight.controller.sal.core.api.data.DataProviderService; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -52,25 +56,38 @@ public final class DataBrokerImplModule extends @Override public java.lang.AutoCloseable createInstance() { - DataBrokerRuntimeMXBeanImpl dataBindingBroker = new DataBrokerRuntimeMXBeanImpl(); + RootDataBrokerImpl dataBindingBroker; - // FIXME: obtain via dependency management - ExecutorService executor = Executors.newCachedThreadPool(); - ExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor); - dataBindingBroker.setExecutor(listeningExecutor); - - Broker domBroker = getDomBrokerDependency(); - BindingIndependentMappingService mappingService = getMappingServiceDependency(); - if (domBroker != null && mappingService != null) { - BindingIndependentConnector runtimeMapping = new BindingIndependentConnector(); - runtimeMapping.setMappingService(mappingService); - runtimeMapping.setBaDataService(dataBindingBroker); - domBroker.registerProvider(runtimeMapping, getBundleContext()); + ExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor(); + + if (getDomBrokerDependency() != null && getMappingServiceDependency() != null) { + + dataBindingBroker = createDomConnectedBroker(listeningExecutor); + } else { + dataBindingBroker = createStandAloneBroker(listeningExecutor); } - getRootRuntimeBeanRegistratorWrapper().register(dataBindingBroker); + dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper()); + return dataBindingBroker; } + private RootDataBrokerImpl createStandAloneBroker(ExecutorService listeningExecutor) { + RootDataBrokerImpl broker = new RootDataBrokerImpl(); + broker.setExecutor(listeningExecutor); + return broker; + } + + private RootDataBrokerImpl createDomConnectedBroker(ExecutorService listeningExecutor) { + DomForwardedDataBrokerImpl forwardedBroker = new DomForwardedDataBrokerImpl(); + forwardedBroker.setExecutor(listeningExecutor); + BindingIndependentConnector connector = BindingDomConnectorDeployer.createConnector(getMappingServiceDependency()); + getDomBrokerDependency().registerProvider(forwardedBroker, getBundleContext()); + ProviderSession domContext = forwardedBroker.getDomProviderContext(); + forwardedBroker.setConnector(connector); + forwardedBroker.setDomProviderContext(domContext); + forwardedBroker.startForwarding(); + return forwardedBroker; + } public BundleContext getBundleContext() { return bundleContext; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java index e4f74deb4b..644860595e 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java @@ -13,6 +13,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl; import com.google.common.util.concurrent.ListeningExecutorService; @@ -43,8 +44,7 @@ public final class NotificationBrokerImplModule extends @Override public java.lang.AutoCloseable createInstance() { - ExecutorService executor = Executors.newFixedThreadPool(5); - ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor); + ListeningExecutorService listeningExecutor = SingletonHolder.getDefaultNotificationExecutor(); NotificationBrokerImpl broker = new NotificationBrokerImpl(listeningExecutor); return broker; } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/statistics/DataBrokerRuntimeMXBeanImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/statistics/DataBrokerRuntimeMXBeanImpl.java deleted file mode 100644 index 5da084e9bd..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/statistics/DataBrokerRuntimeMXBeanImpl.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.opendaylight.controller.config.yang.md.sal.binding.statistics; - -import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data; -import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean; -import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions; -import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl; - -public class DataBrokerRuntimeMXBeanImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean { - - private final Transactions transactions = new Transactions(); - private final Data data = new Data(); - - public Transactions getTransactions() { - transactions.setCreated(getCreatedTransactionsCount().get()); - transactions.setSubmitted(getSubmittedTransactionsCount().get()); - transactions.setSuccessful(getFinishedTransactionsCount().get()); - transactions.setFailed(getFailedTransactionsCount().get()); - return transactions; - } - - @Override - public Data getData() { - transactions.setCreated(getCreatedTransactionsCount().get()); - transactions.setSubmitted(getSubmittedTransactionsCount().get()); - transactions.setSuccessful(getFinishedTransactionsCount().get()); - transactions.setFailed(getFailedTransactionsCount().get()); - data.setTransactions(transactions); - return data; - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java index 7789a06fe8..8aff12b44a 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java @@ -7,8 +7,8 @@ */ package org.opendaylight.controller.sal.binding.codegen; +import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter; import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory; -import org.opendaylight.controller.sal.binding.spi.RpcRouter; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java index 8b2db8b13c..d976a0cec9 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java @@ -3,7 +3,8 @@ package org.opendaylight.controller.sal.binding.codegen.impl; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration; -import org.opendaylight.controller.sal.binding.spi.RpcRouter; +import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter; +import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable; import org.opendaylight.yangtools.yang.binding.BaseIdentity; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -13,7 +14,6 @@ import java.util.Map; import java.util.Set; import java.util.HashMap; -import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.RpcImplementation; import org.opendaylight.controller.md.sal.common.api.routing.MutableRoutingTable; @@ -147,7 +147,6 @@ public class RpcRouterCodegenInstance implements // @Override public void unregisterPath(Class context, InstanceIdentifier path) { routingTables.get(context).removeRoute(path, getInstance()); - } @Override diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java index 808358fb35..76318ae843 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java @@ -1,6 +1,6 @@ package org.opendaylight.controller.sal.binding.codegen.impl; -import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable; +import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable; import org.opendaylight.yangtools.yang.binding.BaseIdentity; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java index 266293fb6d..446a9caf8e 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java @@ -1,14 +1,49 @@ package org.opendaylight.controller.sal.binding.codegen.impl; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; + import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator; import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.ThreadFactoryBuilder; + import javassist.ClassPool; public class SingletonHolder { - public static final ClassPool CLASS_POOL = new ClassPool(); - public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator(CLASS_POOL); + public static final ClassPool CLASS_POOL = new ClassPool(); + public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator( + CLASS_POOL); public static final RuntimeCodeGenerator RPC_GENERATOR = RPC_GENERATOR_IMPL; public static final NotificationInvokerFactory INVOKER_FACTORY = RPC_GENERATOR_IMPL.getInvokerFactory(); + private static ListeningExecutorService NOTIFICATION_EXECUTOR = null; + private static ListeningExecutorService COMMIT_EXECUTOR = null; + + public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() { + if (NOTIFICATION_EXECUTOR == null) { + NOTIFICATION_EXECUTOR = createNamedExecutor("md-sal-binding-notification-%d"); + } + return NOTIFICATION_EXECUTOR; + } + + public static synchronized final ListeningExecutorService getDefaultCommitExecutor() { + if (COMMIT_EXECUTOR == null) { + COMMIT_EXECUTOR = createNamedExecutor("md-sal-binding-commit-%d"); + } + + return COMMIT_EXECUTOR; + } + + private static ListeningExecutorService createNamedExecutor(String format) { + ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat(format).build(); + ExecutorService executor = Executors.newCachedThreadPool(factory); + return MoreExecutors.listeningDecorator(executor); + + } + } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend deleted file mode 100644 index b4bf3f5a83..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 - -import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer -import org.opendaylight.controller.sal.binding.api.BindingAwareProvider -import org.osgi.framework.BundleContext -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker -import org.opendaylight.controller.sal.binding.api.NotificationProviderService -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yangtools.yang.binding.DataObject -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) - - private InstanceIdentifier root = InstanceIdentifier.builder().toInstance(); - - @Property - private var NotificationProviderService notifyBroker - - @Property - private var DataProviderService dataBroker - - @Property - var BundleContext brokerBundleContext - - public new(String name,BundleContext bundleContext) { - super(name); - _brokerBundleContext = bundleContext; - } - - def start() { - log.info("Starting MD-SAL: Binding Aware Broker"); - } - - - - override registerConsumer(BindingAwareConsumer consumer, BundleContext bundleCtx) { - val ctx = consumer.createContext(bundleCtx) - consumer.onSessionInitialized(ctx) - return ctx - } - - override registerProvider(BindingAwareProvider provider, BundleContext bundleCtx) { - val ctx = provider.createContext(bundleCtx) - provider.onSessionInitialized(ctx) - provider.onSessionInitiated(ctx as ProviderContext) - return ctx - } - - private def createContext(BindingAwareConsumer consumer, BundleContext consumerCtx) { - new OsgiConsumerContext(consumerCtx, this) - } - - private def createContext(BindingAwareProvider provider, BundleContext providerCtx) { - new OsgiProviderContext(providerCtx, this) - } - - override >> registerRouteChangeListener(L listener) { - super.registerRouteChangeListener(listener) - } - - override close() throws Exception { - - } -} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java index 5db522f56c..0069de9802 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java @@ -3,7 +3,7 @@ package org.opendaylight.controller.sal.binding.impl; import java.util.Set; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicLong; - + import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker; import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; import org.opendaylight.controller.sal.binding.api.data.DataProviderService; @@ -11,12 +11,13 @@ import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderR import org.opendaylight.controller.sal.common.DataStoreIdentifier; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.DataRoot; +import org.opendaylight.yangtools.yang.binding.Identifiable; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; -public class DataBrokerImpl extends AbstractDataBroker, DataObject, DataChangeListener> implements - DataProviderService, AutoCloseable { +public class DataBrokerImpl extends AbstractDataBroker, DataObject, DataChangeListener> // + implements DataProviderService, AutoCloseable { private final AtomicLong nextTransaction = new AtomicLong(); private final AtomicLong createdTransactionsCount = new AtomicLong(); @@ -114,7 +115,6 @@ public class DataBrokerImpl extends AbstractDataBroker, BindingMountPointImpl> mountPoints; + private final ListenerRegistry listeners = ListenerRegistry.create(); + + private ListeningExecutorService notificationExecutor; + private ListeningExecutorService dataCommitExecutor; + + public MountPointManagerImpl() { + mountPoints = new ConcurrentHashMap<>(); + } + + public ListeningExecutorService getNotificationExecutor() { + return notificationExecutor; + } + + public void setNotificationExecutor(ListeningExecutorService notificationExecutor) { + this.notificationExecutor = notificationExecutor; + } + + public ListeningExecutorService getDataCommitExecutor() { + return dataCommitExecutor; + } + + public void setDataCommitExecutor(ListeningExecutorService dataCommitExecutor) { + this.dataCommitExecutor = dataCommitExecutor; + } + + @Override + public synchronized BindingMountPointImpl createMountPoint(InstanceIdentifier path) { + BindingMountPointImpl potential = mountPoints.get(path); + if (potential != null) { + throw new IllegalStateException("Mount point already exists."); + } + return createOrGetMountPointImpl(path); + } + + @Override + public BindingMountPointImpl createOrGetMountPoint(InstanceIdentifier path) { + BindingMountPointImpl potential = getMountPoint(path); + if (potential != null) { + return potential; + } + return createOrGetMountPointImpl(path); + } + + @Override + public BindingMountPointImpl getMountPoint(InstanceIdentifier path) { + return mountPoints.get(path); + } + + private synchronized BindingMountPointImpl createOrGetMountPointImpl(InstanceIdentifier path) { + BindingMountPointImpl potential = getMountPoint(path); + if (potential != null) { + return potential; + } + RpcProviderRegistryImpl rpcRegistry = new RpcProviderRegistryImpl("mount"); + NotificationBrokerImpl notificationBroker = new NotificationBrokerImpl(); + notificationBroker.setExecutor(getNotificationExecutor()); + DataBrokerImpl dataBroker = new DataBrokerImpl(); + dataBroker.setExecutor(getDataCommitExecutor()); + BindingMountPointImpl mountInstance = new BindingMountPointImpl(path, rpcRegistry, notificationBroker, + dataBroker); + mountPoints.putIfAbsent(path, mountInstance); + notifyMountPointCreated(path); + return mountInstance; + } + + private void notifyMountPointCreated(InstanceIdentifier path) { + for (ListenerRegistration listener : listeners) { + try { + listener.getInstance().onMountPointCreated(path); + } catch (Exception e) { + LOG.error("Unhandled exception during invoking listener.", e); + } + } + } + + @Override + public ListenerRegistration registerProvisionListener(MountProvisionListener listener) { + return listeners.register(listener); + } + + public class BindingMountPointImpl extends + AbstractBindingSalProviderInstance + implements MountProviderInstance { + + private InstanceIdentifier identifier; + + public BindingMountPointImpl(org.opendaylight.yangtools.yang.binding.InstanceIdentifier identifier, + RpcProviderRegistryImpl rpcRegistry, NotificationBrokerImpl notificationBroker, + DataBrokerImpl dataBroker) { + super(rpcRegistry, notificationBroker, dataBroker); + this.identifier = identifier; + } + + @Override + public InstanceIdentifier getIdentifier() { + return this.identifier; + } + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend index b0939a043f..b4fd6b6771 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend @@ -175,6 +175,7 @@ class NotifyTask implements Callable { private static val log = LoggerFactory.getLogger(NotifyTask); + @SuppressWarnings("rawtypes") val NotificationListener listener; val Notification notification; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend deleted file mode 100644 index 644c50b86a..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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; - -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext; -import org.opendaylight.controller.sal.binding.api.BindingAwareService; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.osgi.framework.BundleContext; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceReference; -import org.slf4j.LoggerFactory -import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.* - -class OsgiConsumerContext implements ConsumerContext { - - static val log = LoggerFactory.getLogger(OsgiConsumerContext) - protected val BundleContext bundleContext; - protected val BindingAwareBrokerImpl broker; - - new(BundleContext ctx, BindingAwareBrokerImpl broker) { - this.bundleContext = ctx; - this.broker = broker; - } - - override def getSALService(Class service) { - - // SAL Services are global - var ref = bundleContext.getServiceReference(service); - return bundleContext.getService(ref) as T; - } - - override def T getRpcService(Class module) { - try { - - val services = bundleContext.getServiceReferences(module, getProxyFilter()); - - // Proxy service found / using first implementation - // FIXME: Add advanced logic to retrieve service with right set of models - if (false == services.empty) { - val ref = services.iterator().next() as ServiceReference; - return bundleContext.getService(ref) as T; - } else { - return broker.getRpcService(module); - } - } catch (InvalidSyntaxException e) { - log.error("Created filter was invalid:", e.message, e) - } - return null; - - } - - private def getProxyFilter() { - return '''(«SAL_SERVICE_TYPE»=«SAL_SERVICE_TYPE_CONSUMER_PROXY»)''' - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend deleted file mode 100644 index d1ec35157f..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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; - -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.osgi.framework.BundleContext; - -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.BindingAwareBroker.RpcRegistration -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality -import static com.google.common.base.Preconditions.* - -class OsgiProviderContext extends OsgiConsumerContext implements ProviderContext { - - @Property - val Map, RpcRegistration> registeredServices - - new(BundleContext ctx, BindingAwareBrokerImpl broker) { - super(ctx, broker); - _registeredServices = new HashMap(); - } - - override addRpcImplementation(Class type, T implementation) { - val salReg = broker.addRpcImplementation(type, implementation) - registeredServices.put(type, salReg) - return salReg; - } - - override addRoutedRpcImplementation(Class type, T implementation) throws IllegalStateException { - val salReg = broker.addRoutedRpcImplementation(type, implementation) - registeredServices.put(type, salReg) - return salReg; - } - - override registerFunctionality(ProviderFunctionality functionality) { - // NOOP for now - } - - override unregisterFunctionality(ProviderFunctionality functionality) { - // NOOP for now - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java new file mode 100644 index 0000000000..35c2bee646 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java @@ -0,0 +1,174 @@ +package org.opendaylight.controller.sal.binding.impl; + +import static com.google.common.base.Preconditions.checkState; + +import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance; +import org.opendaylight.controller.md.sal.binding.util.BindingContextUtils; +import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer; +import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; +import org.opendaylight.controller.sal.binding.api.BindingAwareService; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.NotificationService; +import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.controller.sal.binding.api.data.DataBrokerService; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.controller.sal.binding.api.mount.MountProviderService; +import org.opendaylight.controller.sal.binding.api.mount.MountService; +import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Mutable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableClassToInstanceMap; + +public class RootBindingAwareBroker implements // + Mutable, // + Identifiable, // + BindingAwareBroker, AutoCloseable, + RpcProviderRegistry { + + private final static Logger LOG = LoggerFactory.getLogger(RootBindingAwareBroker.class); + + RootSalInstance controllerRoot; + + private final String identifier; + + private RpcProviderRegistry rpcBroker; + + private NotificationProviderService notificationBroker; + + private DataProviderService dataBroker; + + private MountPointManagerImpl mountManager; + + public MountPointManagerImpl getMountManager() { + return mountManager; + } + + public void setMountManager(MountPointManagerImpl mountManager) { + this.mountManager = mountManager; + } + + private ImmutableClassToInstanceMap supportedConsumerServices; + + private ImmutableClassToInstanceMap supportedProviderServices; + + public RootBindingAwareBroker(String instanceName) { + this.identifier = instanceName; + mountManager = new MountPointManagerImpl(); + } + + public String getIdentifier() { + return identifier; + } + + public RootSalInstance getRoot() { + return controllerRoot; + } + + public DataProviderService getDataBroker() { + return this.dataBroker; + } + + public NotificationProviderService getNotificationBroker() { + return this.notificationBroker; + } + + public RpcProviderRegistry getRpcProviderRegistry() { + return this.rpcBroker; + } + + public RpcProviderRegistry getRpcBroker() { + return rpcBroker; + } + + public void setRpcBroker(RpcProviderRegistry rpcBroker) { + this.rpcBroker = rpcBroker; + } + + public void setNotificationBroker(NotificationProviderService notificationBroker) { + this.notificationBroker = notificationBroker; + } + + public void setDataBroker(DataProviderService dataBroker) { + this.dataBroker = dataBroker; + } + + public void start() { + checkState(controllerRoot == null, "Binding Aware Broker was already started."); + LOG.info("Starting Binding Aware Broker: {}", identifier); + + controllerRoot = new RootSalInstance(getRpcProviderRegistry(), getNotificationBroker(), getDataBroker()); + + + supportedConsumerServices = ImmutableClassToInstanceMap. builder() + .put(NotificationService.class, getRoot()) // + .put(DataBrokerService.class, getRoot()) // + .put(RpcConsumerRegistry.class, getRoot()) // + .put(MountService.class, mountManager).build(); + + supportedProviderServices = ImmutableClassToInstanceMap. builder() + .putAll(supportedConsumerServices) + .put(NotificationProviderService.class, getRoot()) // + .put(DataProviderService.class, getRoot()) // + .put(RpcProviderRegistry.class, getRoot()) // + .put(MountProviderService.class, mountManager).build(); + } + + @Override + public ConsumerContext registerConsumer(BindingAwareConsumer consumer, BundleContext ctx) { + checkState(supportedConsumerServices != null, "Broker is not initialized."); + return BindingContextUtils.createConsumerContextAndInitialize(consumer, supportedConsumerServices); + } + + @Override + public ProviderContext registerProvider(BindingAwareProvider provider, BundleContext ctx) { + checkState(supportedProviderServices != null, "Broker is not initialized."); + return BindingContextUtils.createProviderContextAndInitialize(provider, supportedProviderServices); + } + + @Override + public void close() throws Exception { + // FIXME: Close all sessions + } + + @Override + public RoutedRpcRegistration addRoutedRpcImplementation(Class type, T implementation) + throws IllegalStateException { + return getRoot().addRoutedRpcImplementation(type, implementation); + } + + @Override + public RpcRegistration addRpcImplementation(Class type, T implementation) + throws IllegalStateException { + return getRoot().addRpcImplementation(type, implementation); + } + + @Override + public T getRpcService(Class module) { + return getRoot().getRpcService(module); + } + @Override + public >> ListenerRegistration registerRouteChangeListener( + L arg0) { + return getRoot().registerRouteChangeListener(arg0); + } + + + public class RootSalInstance extends + AbstractBindingSalProviderInstance { + + public RootSalInstance(RpcProviderRegistry rpcRegistry, NotificationProviderService notificationBroker, + DataProviderService dataBroker) { + super(rpcRegistry, notificationBroker, dataBroker); + } + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java new file mode 100644 index 0000000000..1b6c56d15d --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java @@ -0,0 +1,43 @@ +package org.opendaylight.controller.sal.binding.impl; + +import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistration; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistrator; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector; + +public class RootDataBrokerImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean { + + private final Transactions transactions = new Transactions(); + private final Data data = new Data(); + private BindingIndependentConnector bindingIndependentConnector; + private DataBrokerImplRuntimeRegistration runtimeBeanRegistration; + + public BindingIndependentConnector getBindingIndependentConnector() { + return bindingIndependentConnector; + } + + public Transactions getTransactions() { + transactions.setCreated(getCreatedTransactionsCount().get()); + transactions.setSubmitted(getSubmittedTransactionsCount().get()); + transactions.setSuccessful(getFinishedTransactionsCount().get()); + transactions.setFailed(getFailedTransactionsCount().get()); + return transactions; + } + + @Override + public Data getData() { + data.setTransactions(getTransactions()); + return data; + } + + public void setBindingIndependentConnector(BindingIndependentConnector runtimeMapping) { + this.bindingIndependentConnector = runtimeMapping; + } + + public void registerRuntimeBean(DataBrokerImplRuntimeRegistrator rootRegistrator) { + runtimeBeanRegistration = rootRegistrator.register(this); + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java index 6a17007d22..8773476cae 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java @@ -15,11 +15,11 @@ import org.opendaylight.controller.md.sal.common.impl.routing.RoutingUtils; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; 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.rpc.RpcRouter; import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator; import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper; import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; -import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier; -import org.opendaylight.controller.sal.binding.spi.RpcRouter; +import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier; import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.concepts.ListenerRegistration; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java new file mode 100644 index 0000000000..f200b4d08d --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java @@ -0,0 +1,103 @@ +package org.opendaylight.controller.sal.binding.impl.connect.dom; + +import static com.google.common.base.Preconditions.checkNotNull; + +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.impl.RootBindingAwareBroker; +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; +import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; +import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService; + +public class BindingDomConnectorDeployer { + + private static BindingIndependentMappingService mappingService; + + public static BindingIndependentConnector tryToDeployConnector(RootBindingAwareBroker baBroker, + ProviderSession domSession) { + checkNotNull(baBroker); + checkNotNull(domSession); + BindingIndependentConnector connector = createConnector(mappingService); + return connector; + } + + public static BindingIndependentConnector createConnector(BindingIndependentMappingService mappingService) { + BindingIndependentConnector connector = new BindingIndependentConnector(); + connector.setMappingService(mappingService); + return connector; + } + + public static BindingIndependentConnector createConnector(BindingIndependentConnector source) { + BindingIndependentConnector connector = new BindingIndependentConnector(); + connector.setMappingService(source.getMappingService()); + return connector; + } + + public static void startDataForwarding(BindingIndependentConnector connector, DataProviderService baService, + ProviderSession domContext) { + startDataForwarding(connector, baService, + domContext.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class)); + } + + public static void startRpcForwarding(BindingIndependentConnector connector, + RpcProviderRegistry rpcProviderRegistry, ProviderSession domProviderContext) { + startRpcForwarding(connector, rpcProviderRegistry, domProviderContext.getService(RpcProvisionRegistry.class)); + + } + + public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService provider,ProviderSession domProviderContext) { + startNotificationForwarding(connector, provider, domProviderContext.getService(NotificationPublishService.class)); + } + + public static void startRpcForwarding(BindingIndependentConnector connector, RpcProviderRegistry baService, + RpcProvisionRegistry domService) { + if (connector.isRpcForwarding()) { + return; + } + + connector.setDomRpcRegistry(domService); + connector.setBindingRpcRegistry(baService); + connector.startRpcForwarding(); + } + + public static void startDataForwarding(BindingIndependentConnector connector, DataProviderService baService, + org.opendaylight.controller.sal.core.api.data.DataProviderService domService) { + if (connector.isDataForwarding()) { + return; + } + + connector.setBindingDataService(baService); + connector.setDomDataService(domService); + connector.startDataForwarding(); + } + + public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService baService, NotificationPublishService domService) { + if(connector.isNotificationForwarding()) { + return; + } + + // FIXME + } + + // + // public static BindingIndependentMappingService getGlobalMappingService() + // { + // return mappingService; + // } + // + // protected static BindingIndependentMappingService + // setGlobalMappingService(BindingIndependentMappingService service) { + // mappingService= service; + // return mappingService; + // } + // + // public static BindingIndependentConnector + // tryToDeployConnector(MountProviderInstance baMount,MountProvisionInstance + // domMount) { + // + // + // return null; + // } + +} 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..75b0138e7c 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,12 +1,9 @@ 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 java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; @@ -18,21 +15,23 @@ 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.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; 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.api.rpc.RpcRouter; 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.binding.api.rpc.RpcContextIdentifier; +import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions; 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; @@ -49,7 +48,6 @@ 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; @@ -65,7 +63,6 @@ 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, // @@ -96,7 +93,7 @@ public class BindingIndependentConnector implements // private Registration> biCommitHandlerRegistration; private RpcProvisionRegistry biRpcRegistry; - private RpcProviderRegistryImpl baRpcRegistry; + private RpcProviderRegistry baRpcRegistry; private ListenerRegistration domToBindingRpcManager; // private ListenerRegistration @@ -111,6 +108,14 @@ public class BindingIndependentConnector implements // }; + private Registration, DataObject>> baDataReaderRegistration; + + private boolean rpcForwarding = false; + + private boolean dataForwarding = false; + + private boolean notificationForwarding = false; + @Override public DataObject readOperationalData(InstanceIdentifier path) { try { @@ -222,7 +227,7 @@ public class BindingIndependentConnector implements // return biDataService; } - public void setBiDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) { + protected void setDomDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) { this.biDataService = biDataService; } @@ -230,7 +235,7 @@ public class BindingIndependentConnector implements // return baDataService; } - public void setBaDataService(DataProviderService baDataService) { + protected void setBindingDataService(DataProviderService baDataService) { this.baDataService = baDataService; } @@ -238,23 +243,33 @@ public class BindingIndependentConnector implements // return baRpcRegistry; } - public void setRpcRegistry(RpcProviderRegistryImpl rpcRegistry) { + protected void setBindingRpcRegistry(RpcProviderRegistry rpcRegistry) { this.baRpcRegistry = rpcRegistry; } - public void start() { - baDataService.registerDataReader(ROOT, this); + 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 (baRpcRegistry != null && biRpcRegistry != null) { + dataForwarding = true; + } + + public void startRpcForwarding() { + if (baRpcRegistry != null && biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher) { + checkState(!rpcForwarding,"Connector is already forwarding RPCs"); domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager()); - + rpcForwarding = true; } } + + public void startNotificationForwarding() { + checkState(!notificationForwarding, "Connector is already forwarding notifications."); + notificationForwarding = true; + } - public void setMappingService(BindingIndependentMappingService mappingService) { + protected void setMappingService(BindingIndependentMappingService mappingService) { this.mappingService = mappingService; } @@ -265,8 +280,9 @@ public class BindingIndependentConnector implements // @Override public void onSessionInitiated(ProviderSession session) { - setBiDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class)); - start(); + setDomDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class)); + setDomRpcRegistry(session.getService(RpcProvisionRegistry.class)); + } public void onRpcRouterCreated(Class serviceType, RpcRouter router) { @@ -381,7 +397,7 @@ public class BindingIndependentConnector implements // */ if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) { - return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction); + return CommitHandlerTransactions.allwaysSuccessfulTransaction(bindingTransaction); } DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction); BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction); @@ -420,7 +436,7 @@ public class BindingIndependentConnector implements // * duplicating data. */ if (domOpenedTransactions.containsKey(identifier)) { - return CommitHandlersTransactions.allwaysSuccessfulTransaction(domTransaction); + return CommitHandlerTransactions.allwaysSuccessfulTransaction(domTransaction); } org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction); @@ -597,6 +613,7 @@ public class BindingIndependentConnector implements // @SuppressWarnings("rawtypes") private WeakReference outputClass; + @SuppressWarnings({ "rawtypes", "unchecked" }) public DefaultInvocationStrategy(Method targetMethod, Class outputClass, Class inputClass) { super(targetMethod); @@ -624,10 +641,27 @@ public class BindingIndependentConnector implements // } 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()); } + } + + public boolean isRpcForwarding() { + return rpcForwarding; + } + + public boolean isDataForwarding() { + return dataForwarding; + } + + public boolean isNotificationForwarding() { + // TODO Auto-generated method stub + return notificationForwarding; + } + public BindingIndependentMappingService getMappingService() { + return mappingService; } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java new file mode 100644 index 0000000000..630b5fa8df --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java @@ -0,0 +1,128 @@ +package org.opendaylight.controller.sal.binding.impl.connect.dom; + +import java.util.concurrent.ConcurrentMap; + +import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance; +import org.opendaylight.controller.sal.binding.api.mount.MountProviderService; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class BindingIndependentMountPointForwarder { + + private MountProvisionService domMountService; + private MountProviderService baMountService; + private BindingIndependentMappingService mappingService; + + private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager(); + private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager(); + + private ConcurrentMap, BindingIndependentConnector> connectors; + private ConcurrentMap, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded; + private ListenerRegistration domListenerRegistration; + private ListenerRegistration baListenerRegistration; + + public MountProvisionService getDomMountService() { + return domMountService; + } + + public void setDomMountService(MountProvisionService domMountService) { + this.domMountService = domMountService; + } + + public void start() { + if(domMountService != null && baMountService != null) { + domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager); + baListenerRegistration = baMountService.registerProvisionListener(bindingForwardingManager); + } + } + + private void tryToDeployConnector(InstanceIdentifier baPath, + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) { + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath); + if(previous != null) { + return; + } + MountProviderInstance baMountPoint = baMountService.getMountPoint(baPath); + MountProvisionInstance domMountPoint = domMountService.getMountPoint(biPath); + BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint); + connectors.put(baPath, connector); + connector.startDataForwarding(); + connector.startRpcForwarding(); + connector.startNotificationForwarding(); + } + + private BindingIndependentConnector createForwarder(InstanceIdentifier path, MountProviderInstance baMountPoint, + MountProvisionInstance domMountPoint) { + BindingIndependentConnector connector = new BindingIndependentConnector(); + + connector.setBindingDataService(baMountPoint); + connector.setBindingRpcRegistry(baMountPoint); + //connector.setBindingNotificationBroker(baMountPoint); + + connector.setDomDataService(domMountPoint); + connector.setDomRpcRegistry(domMountPoint); + //connector.setDomNotificationBroker(domMountPoint); + return connector; + } + + public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) { + InstanceIdentifier baPath; + try { + baPath = mappingService.fromDataDom(domPath); + BindingIndependentConnector potentialConnector = connectors.get(baPath); + if(potentialConnector != null) { + return; + } + tryToDeployConnector(baPath,domPath); + } catch (DeserializationException e) { + + } + } + + public synchronized void tryToDeployBindingForwarder(InstanceIdentifier baPath) { + BindingIndependentConnector potentialConnector =connectors.get(baPath); + if(potentialConnector != null) { + return; + } + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(baPath); + tryToDeployConnector(baPath, domPath); + } + + public synchronized void undeployBindingForwarder(InstanceIdentifier baPath) { + // FIXME: Implement closeMountPoint + } + + public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) { + // FIXME: Implement closeMountPoint + } + + private class DomMountPointForwardingManager implements MountProvisionListener { + + @Override + public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) { + tryToDeployDomForwarder(path); + } + + @Override + public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) { + undeployDomForwarder(path); + } + } + + private class BindingMountPointForwardingManager implements + org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener { + + @Override + public void onMountPointCreated(InstanceIdentifier path) { + tryToDeployBindingForwarder(path); + } + + @Override + public void onMountPointRemoved(InstanceIdentifier path) { + undeployBindingForwarder(path); + } + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java deleted file mode 100644 index d22da3038c..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.opendaylight.controller.sal.binding.impl.connect.dom; - -public class BindingIndependentRpcConnector { - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java deleted file mode 100644 index 254b8725b9..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.opendaylight.controller.sal.binding.impl.connect.dom; - -import java.util.Collections; - -import org.opendaylight.controller.md.sal.common.api.data.DataModification; -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction; -import org.opendaylight.controller.sal.common.util.Rpcs; -import org.opendaylight.yangtools.concepts.Path; -import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; - -public class CommitHandlersTransactions { - - private static class AllwaysSuccessfulTransaction

,D> implements DataCommitTransaction { - - private final DataModification modification; - - public AllwaysSuccessfulTransaction(DataModification modification) { - this.modification = modification; - } - @Override - public RpcResult rollback() throws IllegalStateException { - return Rpcs.getRpcResult(true, null, Collections.emptyList()); - } - @Override - public RpcResult finish() throws IllegalStateException { - return Rpcs.getRpcResult(true, null, Collections.emptyList()); - } - - @Override - public DataModification getModification() { - return modification; - } - } - - - public static final

,D> AllwaysSuccessfulTransaction allwaysSuccessfulTransaction(DataModification modification) { - return new AllwaysSuccessfulTransaction<>(modification); - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java new file mode 100644 index 0000000000..c715c67dd2 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java @@ -0,0 +1,166 @@ +package org.opendaylight.controller.sal.binding.impl.forward; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance; +import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService; +import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationException; +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implements DomForwardedBroker { + + private ProviderSession domProviderContext; + private BindingIndependentConnector connector; + + private MountProvisionService domMountService; + + private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager(); + private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager(); + + private ConcurrentMap, BindingIndependentConnector> connectors = new ConcurrentHashMap<>(); + private ConcurrentMap, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded = new ConcurrentHashMap<>(); + private ListenerRegistration domListenerRegistration; + private ListenerRegistration baListenerRegistration; + + + public DomForwardedBindingBrokerImpl(String instanceName) { + super(instanceName); + } + + @Override + public BindingIndependentConnector getConnector() { + return connector; + } + + @Override + public ProviderSession getDomProviderContext() { + return domProviderContext; + } + + @Override + public void setConnector(BindingIndependentConnector connector) { + this.connector = connector; + } + + @Override + public void setDomProviderContext(ProviderSession domProviderContext) { + this.domProviderContext = domProviderContext; + } + + @Override + public void startForwarding() { + BindingDomConnectorDeployer.startDataForwarding(getConnector(), getDataBroker(), getDomProviderContext()); + BindingDomConnectorDeployer.startRpcForwarding(getConnector(), getRpcProviderRegistry(), + getDomProviderContext()); + BindingDomConnectorDeployer.startNotificationForwarding(getConnector(), getNotificationBroker(), + getDomProviderContext()); + startMountpointForwarding(); + } + + private void startMountpointForwarding() { + domMountService = getDomProviderContext().getService(MountProvisionService.class); + if (domMountService != null && getMountManager() != null) { + domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager); + baListenerRegistration = getMountManager().registerProvisionListener(bindingForwardingManager); + } + } + + public MountProvisionService getDomMountService() { + return domMountService; + } + + public void setDomMountService(MountProvisionService domMountService) { + this.domMountService = domMountService; + } + + private void tryToDeployConnector(InstanceIdentifier baPath, + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) { + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath); + if (previous != null) { + return; + } + MountProviderInstance baMountPoint = getMountManager().createOrGetMountPoint(baPath); + MountProvisionInstance domMountPoint = domMountService.createOrGetMountPoint(biPath); + BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint); + connectors.put(baPath, connector); + } + + private BindingIndependentConnector createForwarder(InstanceIdentifier path, MountProviderInstance baMountPoint, + MountProvisionInstance domMountPoint) { + BindingIndependentConnector mountConnector = BindingDomConnectorDeployer.createConnector(getConnector()); + + BindingDomConnectorDeployer.startDataForwarding(mountConnector, baMountPoint, domMountPoint); + BindingDomConnectorDeployer.startRpcForwarding(mountConnector, baMountPoint, domMountPoint); + BindingDomConnectorDeployer.startNotificationForwarding(mountConnector, baMountPoint, domMountPoint); + // connector.setDomNotificationBroker(domMountPoint); + return connector; + } + + public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) { + InstanceIdentifier baPath; + try { + baPath = connector.getMappingService().fromDataDom(domPath); + BindingIndependentConnector potentialConnector = connectors.get(baPath); + if (potentialConnector != null) { + return; + } + tryToDeployConnector(baPath, domPath); + } catch (DeserializationException e) { + + } + } + + public synchronized void tryToDeployBindingForwarder(InstanceIdentifier baPath) { + BindingIndependentConnector potentialConnector = connectors.get(baPath); + if (potentialConnector != null) { + return; + } + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = connector.getMappingService().toDataDom(baPath); + tryToDeployConnector(baPath, domPath); + } + + public synchronized void undeployBindingForwarder(InstanceIdentifier baPath) { + // FIXME: Implement closeMountPoint + } + + public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) { + // FIXME: Implement closeMountPoint + } + + private class DomMountPointForwardingManager implements MountProvisionListener { + + @Override + public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) { + tryToDeployDomForwarder(path); + } + + @Override + public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) { + undeployDomForwarder(path); + } + } + + private class BindingMountPointForwardingManager implements + org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener { + + @Override + public void onMountPointCreated(InstanceIdentifier path) { + tryToDeployBindingForwarder(path); + } + + @Override + public void onMountPointRemoved(InstanceIdentifier path) { + undeployBindingForwarder(path); + } + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java new file mode 100644 index 0000000000..c7dbcd4f5c --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java @@ -0,0 +1,17 @@ +package org.opendaylight.controller.sal.binding.impl.forward; + +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector; +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; + +interface DomForwardedBroker { + + public BindingIndependentConnector getConnector(); + + public void setConnector(BindingIndependentConnector connector); + + public void setDomProviderContext(ProviderSession domProviderContext); + + public ProviderSession getDomProviderContext(); + + void startForwarding(); +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java new file mode 100644 index 0000000000..f90a4acf2a --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java @@ -0,0 +1,49 @@ +package org.opendaylight.controller.sal.binding.impl.forward; + +import java.util.Collection; +import java.util.Collections; + +import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector; +import org.opendaylight.controller.sal.core.api.Provider; +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; + +public class DomForwardedDataBrokerImpl extends RootDataBrokerImpl implements Provider, DomForwardedBroker { + + private BindingIndependentConnector connector; + private ProviderSession domProviderContext; + + public void setConnector(BindingIndependentConnector connector) { + this.connector = connector; + } + + @Override + public void onSessionInitiated(ProviderSession session) { + this.setDomProviderContext(session); + } + + @Override + public Collection getProviderFunctionality() { + return Collections.emptySet(); + } + + @Override + public BindingIndependentConnector getConnector() { + return connector; + } + + @Override + public ProviderSession getDomProviderContext() { + return domProviderContext; + } + + public void setDomProviderContext(ProviderSession domProviderContext) { + this.domProviderContext = domProviderContext; + } + + @Override + public void startForwarding() { + BindingDomConnectorDeployer.startDataForwarding(getConnector(), this, getDomProviderContext()); + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java new file mode 100644 index 0000000000..581b217bfa --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java @@ -0,0 +1,25 @@ +package org.opendaylight.controller.sal.binding.impl.forward; + +import com.google.common.base.Preconditions; + +public class DomForwardingUtils { + + public static boolean isDomForwardedBroker(Object obj) { + return obj instanceof DomForwardedBroker; + } + + public static void reuseForwardingFrom(Object target,Object source) { + Preconditions.checkArgument(isDomForwardedBroker(source)); + Preconditions.checkArgument(isDomForwardedBroker(target)); + DomForwardedBroker forwardedSource = (DomForwardedBroker) source; + DomForwardedBroker forwardedTarget = (DomForwardedBroker) target; + reuseForwardingFrom(forwardedTarget, forwardedSource); + + } + + private static void reuseForwardingFrom(DomForwardedBroker target, DomForwardedBroker source) { + target.setConnector(source.getConnector()); + target.setDomProviderContext(source.getDomProviderContext()); + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend deleted file mode 100644 index 9fb2140e83..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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.osgi - -class Constants { - - private new() { - } - - public static val SAL_SERVICE_TYPE = "salServiceType" - public static val SAL_SERVICE_TYPE_CONSUMER_PROXY = "consumerProxy" - public static val SAL_SERVICE_TYPE_PROVIDER = "provider" - public static val SAL_SERVICE_TYPE_CONNECTOR = "connector" -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend deleted file mode 100644 index d04ca7f4ce..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.osgi - -import java.util.Hashtable -import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.* - -class PropertiesUtils { - - private new() { - } - - static def setSalServiceType(Hashtable properties, String value) { - properties.put(SAL_SERVICE_TYPE, value) - return properties - } - - static def getSalServiceType(Hashtable properties) { - return properties.get(SAL_SERVICE_TYPE) - } - - static def newProperties() { - new Hashtable() - } - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java deleted file mode 100644 index d788ccf3a3..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * 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.osgi; \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java deleted file mode 100644 index 49e056b100..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.opendaylight.controller.sal.binding.spi; - -public class RoutingContext { - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang b/opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang index b040aa025e..b0d1629a73 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang +++ b/opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang @@ -85,10 +85,10 @@ module opendaylight-sal-binding-broker-impl { config:required-identity sal:binding-notification-service; } } - } + } } } - + augment "/config:modules/config:module/config:configuration" { case binding-data-broker { when "/config:modules/config:module/config:type = 'binding-data-broker'"; @@ -100,6 +100,7 @@ module opendaylight-sal-binding-broker-impl { } } } + container mapping-service { uses config:service-ref { refine type { diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java index 6f0db4cd8d..20181a62c8 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java @@ -16,11 +16,11 @@ import org.junit.Test; import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.*; import org.opendaylight.controller.sal.binding.api.NotificationListener; +import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter; +import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable; import org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator; import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory; import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker; -import org.opendaylight.controller.sal.binding.spi.RpcRouter; -import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable; import org.opendaylight.controller.sal.binding.test.mock.BarListener; import org.opendaylight.controller.sal.binding.test.mock.BarUpdate; import org.opendaylight.controller.sal.binding.test.mock.CompositeListener; diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java index d4d27a14ec..c03d851f5c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java @@ -4,26 +4,44 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.concurrent.Future; import javassist.ClassPool; +import org.eclipse.xtext.xbase.lib.Pure; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.controller.sal.binding.api.mount.MountProviderService; import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl; -import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl; import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl; import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl; +import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker; +import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer; import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector; import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService; +import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl; import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest; +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; +import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration; +import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration; +import org.opendaylight.controller.sal.core.api.BrokerService; 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.DataStore; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; +import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService; import org.opendaylight.controller.sal.dom.broker.BrokerImpl; +import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl; import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper; import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore; import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl; import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; @@ -33,26 +51,26 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Predicate; +import com.google.common.collect.ClassToInstanceMap; +import com.google.common.collect.ImmutableClassToInstanceMap; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import static com.google.common.base.Preconditions.*; public class BindingTestContext implements AutoCloseable { - - + public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier .builder().toInstance(); private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class); - + private RuntimeGeneratedMappingServiceImpl mappingServiceImpl; - - - private BindingAwareBrokerImpl baBrokerImpl; + + private DomForwardedBindingBrokerImpl baBrokerImpl; private DataBrokerImpl baDataImpl; private NotificationBrokerImpl baNotifyImpl; - private BindingIndependentConnector baConnectDataServiceImpl; + private BindingIndependentConnector baConnectImpl; private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl; private BrokerImpl biBrokerImpl; @@ -61,15 +79,15 @@ public class BindingTestContext implements AutoCloseable { private DataStoreStatsWrapper dataStoreStats; private DataStore dataStore; - private boolean dataStoreStatisticsEnabled = false; - + private final ListeningExecutorService executor; private final ClassPool classPool; private final boolean startWithSchema; - + private MountPointManagerImpl biMountImpl; + protected BindingTestContext(ListeningExecutorService executor, ClassPool classPool, boolean startWithSchema) { this.executor = executor; this.classPool = classPool; @@ -82,74 +100,133 @@ public class BindingTestContext implements AutoCloseable { rawDataStore = new HashMapDataStore(); schemaAwareDataStore = new SchemaAwareDataStoreAdapter(); schemaAwareDataStore.changeDelegate(rawDataStore); - if(dataStoreStatisticsEnabled) { - dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore); - dataStore = dataStoreStats; + if (dataStoreStatisticsEnabled) { + dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore); + dataStore = dataStoreStats; } else { dataStore = schemaAwareDataStore; } - + biDataImpl.registerConfigurationReader(TREE_ROOT, dataStore); biDataImpl.registerOperationalReader(TREE_ROOT, dataStore); biDataImpl.registerCommitHandler(TREE_ROOT, dataStore); } - + public void startDomDataBroker() { - checkState(executor != null,"Executor needs to be set"); + checkState(executor != null, "Executor needs to be set"); biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl(); biDataImpl.setExecutor(executor); } - + public void startBindingDataBroker() { - checkState(executor != null,"Executor needs to be set"); + checkState(executor != null, "Executor needs to be set"); baDataImpl = new DataBrokerImpl(); baDataImpl.setExecutor(executor); } - + public void startBindingBroker() { - checkState(executor != null,"Executor needs to be set"); - checkState(baDataImpl != null,"Binding Data Broker must be started"); + 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("test",null); - + baBrokerImpl = new DomForwardedBindingBrokerImpl("test"); + + baBrokerImpl.getMountManager().setDataCommitExecutor(executor); + baBrokerImpl.getMountManager().setNotificationExecutor(executor); + baBrokerImpl.setRpcBroker(new RpcProviderRegistryImpl("test")); baBrokerImpl.setDataBroker(baDataImpl); - baBrokerImpl.setNotifyBroker(baNotifyImpl); - + baBrokerImpl.setNotificationBroker(baNotifyImpl); baBrokerImpl.start(); } - - public void startBindingToDomDataConnector() { - checkState(baDataImpl != null,"Binding Data Broker needs to be started"); - checkState(biDataImpl != null,"DOM Data Broker needs to be started."); - checkState(mappingServiceImpl != null,"DOM Mapping Service needs to be started."); - baConnectDataServiceImpl = new BindingIndependentConnector(); - baConnectDataServiceImpl.setRpcRegistry(baBrokerImpl); - baConnectDataServiceImpl.setDomRpcRegistry(getDomRpcRegistry()); - baConnectDataServiceImpl.setBaDataService(baDataImpl); - baConnectDataServiceImpl.setBiDataService(biDataImpl); - baConnectDataServiceImpl.setMappingService(mappingServiceImpl); - baConnectDataServiceImpl.start(); + + public void startForwarding() { + checkState(baDataImpl != null, "Binding Data Broker needs to be started"); + checkState(biDataImpl != null, "DOM Data Broker needs to be started."); + checkState(mappingServiceImpl != null, "DOM Mapping Service needs to be started."); + + baConnectImpl = BindingDomConnectorDeployer.createConnector(getBindingToDomMappingService()); + baConnectImpl.setDomRpcRegistry(getDomRpcRegistry()); + baBrokerImpl.setConnector(baConnectImpl); + baBrokerImpl.setDomProviderContext(createMockContext()); + baBrokerImpl.startForwarding(); } - + + private ProviderSession createMockContext() { + // TODO Auto-generated method stub + final ClassToInstanceMap domBrokerServices = ImmutableClassToInstanceMap + . builder() + // + .put(org.opendaylight.controller.sal.core.api.data.DataProviderService.class, biDataImpl) // + .put(RpcProvisionRegistry.class, biBrokerImpl.getRouter()) // + .put(MountProvisionService.class, biMountImpl) // + .build(); + + return new ProviderSession() { + + @Override + public Future> rpc(QName rpc, CompositeNode input) { + throw new UnsupportedOperationException(); + } + + @Override + public T getService(Class service) { + return domBrokerServices.getInstance(service); + } + + @Override + public boolean isClosed() { + return false; + } + + @Override + public Set getSupportedRpcs() { + return null; + } + + @Override + public void close() { + } + + @Override + public ListenerRegistration addRpcRegistrationListener( + RpcRegistrationListener listener) { + return null; + } + + @Override + public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation) + throws IllegalArgumentException { + return null; + } + + @Override + public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) { + return null; + } + + @Override + public RoutedRpcRegistration addMountedRpcImplementation(QName rpcType, RpcImplementation implementation) { + return null; + } + }; + } + public void startBindingToDomMappingService() { - checkState(classPool != null,"ClassPool needs to be present"); + checkState(classPool != null, "ClassPool needs to be present"); mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl(); mappingServiceImpl.setPool(classPool); mappingServiceImpl.start(null); } - - + public void updateYangSchema(String[] files) { SchemaContext context = getContext(files); - if(schemaAwareDataStore != null) { + if (schemaAwareDataStore != null) { schemaAwareDataStore.onGlobalContextUpdated(context); } - if(mappingServiceImpl != null) { + if (mappingServiceImpl != null) { mappingServiceImpl.onGlobalContextUpdated(context); } } - - + public static String[] getAllYangFilesOnClasspath() { Predicate predicate = new Predicate() { @Override @@ -161,7 +238,7 @@ public class BindingTestContext implements AutoCloseable { Set result = reflection.getResources(predicate); return (String[]) result.toArray(new String[result.size()]); } - + private static SchemaContext getContext(String[] yangFiles) { ClassLoader loader = BindingTestContext.class.getClassLoader(); List streams = new ArrayList<>(); @@ -173,7 +250,7 @@ public class BindingTestContext implements AutoCloseable { Set modules = parser.parseYangModelsFromStreams(streams); return parser.resolveSchemaContext(modules); } - + public void start() { startBindingDataBroker(); startBindingNotificationBroker(); @@ -181,13 +258,19 @@ public class BindingTestContext implements AutoCloseable { startDomDataBroker(); startDomDataStore(); startDomBroker(); + startDomMountPoint(); startBindingToDomMappingService(); - startBindingToDomDataConnector(); - if(startWithSchema) { + startForwarding(); + if (startWithSchema) { loadYangSchemaFromClasspath(); } } + private void startDomMountPoint() { + biMountImpl = new MountPointManagerImpl(); + biMountImpl.setDataBroker(getDomDataBroker()); + } + private void startDomBroker() { checkState(executor != null); biBrokerImpl = new BrokerImpl(); @@ -198,7 +281,7 @@ public class BindingTestContext implements AutoCloseable { public void startBindingNotificationBroker() { checkState(executor != null); baNotifyImpl = new NotificationBrokerImpl(executor); - + } public void loadYangSchemaFromClasspath() { @@ -223,10 +306,10 @@ public class BindingTestContext implements AutoCloseable { } public void logDataStoreStatistics() { - if(dataStoreStats == null) { + if (dataStoreStats == null) { return; } - + LOG.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms", dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(), dataStoreStats.getConfigurationReadAverageTime()); @@ -241,22 +324,30 @@ public class BindingTestContext implements AutoCloseable { } public RpcProviderRegistry getBindingRpcRegistry() { - return baBrokerImpl; + return baBrokerImpl.getRoot(); } public RpcProvisionRegistry getDomRpcRegistry() { - if(biBrokerImpl == null) { + if (biBrokerImpl == null) { return null; } return biBrokerImpl.getRouter(); } - + public RpcImplementation getDomRpcInvoker() { return biBrokerImpl.getRouter(); } - + @Override public void close() throws Exception { - + + } + + public MountProviderService getBindingMountProviderService() { + return baBrokerImpl.getMountManager(); + } + + public MountProvisionService getDomMountProviderService() { + return biMountImpl; } } diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java index 55bff1a5c7..0258c3e439 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java @@ -5,7 +5,7 @@ import org.junit.Test; 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.DataModification; -import org.opendaylight.controller.sal.binding.impl.connect.dom.CommitHandlersTransactions; +import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions; import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest; import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpVersion; @@ -136,7 +136,7 @@ public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest { public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction, DataObject> requestCommit( DataModification, DataObject> modification) { modificationCapture = modification; - return CommitHandlersTransactions.allwaysSuccessfulTransaction(modification); + return CommitHandlerTransactions.allwaysSuccessfulTransaction(modification); } }; diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java new file mode 100644 index 0000000000..a99d80ff30 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java @@ -0,0 +1,154 @@ +package org.opendaylight.controller.sal.binding.test.connect.dom; + +import static junit.framework.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; + +import java.math.BigInteger; +import java.util.Collections; +import java.util.Map; + +import javax.management.Notification; + +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.controller.md.sal.common.api.data.DataModification; +import org.opendaylight.controller.md.sal.common.api.data.DataReader; +import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance; +import org.opendaylight.controller.sal.binding.api.mount.MountProviderService; +import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory; +import org.opendaylight.controller.sal.binding.test.util.BindingTestContext; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; +import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; + +import com.google.common.collect.ImmutableMap; +import com.google.common.util.concurrent.MoreExecutors; + +public class CrossBrokerMountPointTest { + + private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id"); + private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id"); + private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node"); + private static final QName TABLE_ID_QNAME = QName.create(Table.QNAME, "id"); + + private static final String NODE_ID = "node:1"; + + private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID)); + + private static final Map NODE_KEY_BI = Collections. singletonMap(NODE_ID_QNAME, + NODE_ID); + + private static final InstanceIdentifier NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) // + .child(Node.class, NODE_KEY).toInstance(); + private static GroupKey GROUP_KEY = new GroupKey(new GroupId(0L)); + + private static final InstanceIdentifier GROUP_STATISTICS_ID_BA = InstanceIdentifier + .builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class) // + .child(Group.class, GROUP_KEY) // + .augmentation(NodeGroupStatistics.class) // + .child(GroupStatistics.class) // + .toInstance(); + + private static final QName AUGMENTED_GROUP_STATISTICS = QName.create(NodeGroupStatistics.QNAME, + GroupStatistics.QNAME.getLocalName()); + + private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = // + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() // + .node(Nodes.QNAME) // + .nodeWithKey(Node.QNAME, NODE_KEY_BI) // + .toInstance(); + + private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier GROUP_STATISTICS_ID_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier + // + .builder(NODE_INSTANCE_ID_BI) + .nodeWithKey(QName.create(FlowCapableNode.QNAME, "group"), QName.create(FlowCapableNode.QNAME, "group-id"), + 0L).node(AUGMENTED_GROUP_STATISTICS).toInstance(); + + private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA); + + private BindingTestContext testContext; + private MountProviderService bindingMountPointService; + private MountProvisionService domMountPointService; + + @Before + public void setup() { + BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory(); + testFactory.setExecutor(MoreExecutors.sameThreadExecutor()); + testFactory.setStartWithParsedSchema(true); + testContext = testFactory.getTestContext(); + + testContext.start(); + bindingMountPointService = testContext.getBindingMountProviderService(); + domMountPointService = testContext.getDomMountProviderService(); + + // biRpcInvoker = testContext.getDomRpcInvoker(); + assertNotNull(bindingMountPointService); + assertNotNull(domMountPointService); + + // flowService = MessageCapturingFlowService.create(baRpcRegistry); + } + + @Test + public void testMountPoint() { + + testContext.getBindingDataBroker().readOperationalData(NODE_INSTANCE_ID_BA); + + MountProvisionInstance domMountPoint = domMountPointService.createMountPoint(NODE_INSTANCE_ID_BI); + assertNotNull(domMountPoint); + MountProviderInstance bindingMountPoint = bindingMountPointService.getMountPoint(NODE_INSTANCE_ID_BA); + assertNotNull(bindingMountPoint); + + final BigInteger packetCount = BigInteger.valueOf(500L); + + + DataReader simpleReader = new DataReader() { + + @Override + public CompositeNode readConfigurationData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) { + return null; + } + + + @Override + public CompositeNode readOperationalData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) { + if (arg0.equals(GROUP_STATISTICS_ID_BI)) { + ImmutableCompositeNode data = ImmutableCompositeNode + .builder() + .setQName(AUGMENTED_GROUP_STATISTICS) + .addLeaf(QName.create(AUGMENTED_GROUP_STATISTICS, "packet-count"), packetCount) // + .toInstance(); + + return data; + } + return null; + } + + }; + domMountPoint.registerOperationalReader(NODE_INSTANCE_ID_BI, simpleReader); + + GroupStatistics data = (GroupStatistics) bindingMountPoint.readOperationalData(GROUP_STATISTICS_ID_BA); + assertNotNull(data); + assertEquals(packetCount,data.getPacketCount().getValue()); + } +} diff --git a/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java b/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java index 112b57cd33..c943226cca 100644 --- a/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java +++ b/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java @@ -87,6 +87,7 @@ public class TestHelper { mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), // // mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(), // mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), // // + mavenBundle(CONTROLLER, "sal-binding-util").versionAsInProject(), // mavenBundle("org.javassist", "javassist").versionAsInProject(), // // mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), // // diff --git a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java index 6fec18033f..2f86ee4cc2 100644 --- a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java +++ b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java @@ -5,13 +5,16 @@ import static org.junit.Assert.assertNotNull; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; +import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality; import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer; +import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; import org.opendaylight.controller.sal.binding.api.NotificationService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded; @@ -24,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalF import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.NotificationListener; +import org.opendaylight.yangtools.yang.binding.RpcService; public class NoficationTest extends AbstractTest { @@ -95,16 +99,36 @@ public class NoficationTest extends AbstractTest { * The registration of the Consumer 2. SalFlowListener is registered * registered as notification listener. */ - BindingAwareConsumer consumer2 = new BindingAwareConsumer() { + BindingAwareProvider provider = new BindingAwareProvider() { + @Override - public void onSessionInitialized(ConsumerContext session) { + public void onSessionInitiated(ProviderContext session) { listener2Reg = session.getSALService(NotificationProviderService.class).registerNotificationListener( listener2); } + + @Override + public void onSessionInitialized(ConsumerContext session) { + // TODO Auto-generated method stub + + } + + @Override + public Collection getImplementations() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Collection getFunctionality() { + // TODO Auto-generated method stub + return null; + } + }; // registerConsumer method calls onSessionInitialized method above - broker.registerConsumer(consumer2, getBundleContext()); + broker.registerProvider(provider, getBundleContext()); /** * 3 notifications are published diff --git a/opendaylight/md-sal/sal-binding-util/pom.xml b/opendaylight/md-sal/sal-binding-util/pom.xml index 26041ea85e..67c10f4a04 100644 --- a/opendaylight/md-sal/sal-binding-util/pom.xml +++ b/opendaylight/md-sal/sal-binding-util/pom.xml @@ -24,10 +24,5 @@ sal-binding-api 1.0-SNAPSHOT - - org.apache.felix - org.apache.felix.dependencymanager - 3.1.0 - diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java new file mode 100644 index 0000000000..ff6f6185ea --- /dev/null +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java @@ -0,0 +1,178 @@ +package org.opendaylight.controller.md.sal.binding.util; + +import java.util.concurrent.Future; +import java.util.zip.Checksum; + +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.NotificationListener; +import org.opendaylight.controller.sal.binding.api.NotificationService; +import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.controller.sal.binding.api.data.DataBrokerService; +import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.mount.MountInstance; +import org.opendaylight.controller.sal.common.DataStoreIdentifier; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.DataRoot; +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.common.RpcResult; + +import com.google.common.base.Preconditions; + +public abstract class AbstractBindingSalConsumerInstance // + implements // + RpcConsumerRegistry, // + NotificationService, // + DataBrokerService { + + private final R rpcRegistry; + private final N notificationBroker; + private final D dataBroker; + + protected final R getRpcRegistry() { + return rpcRegistry; + } + + protected final N getNotificationBroker() { + return notificationBroker; + } + + protected final D getDataBroker() { + return dataBroker; + } + + protected final R getRpcRegistryChecked() { + Preconditions.checkState(rpcRegistry != null,"Rpc Registry is not available."); + return rpcRegistry; + } + + protected final N getNotificationBrokerChecked() { + Preconditions.checkState(notificationBroker != null,"Notification Broker is not available."); + return notificationBroker; + } + + protected final D getDataBrokerChecked() { + Preconditions.checkState(dataBroker != null, "Data Broker is not available"); + return dataBroker; + } + + + protected AbstractBindingSalConsumerInstance(R rpcRegistry, N notificationBroker, D dataBroker) { + this.rpcRegistry = rpcRegistry; + this.notificationBroker = notificationBroker; + this.dataBroker = dataBroker; + } + + public T getRpcService(Class module) { + return getRpcRegistryChecked().getRpcService(module); + } + + @Deprecated + public void addNotificationListener(Class notificationType, + NotificationListener listener) { + getNotificationBrokerChecked().addNotificationListener(notificationType, listener); + } + + @Deprecated + public void addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) { + getNotificationBrokerChecked().addNotificationListener(listener); + } + + @Deprecated + public void removeNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) { + getNotificationBrokerChecked().removeNotificationListener(listener); + } + + @Deprecated + public void removeNotificationListener(Class notificationType, + NotificationListener listener) { + getNotificationBrokerChecked().removeNotificationListener(notificationType, listener); + } + + public Registration> registerNotificationListener( + Class notificationType, NotificationListener listener) { + return getNotificationBrokerChecked().registerNotificationListener(notificationType, listener); + } + + public Registration registerNotificationListener( + org.opendaylight.yangtools.yang.binding.NotificationListener listener) { + return getNotificationBrokerChecked().registerNotificationListener(listener); + } + + @Deprecated + public T getData(DataStoreIdentifier store, Class rootType) { + return getDataBrokerChecked().getData(store, rootType); + } + + @Deprecated + public T getData(DataStoreIdentifier store, T filter) { + return getDataBrokerChecked().getData(store, filter); + } + + @Deprecated + public T getCandidateData(DataStoreIdentifier store, Class rootType) { + return getDataBrokerChecked().getCandidateData(store, rootType); + } + + @Deprecated + public T getCandidateData(DataStoreIdentifier store, T filter) { + return getDataBrokerChecked().getCandidateData(store, filter); + } + + @Deprecated + public RpcResult editCandidateData(DataStoreIdentifier store, DataRoot changeSet) { + return getDataBrokerChecked().editCandidateData(store, changeSet); + } + + @Deprecated + public Future> commit(DataStoreIdentifier store) { + return getDataBrokerChecked().commit(store); + } + + @Deprecated + public DataObject getData(InstanceIdentifier data) { + return getDataBrokerChecked().getData(data); + } + + @Deprecated + public DataObject getConfigurationData(InstanceIdentifier data) { + return getDataBrokerChecked().getConfigurationData(data); + } + + public DataModificationTransaction beginTransaction() { + return getDataBrokerChecked().beginTransaction(); + } + + @Deprecated + public void registerChangeListener(InstanceIdentifier path, DataChangeListener changeListener) { + getDataBrokerChecked().registerChangeListener(path, changeListener); + } + + @Deprecated + public void unregisterChangeListener(InstanceIdentifier path, + DataChangeListener changeListener) { + getDataBrokerChecked().unregisterChangeListener(path, changeListener); + } + + @Deprecated + public DataObject readConfigurationData(InstanceIdentifier path) { + return getDataBrokerChecked().readConfigurationData(path); + } + + public DataObject readOperationalData(InstanceIdentifier path) { + return getDataBrokerChecked().readOperationalData(path); + } + + @Deprecated + public ListenerRegistration registerDataChangeListener( + InstanceIdentifier path, DataChangeListener listener) { + return getDataBrokerChecked().registerDataChangeListener(path, listener); + } +} diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java new file mode 100644 index 0000000000..278e90ee6b --- /dev/null +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java @@ -0,0 +1,95 @@ +package org.opendaylight.controller.md.sal.binding.util; + +import java.util.concurrent.ExecutorService; + +import org.opendaylight.controller.md.sal.common.api.RegistrationListener; +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler; +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration; +import org.opendaylight.controller.md.sal.common.api.data.DataReader; +import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; +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.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.mount.MountProviderInstance; +import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.Notification; +import org.opendaylight.yangtools.yang.binding.RpcService; + +public abstract class AbstractBindingSalProviderInstance // + extends AbstractBindingSalConsumerInstance // + implements // + DataProviderService, // + RpcProviderRegistry, // + NotificationProviderService { + + public AbstractBindingSalProviderInstance(R rpcRegistry, N notificationBroker, + D dataBroker) { + super(rpcRegistry, notificationBroker, dataBroker); + } + + @Override + public Registration, DataObject>> registerDataReader( + InstanceIdentifier path, + DataReader, DataObject> reader) { + return getDataBrokerChecked().registerDataReader(path, reader); + } + + @Override + public Registration, DataObject>> registerCommitHandler( + InstanceIdentifier path, + DataCommitHandler, DataObject> commitHandler) { + return getDataBrokerChecked().registerCommitHandler(path, commitHandler); + } + + @Override + public ListenerRegistration, DataObject>>> registerCommitHandlerListener( + RegistrationListener, DataObject>> commitHandlerListener) { + return getDataBrokerChecked().registerCommitHandlerListener(commitHandlerListener); + } + + @Override + public RpcRegistration addRpcImplementation(Class type, T implementation) + throws IllegalStateException { + return getRpcRegistryChecked().addRpcImplementation(type, implementation); + } + + @Override + public RoutedRpcRegistration addRoutedRpcImplementation(Class type, T implementation) + throws IllegalStateException { + return getRpcRegistryChecked().addRoutedRpcImplementation(type, implementation); + } + + @Override + @Deprecated + public void notify(Notification notification) { + getNotificationBrokerChecked().notify(notification); + } + + @Override + @Deprecated + public void notify(Notification notification, ExecutorService service) { + getNotificationBrokerChecked().notify(notification, service); + } + + @Override + public void publish(Notification notification) { + getNotificationBrokerChecked().publish(notification); + } + + @Override + public void publish(Notification notification, ExecutorService service) { + getNotificationBrokerChecked().publish(notification, service); + } + + @Override + public >> ListenerRegistration registerRouteChangeListener( + L listener) { + return getRpcRegistryChecked().registerRouteChangeListener(listener); + } +} diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java new file mode 100644 index 0000000000..6f2186be88 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java @@ -0,0 +1,143 @@ +package org.opendaylight.controller.md.sal.binding.util; + +import java.awt.image.SinglePixelPackedSampleModel; + +import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; +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.BindingAwareProvider; +import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality; +import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier; +import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer; +import org.opendaylight.controller.sal.binding.api.BindingAwareService; +import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.RpcService; + +import static com.google.common.base.Preconditions.*; + +import com.google.common.collect.ClassToInstanceMap; +import com.google.common.collect.MutableClassToInstanceMap; + +public class BindingContextUtils { + + public static ConsumerContext createConsumerContext(BindingAwareConsumer consumer, + ClassToInstanceMap serviceProvider) { + checkNotNull(consumer,"Consumer should not be null"); + checkNotNull(serviceProvider,"Service map should not be null"); + return new SingleConsumerContextImpl(serviceProvider); + } + + public static ProviderContext createProviderContext(BindingAwareProvider provider, + ClassToInstanceMap serviceProvider) { + checkNotNull(provider,"Provider should not be null"); + checkNotNull(serviceProvider,"Service map should not be null"); + return new SingleProviderContextImpl(serviceProvider); + } + + public static ConsumerContext createConsumerContextAndInitialize(BindingAwareConsumer consumer, + ClassToInstanceMap serviceProvider) { + ConsumerContext context = createConsumerContext(consumer, serviceProvider); + consumer.onSessionInitialized(context); + return context; + } + + public static ProviderContext createProviderContextAndInitialize(BindingAwareProvider provider, + ClassToInstanceMap serviceProvider) { + ProviderContext context = createProviderContext(provider, serviceProvider); + provider.onSessionInitiated(context); + return context; + } + + public static T createContextProxyOrReturnService(Class service, T instance) { + // FIXME: Create Proxy + return instance; + } + + private static class SingleConsumerContextImpl implements ConsumerContext, AutoCloseable { + + private ClassToInstanceMap alreadyRetrievedServices; + private ClassToInstanceMap serviceProvider; + + public SingleConsumerContextImpl(ClassToInstanceMap serviceProvider) { + this.alreadyRetrievedServices = MutableClassToInstanceMap.create(); + this.serviceProvider = serviceProvider; + } + + @Override + public final T getRpcService(Class module) { + return getSALService(RpcConsumerRegistry.class).getRpcService(module); + } + + @Override + public final T getSALService(Class service) { + checkNotNull(service,"Service class should not be null."); + T potential = alreadyRetrievedServices.getInstance(service); + if(potential != null) { + return potential; + } + return tryToRetrieveSalService(service); + } + + private synchronized T tryToRetrieveSalService(Class service) { + final T potential = alreadyRetrievedServices.getInstance(service); + if(potential != null) { + return potential; + } + final T requested = serviceProvider.getInstance(service); + if(requested == null) { + throw new IllegalArgumentException("Requested service "+service.getName() +" is not available."); + } + final T retrieved = BindingContextUtils.createContextProxyOrReturnService(service,requested); + alreadyRetrievedServices.put(service, retrieved); + return retrieved; + } + + @Override + public final void close() throws Exception { + alreadyRetrievedServices = null; + serviceProvider = null; + } + } + + private static class SingleProviderContextImpl extends SingleConsumerContextImpl implements ProviderContext { + + public SingleProviderContextImpl(ClassToInstanceMap serviceProvider) { + super(serviceProvider); + } + + @Override + public >> ListenerRegistration registerRouteChangeListener( + L listener) { + return getSALService(RpcProviderRegistry.class).registerRouteChangeListener(listener); + } + + @Override + public RoutedRpcRegistration addRoutedRpcImplementation(Class type, + T implementation) throws IllegalStateException { + return getSALService(RpcProviderRegistry.class).addRoutedRpcImplementation(type, implementation); + } + + @Override + public RpcRegistration addRpcImplementation(Class type, T implementation) + throws IllegalStateException { + return getSALService(RpcProviderRegistry.class).addRpcImplementation(type, implementation); + } + + @Deprecated + @Override + public void registerFunctionality(ProviderFunctionality functionality) { + // NOOP + } + + @Deprecated + @Override + public void unregisterFunctionality(ProviderFunctionality functionality) { + // NOOP + } + } +} diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java index fd81af353c..17de595a8b 100644 --- a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java @@ -6,32 +6,26 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class TypeSafeDataReader { - - private final DataReader,DataObject> delegate; - - - + private final DataReader, DataObject> delegate; + public DataReader, DataObject> getDelegate() { return delegate; } - public TypeSafeDataReader(DataReader, DataObject> delegate) { this.delegate = delegate; } - @SuppressWarnings("unchecked") public D readConfigurationData(InstanceIdentifier path) { return (D) delegate.readConfigurationData(path); } - - + @SuppressWarnings("unchecked") - public D readOperationalData(InstanceIdentifier path) { + public D readOperationalData(InstanceIdentifier path) { return (D) delegate.readOperationalData(path); } - + public static TypeSafeDataReader forReader(DataReader, DataObject> delegate) { return new TypeSafeDataReader(delegate); }