Merge "Update to new version of ADSAL components and its dependencies proposed by...
authorGiovanni Meo <gmeo@cisco.com>
Wed, 15 Jan 2014 20:54:56 +0000 (20:54 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 15 Jan 2014 20:54:56 +0000 (20:54 +0000)
71 files changed:
opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/DataPacketServiceAdapter.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcContextIdentifier.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcContextIdentifier.java with 97% similarity]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java with 98% similarity]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingContext.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java with 82% similarity]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingTable.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingTable.java with 96% similarity]
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/statistics/DataBrokerRuntimeMXBeanImpl.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/MountPointManagerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java
opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java
opendaylight/md-sal/sal-binding-util/pom.xml
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java
opendaylight/md-sal/sal-common-util/pom.xml
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/CommitHandlerTransactions.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java with 89% similarity]
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Futures.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcProvisionRegistry.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionService.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/$ModuleInfo.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java [deleted file]

index 03654ebcb223209c01b26738ccadfe4accec97a9..779a887924ca832ac9a0dcbfca23c536d723aa85 100644 (file)
@@ -23,6 +23,7 @@ enum FileType {
     plaintext, xml;
 
     public static final String XML_STORAGE_FIRST_LINE = "<" + ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME + ">";
+    private static final String XML_FILE_DEFINITION_LINE = "<?xml";
 
     static FileType getFileType(File file) {
         String firstLine = readFirstLine(file);
@@ -35,7 +36,10 @@ enum FileType {
     }
 
     private static boolean isXmlStorage(String firstLine) {
-        return firstLine.startsWith(XML_STORAGE_FIRST_LINE);
+        boolean isXml = false;
+        isXml |= firstLine.startsWith(XML_STORAGE_FIRST_LINE);
+        isXml |= firstLine.startsWith(XML_FILE_DEFINITION_LINE);
+        return isXml;
     }
 
     private static boolean isPlaintextStorage(String firstLine) {
index 2156a81787b9906b46cdcd4f83138d33feb67de1..3d19c986327154cace3b76fe06d4fed9d6718549 100644 (file)
@@ -28,8 +28,10 @@ import org.opendaylight.controller.sal.utils.GlobalConstants
 import org.opendaylight.controller.sal.utils.INodeConnectorFactory
 import org.opendaylight.controller.sal.utils.INodeFactory
 import org.opendaylight.controller.clustering.services.IClusterGlobalServices
+import org.opendaylight.controller.sal.packet.IPluginInDataPacketService
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
@@ -38,6 +40,7 @@ import org.osgi.framework.BundleContext
 
 import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
 import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider
+import org.opendaylight.controller.sal.compatibility.adsal.DataPacketServiceAdapter
 
 class ComponentActivator extends ComponentActivatorAbstractBase implements BindingAwareConsumer {
 
@@ -64,6 +67,10 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
     @Property
     TopologyProvider tpProvider = new TopologyProvider()
 
+    @Property
+    DataPacketServiceAdapter dataPacketService = new DataPacketServiceAdapter()
+
+
 
     override protected init() {
         Node.NodeIDType.registerIDType(MD_SAL_TYPE, String);
@@ -89,6 +96,7 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
 
         // Data Packet Service
         subscribe.registerNotificationListener(inventory);
+        dataPacketService.delegate = session.getRpcService(PacketProcessingService)
 
         // Inventory Service
         inventory.dataService = session.getSALService(DataBrokerService);
@@ -99,6 +107,8 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
                inventory.dataProviderService = session.getSALService(DataProviderService)
                topology.dataService = session.getSALService(DataProviderService)
                tpProvider.dataService = session.getSALService(DataProviderService)
+
+
                tpProvider.start();
 
         subscribe.registerNotificationListener(dataPacket)
@@ -113,6 +123,14 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
         configure(imp, c);
     }
 
+    override protected getImplementations() {
+        return Arrays.asList(dataPacketService)
+    }
+
+    override protected configureInstance(Component c, Object imp, String containerName) {
+        instanceConfigure(imp, c, containerName);
+    }
+
     private def dispatch configure(MDSalNodeFactory imp, Component it) {
         setInterface(INodeFactory.name, properties);
     }
@@ -154,6 +172,14 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
 
     }
 
+    private def dispatch instanceConfigure(DataPacketServiceAdapter imp, Component it, String containerName) {
+        setInterface(IPluginInDataPacketService.name, properties)
+    }
+
+    private def dispatch instanceConfigure(ComponentActivator imp, Component it, String containerName) {
+    }
+
+
     private def dispatch configure(InventoryAndReadAdapter imp, Component it) {
         setInterface(Arrays.asList(IPluginInInventoryService.name, IPluginInReadService.name), properties)
         add(
@@ -164,7 +190,7 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
         add(
             createServiceDependency() //
             .setService(IPluginOutInventoryService) //
-            .setCallbacks("setInventoryPublisher", "setInventoryPublisher") //
+            .setCallbacks("setInventoryPublisher", "unsetInventoryPublisher") //
             .setRequired(false))
         add(
             createServiceDependency() //
index 47a3d113254eee1ad85a66a63132de283fe4ac73..21af047c3d79a5cb2d6c2508e05f9121b119be71 100644 (file)
@@ -3,6 +3,8 @@ package org.opendaylight.controller.sal.compatibility
 import java.util.ArrayList
 import java.util.Collections
 import java.util.List
+import java.util.Set
+import java.util.concurrent.CopyOnWriteArrayList;
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
 import org.opendaylight.controller.sal.core.Edge
@@ -93,15 +95,23 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     @Property
     OpendaylightFlowTableStatisticsService flowTableStatisticsService;
 
-    @Property
-    IPluginOutInventoryService inventoryPublisher;
-
     @Property
     FlowTopologyDiscoveryService topologyDiscovery;
     
     @Property
-    List<IPluginOutReadService> statisticsPublisher = new ArrayList<IPluginOutReadService>();
-       
+    List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<IPluginOutReadService>();
+
+    @Property
+    List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
+
+       def setInventoryPublisher(IPluginOutInventoryService listener){
+        inventoryPublisher.add(listener);
+       }
+
+       def unsetInventoryPublisher(IPluginOutInventoryService listener){
+        inventoryPublisher.remove(listener);
+       }
+
     def setReadPublisher(IPluginOutReadService listener) {
        statisticsPublisher.add(listener);
     }
@@ -330,7 +340,7 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     override onNodeRemoved(NodeRemoved notification) {
         val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
 
-        inventoryPublisher.updateNode(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
+        publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
     }
 
     override onNodeConnectorUpdated(NodeConnectorUpdated update) {
@@ -341,7 +351,7 @@ class InventoryAndReadAdapter implements IPluginInReadService,
 
         var nodeConnector = update.nodeConnectorRef.toADNodeConnector
 
-        inventoryPublisher.updateNodeConnector(nodeConnector , updateType , update.toADNodeConnectorProperties);
+        publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
     }
 
     override onNodeUpdated(NodeUpdated notification) {
@@ -351,7 +361,7 @@ class InventoryAndReadAdapter implements IPluginInReadService,
         if ( this._dataService.readOperationalData(identifier) == null ){
             updateType = UpdateType.ADDED;
         }
-        inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
+        publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
         
                //Notify the listeners of IPluginOutReadService
         
@@ -574,4 +584,17 @@ class InventoryAndReadAdapter implements IPluginInReadService,
        override  getConfiguredNotConnectedNodes() {
         return Collections.emptySet();
        }
+
+
+       private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+           for( publisher : inventoryPublisher){
+               publisher.updateNode(node, updateType, properties);
+           }
+       }
+
+       private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+           for( publisher : inventoryPublisher){
+               publisher.updateNodeConnector(nodeConnector, updateType, properties);
+           }
+       }
 }
index aa67600124e8ebc229b46c3d391f09011b604ce7..edd3a27255d48dc27f3e67ff808a6ca7c8ce440b 100644 (file)
@@ -3,7 +3,6 @@ package org.opendaylight.controller.sal.compatibility.adsal;
 import org.opendaylight.controller.sal.compatibility.NodeMapping;
 import org.opendaylight.controller.sal.packet.IPluginInDataPacketService;
 import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.controller.sal.packet.RawPacket;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
@@ -22,8 +21,12 @@ public class DataPacketServiceAdapter implements IPluginInDataPacketService {
     private TransmitPacketInput toTransmitPacketInput(RawPacket rawPacket) {
         TransmitPacketInputBuilder builderTPIB = new TransmitPacketInputBuilder();
 
-        NodeConnectorRef egress = NodeMapping.toNodeConnectorRef(rawPacket.getOutgoingNodeConnector());
-        NodeConnectorRef ingress = NodeMapping.toNodeConnectorRef(rawPacket.getIncomingNodeConnector());
+        builderTPIB.setNode(NodeMapping.toNodeRef(rawPacket.getOutgoingNodeConnector().getNode()));
+
+        NodeConnectorRef egress = rawPacket.getOutgoingNodeConnector() == null ? null :
+                NodeMapping.toNodeConnectorRef(rawPacket.getOutgoingNodeConnector());
+        NodeConnectorRef ingress = rawPacket.getIncomingNodeConnector() == null ? null :
+                NodeMapping.toNodeConnectorRef(rawPacket.getIncomingNodeConnector());
         byte[] payload = rawPacket.getPacketData();
 
         builderTPIB.setEgress(egress);
@@ -33,4 +36,14 @@ public class DataPacketServiceAdapter implements IPluginInDataPacketService {
         return builderTPIB.build();
     }
 
+    public PacketProcessingService getDelegate() {
+        return delegate;
+    }
+
+    public void setDelegate(PacketProcessingService delegate) {
+        this.delegate = delegate;
+    }
+
+
+
 }
index e20640d4202d0bc3441d713bb3caee9a5e14e9eb..72c6b1d75d99fec54f2914b2cc201e9a527910ed 100644 (file)
@@ -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.
index 972e64faf6caa16db8c994db7c39c5682eed1539..cc764888cca932b89dacfe8210c6671147bc5f9d 100644 (file)
@@ -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<RpcContextIdentifier, InstanceIdentifier<?>> {
     /**
      * 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
      */
index d91a216baa0f66bf4d5b7c8de94460844a321f06..194c431ec0aad22a2391f20d4949f414b53bc41b 100644 (file)
@@ -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<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
+
+    public interface MountProvisionListener extends EventListener {
+
+        void onMountPointCreated(InstanceIdentifier<?> path);
+
+        void onMountPointRemoved(InstanceIdentifier<?> path);
+
+    }
 }
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 621d048dfd771694d5b479588980140e9e873066..31fed62d876ef5b8e25512023393204bf1856d02 100644 (file)
@@ -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;
 
@@ -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;
 
index 1b0f78384f1a6c166b46fed6f4f89152e276c77c..29357c04328a056c107af1671b35228970060979 100644 (file)
             <artifactId>sal-binding-api</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-util</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
index c46b0dd6b4c529d00e0fae55f862f6a0229e701b..cd45f2c8b2bf8439f19bccbd4125e3eb3d253309 100644 (file)
@@ -1,48 +1,85 @@
 /**\r
-* Generated file\r
+ * Generated file\r
 \r
-* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-broker-impl\r
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator\r
-* Generated at: Wed Nov 20 17:33:01 CET 2013\r
-*\r
-* Do not modify this file unless it is present under src/main directory\r
-*/\r
+ * Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-broker-impl\r
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator\r
+ * Generated at: Wed Nov 20 17:33:01 CET 2013\r
+ *\r
+ * Do not modify this file unless it is present under src/main directory\r
+ */\r
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;\r
 \r
-import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;\r
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;\r
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardingUtils;\r
 import org.osgi.framework.BundleContext;\r
 \r
-import com.google.common.base.Preconditions;\r
+import com.google.common.util.concurrent.MoreExecutors;\r
 \r
 /**\r
 *\r
 */\r
-public final class BindingBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule {\r
+public final class BindingBrokerImplModule extends\r
+        org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule {\r
 \r
     private BundleContext bundleContext;\r
 \r
-    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
+    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
+            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
         super(identifier, dependencyResolver);\r
     }\r
 \r
-    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {\r
+    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
+            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,\r
+            BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {\r
         super(identifier, dependencyResolver, oldModule, oldInstance);\r
     }\r
 \r
     @Override\r
-    public void validate(){\r
+    public void validate() {\r
         super.validate();\r
     }\r
 \r
     @Override\r
     public java.lang.AutoCloseable createInstance() {\r
-        BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getIdentifier().getInstanceName(),getBundleContext());\r
-        broker.setDataBroker(getDataBrokerDependency());\r
-        broker.setNotifyBroker(getNotificationServiceDependency());\r
+\r
+        RootBindingAwareBroker broker;\r
+        if (DomForwardingUtils.isDomForwardedBroker(getDataBrokerDependency())) {\r
+            broker = createForwardedBroker();\r
+        } else {\r
+            broker = createStandaloneBroker();\r
+        }\r
         broker.start();\r
         return broker;\r
     }\r
 \r
+    private RootBindingAwareBroker createStandaloneBroker() {\r
+        RootBindingAwareBroker broker = new RootBindingAwareBroker(getIdentifier().getInstanceName());\r
+\r
+        broker.setDataBroker(getDataBrokerDependency());\r
+        broker.setNotificationBroker(getNotificationServiceDependency());\r
+        broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));\r
+        return broker;\r
+    }\r
+\r
+    private RootBindingAwareBroker createForwardedBroker() {\r
+        DomForwardedBindingBrokerImpl broker = new DomForwardedBindingBrokerImpl(getIdentifier().getInstanceName());\r
+\r
+        broker.setDataBroker(getDataBrokerDependency());\r
+        broker.setNotificationBroker(getNotificationServiceDependency());\r
+        broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));\r
+\r
+        broker.getMountManager().setDataCommitExecutor(SingletonHolder.getDefaultCommitExecutor());\r
+        broker.getMountManager().setNotificationExecutor(SingletonHolder.getDefaultNotificationExecutor());\r
+\r
+\r
+        DomForwardingUtils.reuseForwardingFrom(broker, broker.getDataBroker());\r
+        broker.startForwarding();\r
+        return broker;\r
+    }\r
+\r
     public BundleContext getBundleContext() {\r
         return bundleContext;\r
     }\r
index 01dc6b8c0cd6162be049fe44d6806524da820f7a..185b37bab53a2789763979525f9455e73aaee8d3 100644 (file)
@@ -13,12 +13,16 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;\r
 import java.util.concurrent.ScheduledExecutorService;\r
 \r
-import org.opendaylight.controller.config.yang.md.sal.binding.statistics.DataBrokerRuntimeMXBeanImpl;\r
 import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter;\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;\r
 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;\r
 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl;\r
 import org.opendaylight.controller.sal.core.api.Broker;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;\r
 import org.opendaylight.yangtools.yang.binding.DataObject;\r
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
@@ -52,25 +56,38 @@ public final class DataBrokerImplModule extends
 \r
     @Override\r
     public java.lang.AutoCloseable createInstance() {\r
-        DataBrokerRuntimeMXBeanImpl dataBindingBroker = new DataBrokerRuntimeMXBeanImpl();\r
+        RootDataBrokerImpl dataBindingBroker;\r
         \r
-        // FIXME: obtain via dependency management\r
-        ExecutorService executor = Executors.newCachedThreadPool();\r
-        ExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);\r
-        dataBindingBroker.setExecutor(listeningExecutor);\r
-\r
-        Broker domBroker = getDomBrokerDependency();\r
-        BindingIndependentMappingService mappingService = getMappingServiceDependency();\r
         \r
-        if (domBroker != null && mappingService != null) {\r
-            BindingIndependentConnector runtimeMapping = new BindingIndependentConnector();\r
-            runtimeMapping.setMappingService(mappingService);\r
-            runtimeMapping.setBaDataService(dataBindingBroker);\r
-            domBroker.registerProvider(runtimeMapping, getBundleContext());\r
+        ExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor();\r
+        \r
+        if (getDomBrokerDependency() != null && getMappingServiceDependency() != null) {\r
+            \r
+            dataBindingBroker = createDomConnectedBroker(listeningExecutor);\r
+        } else {\r
+            dataBindingBroker = createStandAloneBroker(listeningExecutor);\r
         }\r
-        getRootRuntimeBeanRegistratorWrapper().register(dataBindingBroker);\r
+        dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper());\r
+\r
         return dataBindingBroker;\r
     }\r
+    private RootDataBrokerImpl createStandAloneBroker(ExecutorService listeningExecutor) {\r
+        RootDataBrokerImpl broker = new RootDataBrokerImpl();\r
+        broker.setExecutor(listeningExecutor);\r
+        return broker;\r
+    }\r
+\r
+    private RootDataBrokerImpl createDomConnectedBroker(ExecutorService listeningExecutor) {\r
+        DomForwardedDataBrokerImpl forwardedBroker = new DomForwardedDataBrokerImpl();\r
+        forwardedBroker.setExecutor(listeningExecutor);\r
+        BindingIndependentConnector connector = BindingDomConnectorDeployer.createConnector(getMappingServiceDependency());\r
+        getDomBrokerDependency().registerProvider(forwardedBroker, getBundleContext());\r
+        ProviderSession domContext = forwardedBroker.getDomProviderContext();\r
+        forwardedBroker.setConnector(connector);\r
+        forwardedBroker.setDomProviderContext(domContext);\r
+        forwardedBroker.startForwarding();\r
+        return forwardedBroker;\r
+    }\r
 \r
     public BundleContext getBundleContext() {\r
         return bundleContext;\r
index e4f74deb4b3487e31f080186315bc14dc4f9d9d5..644860595e0de2f7b4974616ac341ccc363dc453 100644 (file)
@@ -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 (file)
index 5da084e..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.opendaylight.controller.config.yang.md.sal.binding.statistics;\r
-\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions;\r
-import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;\r
-\r
-public class DataBrokerRuntimeMXBeanImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean {\r
-    \r
-    private final Transactions transactions = new Transactions();\r
-    private final Data data = new Data();\r
-    \r
-    public Transactions getTransactions() {\r
-        transactions.setCreated(getCreatedTransactionsCount().get());\r
-        transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
-        transactions.setSuccessful(getFinishedTransactionsCount().get());\r
-        transactions.setFailed(getFailedTransactionsCount().get());\r
-        return transactions;\r
-    }\r
-\r
-    @Override\r
-    public Data getData() {\r
-        transactions.setCreated(getCreatedTransactionsCount().get());\r
-        transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
-        transactions.setSuccessful(getFinishedTransactionsCount().get());\r
-        transactions.setFailed(getFailedTransactionsCount().get());\r
-        data.setTransactions(transactions);\r
-        return data;\r
-    }\r
-}\r
index 7789a06fe8c734f61215805d3e5b18bd558c4916..8aff12b44a5f1b5c58dfd816f457a918b497925d 100644 (file)
@@ -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;
index 8b2db8b13cd09b175fc1269ebec693717b70aab5..d976a0cec9ac7e828b9877001d0847e4cc29dab9 100644 (file)
@@ -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<T extends RpcService> implements //
         @Override
         public void unregisterPath(Class<? extends BaseIdentity> context, InstanceIdentifier<?> path) {
             routingTables.get(context).removeRoute(path, getInstance());
-
         }
 
         @Override
index 808358fb3503c1ea38bca66951137c1353c7b64d..76318ae843ff2e7f0689aea0527250ab288756d5 100644 (file)
@@ -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;
index 266293fb6dc7f66fff5727fce78798046ced2561..446a9caf8e7fd48f415926f457c6e68abcf73745 100644 (file)
@@ -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 (file)
index b4bf3f5..0000000
+++ /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<? extends DataObject> 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 <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> registerRouteChangeListener(L listener) {
-        super.<L>registerRouteChangeListener(listener)
-    }
-    
-    override close() throws Exception {
-        
-    }
-}
\ No newline at end of file
index 5db522f56c34b6c6816b067d96441034a01dfed1..0069de98026dfa2f710e77fc3b60b3a026e6f37d 100644 (file)
@@ -3,7 +3,7 @@ package org.opendaylight.controller.sal.binding.impl;
 import java.util.Set;
 import java.util.concurrent.Future;\r
 import java.util.concurrent.atomic.AtomicLong;\r
-
+\r
 import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;\r
 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;\r
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;\r
@@ -11,12 +11,13 @@ import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderR
 import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
 import org.opendaylight.yangtools.yang.binding.DataObject;\r
 import org.opendaylight.yangtools.yang.binding.DataRoot;\r
+import org.opendaylight.yangtools.yang.binding.Identifiable;\r
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
 import org.opendaylight.yangtools.yang.common.RpcResult;\r
 \r
 \r
-public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> implements\r
-        DataProviderService, AutoCloseable {\r
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> //\r
+       implements DataProviderService, AutoCloseable {\r
 \r
     private final AtomicLong nextTransaction = new AtomicLong();\r
     private final AtomicLong createdTransactionsCount = new AtomicLong();\r
@@ -114,7 +115,6 @@ public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? exte
                 return true;
             }
         }
-
         return false;
     }\r
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/MountPointManagerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/MountPointManagerImpl.java
new file mode 100644 (file)
index 0000000..f8059fe
--- /dev/null
@@ -0,0 +1,120 @@
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+public class MountPointManagerImpl implements MountProviderService {
+
+    public final Logger LOG = LoggerFactory.getLogger(MountPointManagerImpl.class);
+
+    private final ConcurrentMap<InstanceIdentifier<?>, BindingMountPointImpl> mountPoints;
+    private final ListenerRegistry<MountProvisionListener> 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<MountProvisionListener> listener : listeners) {
+            try {
+                listener.getInstance().onMountPointCreated(path);
+            } catch (Exception e) {
+                LOG.error("Unhandled exception during invoking listener.", e);
+            }
+        }
+    }
+
+    @Override
+    public ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener) {
+        return listeners.register(listener);
+    }
+
+    public class BindingMountPointImpl extends
+            AbstractBindingSalProviderInstance<DataBrokerImpl, NotificationBrokerImpl, RpcProviderRegistryImpl>
+    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;
+        }
+    }
+}
index b0939a043f68c72f7f994fa538a005d4942f08ea..b4fd6b67712d6054b2f74737d89f3ea091aa9345 100644 (file)
@@ -175,6 +175,7 @@ class NotifyTask implements Callable<Object> {
 \r
     private static val log = LoggerFactory.getLogger(NotifyTask);\r
 \r
+    @SuppressWarnings("rawtypes")\r
     val NotificationListener listener;\r
     val Notification notification;\r
 \r
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 (file)
index 644c50b..0000000
+++ /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 <T extends BindingAwareService> getSALService(Class<T> service) {
-
-        // SAL Services are global
-        var ref = bundleContext.getServiceReference(service);
-        return bundleContext.getService(ref) as T;
-    }
-
-    override def <T extends RpcService> T getRpcService(Class<T> 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<T>;
-                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 (file)
index d1ec351..0000000
+++ /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<Class<? extends RpcService>, RpcRegistration<? extends RpcService>> registeredServices
-
-    new(BundleContext ctx, BindingAwareBrokerImpl broker) {
-        super(ctx, broker);
-        _registeredServices = new HashMap();
-    }
-
-    override <T extends RpcService> addRpcImplementation(Class<T> type, T implementation) {
-        val salReg = broker.addRpcImplementation(type, implementation)
-        registeredServices.put(type, salReg)
-        return salReg;
-    }
-
-    override <T extends RpcService> addRoutedRpcImplementation(Class<T> 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 (file)
index 0000000..35c2bee
--- /dev/null
@@ -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<String>, //
+        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<BindingAwareService> supportedConsumerServices;
+
+    private ImmutableClassToInstanceMap<BindingAwareService> 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.<BindingAwareService> builder()
+                .put(NotificationService.class, getRoot()) //
+                .put(DataBrokerService.class, getRoot()) //
+                .put(RpcConsumerRegistry.class, getRoot()) //
+                .put(MountService.class, mountManager).build();
+
+        supportedProviderServices = ImmutableClassToInstanceMap.<BindingAwareService> 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 <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type, T implementation)
+            throws IllegalStateException {
+        return getRoot().addRoutedRpcImplementation(type, implementation);
+    }
+    
+    @Override
+    public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+            throws IllegalStateException {
+        return getRoot().addRpcImplementation(type, implementation);
+    }
+    
+    @Override
+    public <T extends RpcService> T getRpcService(Class<T> module) {
+        return getRoot().getRpcService(module);
+    }
+    @Override
+    public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+            L arg0) {
+        return getRoot().registerRouteChangeListener(arg0);
+    }
+    
+
+    public class RootSalInstance extends
+            AbstractBindingSalProviderInstance<DataProviderService, NotificationProviderService, RpcProviderRegistry> {
+
+        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 (file)
index 0000000..1b6c56d
--- /dev/null
@@ -0,0 +1,43 @@
+package org.opendaylight.controller.sal.binding.impl;\r
+\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistration;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistrator;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions;\r
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
+\r
+public class RootDataBrokerImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean {\r
+\r
+    private final Transactions transactions = new Transactions();\r
+    private final Data data = new Data();\r
+    private BindingIndependentConnector bindingIndependentConnector;\r
+    private DataBrokerImplRuntimeRegistration runtimeBeanRegistration;\r
+\r
+    public BindingIndependentConnector getBindingIndependentConnector() {\r
+        return bindingIndependentConnector;\r
+    }\r
+\r
+    public Transactions getTransactions() {\r
+        transactions.setCreated(getCreatedTransactionsCount().get());\r
+        transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
+        transactions.setSuccessful(getFinishedTransactionsCount().get());\r
+        transactions.setFailed(getFailedTransactionsCount().get());\r
+        return transactions;\r
+    }\r
+\r
+    @Override\r
+    public Data getData() {\r
+        data.setTransactions(getTransactions());\r
+        return data;\r
+    }\r
+\r
+    public void setBindingIndependentConnector(BindingIndependentConnector runtimeMapping) {\r
+        this.bindingIndependentConnector = runtimeMapping;\r
+    }\r
+\r
+    public void registerRuntimeBean(DataBrokerImplRuntimeRegistrator rootRegistrator) {\r
+        runtimeBeanRegistration = rootRegistrator.register(this);\r
+    }\r
+\r
+}\r
index 6a17007d22779c81dd9a55d592fc80da73323f6f..8773476caee9ee4fd01f7b75b3b128bb331e3edd 100644 (file)
@@ -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 (file)
index 0000000..f200b4d
--- /dev/null
@@ -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;
+    // }
+
+}
index 0a769921d80410742cb22b4ad7ee8cc0e9920f0a..75b0138e7cd75657adba42182d0dc7e0cf9c270c 100644 (file)
@@ -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<DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>> biCommitHandlerRegistration;
 
     private RpcProvisionRegistry biRpcRegistry;
-    private RpcProviderRegistryImpl baRpcRegistry;
+    private RpcProviderRegistry baRpcRegistry;
 
     private ListenerRegistration<DomToBindingRpcForwardingManager> domToBindingRpcManager;
     // private ListenerRegistration<BindingToDomRpcForwardingManager>
@@ -111,6 +108,14 @@ public class BindingIndependentConnector implements //
 
     };
 
+    private Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> baDataReaderRegistration;
+
+    private boolean rpcForwarding = false;
+
+    private boolean dataForwarding = false;
+
+    private boolean notificationForwarding = false;
+
     @Override
     public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> 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 <T extends RpcService> void onRpcRouterCreated(Class<T> serviceType, RpcRouter<T> 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<Class> outputClass;
 
+        @SuppressWarnings({ "rawtypes", "unchecked" })
         public DefaultInvocationStrategy(Method targetMethod, Class<?> outputClass,
                 Class<? extends DataContainer> inputClass) {
             super(targetMethod);
@@ -624,10 +641,27 @@ public class BindingIndependentConnector implements //
         }
 
         public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
+            @SuppressWarnings("unchecked")
             Future<RpcResult<Void>> result = (Future<RpcResult<Void>>) targetMethod.invoke(rpcService);
             RpcResult<Void> 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 (file)
index 0000000..630b5fa
--- /dev/null
@@ -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<InstanceIdentifier<?>, BindingIndependentConnector> connectors;
+    private ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded;
+    private ListenerRegistration<MountProvisionListener> domListenerRegistration;
+    private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> 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 (file)
index d22da30..0000000
+++ /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/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 (file)
index 0000000..c715c67
--- /dev/null
@@ -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<InstanceIdentifier<?>, BindingIndependentConnector> connectors = new ConcurrentHashMap<>();
+    private ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded = new ConcurrentHashMap<>();
+    private ListenerRegistration<MountProvisionListener> domListenerRegistration;
+    private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> 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 (file)
index 0000000..c7dbcd4
--- /dev/null
@@ -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 (file)
index 0000000..f90a4ac
--- /dev/null
@@ -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<ProviderFunctionality> 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 (file)
index 0000000..581b217
--- /dev/null
@@ -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 (file)
index 9fb2140..0000000
+++ /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 (file)
index d04ca7f..0000000
+++ /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<String, String> properties, String value) {
-        properties.put(SAL_SERVICE_TYPE, value)
-        return properties
-    }
-
-    static def getSalServiceType(Hashtable<String, String> properties) {
-        return properties.get(SAL_SERVICE_TYPE)
-    }
-
-    static def newProperties() {
-        new Hashtable<String, String>()
-    }
-
-}
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 (file)
index d788ccf..0000000
+++ /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 (file)
index 49e056b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.opendaylight.controller.sal.binding.spi;
-
-public class RoutingContext {
-
-}
index b040aa025e2bd05450f5458922df34f85c46fa30..b0d1629a73f645333fb3aacfc3d33aae4fa562a2 100644 (file)
@@ -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 {
index 6f0db4cd8d3635d0cd43bea0e943dd7d5555fdd2..20181a62c8a8b38abc3add11873ed3452350cf89 100644 (file)
@@ -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;
index d4d27a14eceb68c3df38c8b826ae23845fb76e69..c03d851f5c9ef740a14a9097feceaf8909833184 100644 (file)
@@ -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<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
+                .<BrokerService> 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<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public <T extends BrokerService> T getService(Class<T> service) {
+                return domBrokerServices.getInstance(service);
+            }
+
+            @Override
+            public boolean isClosed() {
+                return false;
+            }
+
+            @Override
+            public Set<QName> getSupportedRpcs() {
+                return null;
+            }
+
+            @Override
+            public void close() {
+            }
+
+            @Override
+            public ListenerRegistration<RpcRegistrationListener> 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<String> predicate = new Predicate<String>() {
             @Override
@@ -161,7 +238,7 @@ public class BindingTestContext implements AutoCloseable {
         Set<String> result = reflection.getResources(predicate);
         return (String[]) result.toArray(new String[result.size()]);
     }
-    
+
     private static SchemaContext getContext(String[] yangFiles) {
         ClassLoader loader = BindingTestContext.class.getClassLoader();
         List<InputStream> streams = new ArrayList<>();
@@ -173,7 +250,7 @@ public class BindingTestContext implements AutoCloseable {
         Set<Module> 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;
     }
 }
index 55bff1a5c7d56da9a5a1eda2cb7bb21c8f37f17b..0258c3e439acde92a132406f82861e23314147df 100644 (file)
@@ -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<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
                     DataModification<InstanceIdentifier<? extends DataObject>, 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 (file)
index 0000000..a99d80f
--- /dev/null
@@ -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<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
+            NODE_ID);
+
+    private static final InstanceIdentifier<Node> 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<GroupStatistics> 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<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> simpleReader = new DataReader<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>() {
+
+            @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());
+    }
+}
index 112b57cd33fc2fbb43c08059a5274f9647574084..c943226ccac994284cef91da558f3fce973ea11f 100644 (file)
@@ -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(), // //
 
index 6fec18033f8feeed2df5dd7f040d2ddf622d63ad..2f86ee4cc2e9e34c4db55b803b565f090c7962b5 100644 (file)
@@ -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<? extends RpcService> getImplementations() {
+                // TODO Auto-generated method stub
+                return null;
+            }
+            
+            @Override
+            public Collection<? extends ProviderFunctionality> 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
index 26041ea85ec61d1f7bece2d274627fea3bd63e33..67c10f4a048405b64ca6ca58b1f7a22cdc8d9d53 100644 (file)
             <artifactId>sal-binding-api</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.dependencymanager</artifactId>
-            <version>3.1.0</version>
-        </dependency>
     </dependencies>
 </project>
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 (file)
index 0000000..ff6f618
--- /dev/null
@@ -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<D extends DataBrokerService, N extends NotificationService, R extends RpcConsumerRegistry> //
+        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 extends RpcService> T getRpcService(Class<T> module) {
+        return getRpcRegistryChecked().getRpcService(module);
+    }
+
+    @Deprecated
+    public <T extends Notification> void addNotificationListener(Class<T> notificationType,
+            NotificationListener<T> 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 <T extends Notification> void removeNotificationListener(Class<T> notificationType,
+            NotificationListener<T> listener) {
+        getNotificationBrokerChecked().removeNotificationListener(notificationType, listener);
+    }
+
+    public <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(
+            Class<T> notificationType, NotificationListener<T> listener) {
+        return getNotificationBrokerChecked().registerNotificationListener(notificationType, listener);
+    }
+
+    public Registration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(
+            org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+        return getNotificationBrokerChecked().registerNotificationListener(listener);
+    }
+
+    @Deprecated
+    public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
+        return getDataBrokerChecked().getData(store, rootType);
+    }
+
+    @Deprecated
+    public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
+        return getDataBrokerChecked().getData(store, filter);
+    }
+
+    @Deprecated
+    public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
+        return getDataBrokerChecked().getCandidateData(store, rootType);
+    }
+
+    @Deprecated
+    public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
+        return getDataBrokerChecked().getCandidateData(store, filter);
+    }
+
+    @Deprecated
+    public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
+        return getDataBrokerChecked().editCandidateData(store, changeSet);
+    }
+
+    @Deprecated
+    public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
+        return getDataBrokerChecked().commit(store);
+    }
+
+    @Deprecated
+    public DataObject getData(InstanceIdentifier<? extends DataObject> 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<? extends DataObject> path, DataChangeListener changeListener) {
+        getDataBrokerChecked().registerChangeListener(path, changeListener);
+    }
+
+    @Deprecated
+    public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path,
+            DataChangeListener changeListener) {
+        getDataBrokerChecked().unregisterChangeListener(path, changeListener);
+    }
+
+    @Deprecated
+    public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+        return getDataBrokerChecked().readConfigurationData(path);
+    }
+
+    public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+        return getDataBrokerChecked().readOperationalData(path);
+    }
+
+    @Deprecated
+    public ListenerRegistration<DataChangeListener> registerDataChangeListener(
+            InstanceIdentifier<? extends DataObject> 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 (file)
index 0000000..278e90e
--- /dev/null
@@ -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<D extends DataProviderService, N extends NotificationProviderService, R extends RpcProviderRegistry> //
+        extends AbstractBindingSalConsumerInstance<D, N, R> //
+        implements //
+        DataProviderService, //
+        RpcProviderRegistry, //
+        NotificationProviderService {
+
+    public AbstractBindingSalProviderInstance(R rpcRegistry, N notificationBroker,
+            D dataBroker) {
+        super(rpcRegistry, notificationBroker, dataBroker);
+    }
+
+    @Override
+    public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerDataReader(
+            InstanceIdentifier<? extends DataObject> path,
+            DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
+        return getDataBrokerChecked().registerDataReader(path, reader);
+    }
+
+    @Override
+    public Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> registerCommitHandler(
+            InstanceIdentifier<? extends DataObject> path,
+            DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
+        return getDataBrokerChecked().registerCommitHandler(path, commitHandler);
+    }
+
+    @Override
+    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>>> registerCommitHandlerListener(
+            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>> commitHandlerListener) {
+        return getDataBrokerChecked().registerCommitHandlerListener(commitHandlerListener);
+    }
+
+    @Override
+    public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+            throws IllegalStateException {
+        return getRpcRegistryChecked().addRpcImplementation(type, implementation);
+    }
+
+    @Override
+    public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> 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 <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> 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 (file)
index 0000000..6f2186b
--- /dev/null
@@ -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<BindingAwareService> 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<BindingAwareService> 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<BindingAwareService> serviceProvider) {
+        ConsumerContext context = createConsumerContext(consumer, serviceProvider);
+        consumer.onSessionInitialized(context);
+        return context;
+    }
+    
+    public static ProviderContext createProviderContextAndInitialize(BindingAwareProvider provider,
+            ClassToInstanceMap<BindingAwareService> serviceProvider) {
+        ProviderContext context = createProviderContext(provider, serviceProvider);
+        provider.onSessionInitiated(context);
+        return context;
+    }
+
+    public static <T extends BindingAwareService> T createContextProxyOrReturnService(Class<T> service, T instance) {
+        // FIXME: Create Proxy
+        return instance;
+    }
+    
+    private static class SingleConsumerContextImpl implements ConsumerContext, AutoCloseable {
+        
+        private ClassToInstanceMap<BindingAwareService> alreadyRetrievedServices;
+        private ClassToInstanceMap<BindingAwareService> serviceProvider;
+
+        public SingleConsumerContextImpl(ClassToInstanceMap<BindingAwareService> serviceProvider) {
+            this.alreadyRetrievedServices = MutableClassToInstanceMap.create();
+            this.serviceProvider = serviceProvider;
+        }
+
+        @Override
+        public final <T extends RpcService> T getRpcService(Class<T> module) {
+            return getSALService(RpcConsumerRegistry.class).getRpcService(module);
+        }
+        
+        @Override
+        public final <T extends BindingAwareService> T getSALService(Class<T> 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 extends BindingAwareService> T tryToRetrieveSalService(Class<T> 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<BindingAwareService> serviceProvider) {
+            super(serviceProvider);
+        }
+        
+        @Override
+        public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+                L listener) {
+            return getSALService(RpcProviderRegistry.class).registerRouteChangeListener(listener);
+        }
+        
+        @Override
+        public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type,
+                T implementation) throws IllegalStateException {
+            return getSALService(RpcProviderRegistry.class).addRoutedRpcImplementation(type, implementation);
+        }
+        
+        @Override
+        public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> 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
+        }
+    }
+}
index fd81af353ceb0d137bf9fbd527a349b6430fd20c..17de595a8b79752400ee5ba36c442d3412f8f5d6 100644 (file)
@@ -6,32 +6,26 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public final class TypeSafeDataReader {
 
-    
-    private final DataReader<InstanceIdentifier<? extends DataObject>,DataObject> delegate;
-    
-    
-    
+    private final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate;
+
     public DataReader<InstanceIdentifier<?>, DataObject> getDelegate() {
         return delegate;
     }
 
-
     public TypeSafeDataReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
         this.delegate = delegate;
     }
 
-
     @SuppressWarnings("unchecked")
     public <D extends DataObject> D readConfigurationData(InstanceIdentifier<D> path) {
         return (D) delegate.readConfigurationData(path);
     }
-    
-    
+
     @SuppressWarnings("unchecked")
-    public <D extends DataObject> D  readOperationalData(InstanceIdentifier<D> path) {
+    public <D extends DataObject> D readOperationalData(InstanceIdentifier<D> path) {
         return (D) delegate.readOperationalData(path);
     }
-    
+
     public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
         return new TypeSafeDataReader(delegate);
     }
index ff15e72ba6fc3d1106a46bfadd08dfcd2e67bd60..adbe3d2a4997e183d6ce73d2420fe67b50db8dab 100644 (file)
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-common-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
   </dependencies>
 
   <packaging>bundle</packaging>
index 2d10fba8a5fd77c18b872991669d576f9aae7a7e..902665d1a6fa137d41d7f1bc89cf8116fbb52ee1 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * 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.common.util;
 
 public class Arguments {
@@ -1,15 +1,14 @@
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
+package org.opendaylight.controller.sal.common.util;
 
 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 {
+public class CommitHandlerTransactions {
 
     private static class AllwaysSuccessfulTransaction<P extends Path<P>,D> implements DataCommitTransaction<P, D> {
         
@@ -33,7 +32,6 @@ public class CommitHandlersTransactions {
         }
     }
     
-    
     public static final <P extends Path<P>,D> AllwaysSuccessfulTransaction<P, D> allwaysSuccessfulTransaction(DataModification<P, D> modification)  {
         return new AllwaysSuccessfulTransaction<>(modification);
     }
index d9cf5cc477aa2a81cd33796dd6b5f90b488fb1b9..42b00ba03d113dbcf0eb67958f068d5370491792 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * 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.common.util;
 
 import java.util.concurrent.ExecutionException;
index c326bab7a4677bf5db471f940ad2a35768b11dc0..951d5b142e76561485c5cd7f52e12fb84a462cce 100644 (file)
@@ -4,7 +4,7 @@ import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
 
-public interface RpcProvisionRegistry {
+public interface RpcProvisionRegistry extends BrokerService {
 
     /**
      * Registers an implementation of the rpc.
index 910c7cb62365d01ca43e6d30dec43966f1a8f233..18c854646cca6aa08596a84ddaeba77959129219 100644 (file)
@@ -6,7 +6,6 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-
 package org.opendaylight.controller.sal.core.api.mount;
 
 import java.util.concurrent.Future;
@@ -18,9 +17,11 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public interface MountInstance extends NotificationService, DataBrokerService {
+public interface MountInstance extends //
+        NotificationService, //
+        DataBrokerService {
 
     Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input);
-    
+
     SchemaContext getSchemaContext();
 }
index fade7d341b2bf7d69ee0ad41ad0d4f4e64042acf..c1f873c3af4694395d8cd8a141c06814ecc11bbf 100644 (file)
@@ -1,5 +1,8 @@
 package org.opendaylight.controller.sal.core.api.mount;
 
+import java.util.EventListener;
+
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
 public interface MountProvisionService extends MountService {
@@ -10,4 +13,14 @@ public interface MountProvisionService extends MountService {
     MountProvisionInstance createMountPoint(InstanceIdentifier path);
     
     MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path);
+    
+    ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
+    
+    public  interface MountProvisionListener extends EventListener {
+        
+        void onMountPointCreated(InstanceIdentifier path);
+        
+        void onMountPointRemoved(InstanceIdentifier path);
+        
+    }
 }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/$ModuleInfo.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/$ModuleInfo.java
new file mode 100644 (file)
index 0000000..3cc5a61
--- /dev/null
@@ -0,0 +1,6 @@
+package org.opendaylight.controller.sal.dom.broker;
+
+public class $ModuleInfo {
+
+    
+}
index 56eae97848b71c9556c0eb3108c6d7f92e38b200..8f62be97d801f7a557026a1aacd054bdaf5f6936 100644 (file)
@@ -13,6 +13,8 @@ import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
+import com.google.common.util.concurrent.MoreExecutors;
+
 public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, CompositeNode, DataChangeListener> implements
         DataProviderService, AutoCloseable {
 
@@ -21,6 +23,7 @@ public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, Compo
     
     public DataBrokerImpl() {
         setDataReadRouter(new DataReaderRouter());
+        setExecutor(MoreExecutors.sameThreadExecutor());
     }
     
     public AtomicLong getCreatedTransactionsCount() {
index ab5b145064c828cfa083f74a21beff4e66e9074a..b4fccff3b0fe745ae71088942ed05e92429f5e0e 100644 (file)
@@ -36,7 +36,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 public class MountPointImpl implements MountProvisionInstance {
 
     private final RpcRouter rpcs;
-    private final DataReaderRouter dataReader;
+    private final DataBrokerImpl dataReader;
     private final NotificationRouter notificationRouter;
     private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
     
@@ -48,7 +48,7 @@ public class MountPointImpl implements MountProvisionInstance {
     public MountPointImpl(InstanceIdentifier path) {
         this.mountPath = path;
         rpcs = new RpcRouterImpl("");
-        dataReader = new DataReaderRouter();
+        dataReader = new DataBrokerImpl();
         notificationRouter = new NotificationRouterImpl();
         readWrapper = new ReadWrapper();
     }
@@ -124,15 +124,13 @@ public class MountPointImpl implements MountProvisionInstance {
 
     @Override
     public DataModificationTransaction beginTransaction() {
-        // TODO Auto-generated method stub
-        return null;
+        return dataReader.beginTransaction();
     }
 
     @Override
     public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
             DataChangeListener listener) {
-        // TODO Auto-generated method stub
-        return null;
+        return dataReader.registerDataChangeListener(path, listener);
     }
 
     @Override
@@ -143,8 +141,7 @@ public class MountPointImpl implements MountProvisionInstance {
     @Override
     public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
             InstanceIdentifier path, DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
-        // TODO Auto-generated method stub
-        return null;
+        return dataReader.registerCommitHandler(path, commitHandler);
     }
     
     @Override
@@ -208,7 +205,6 @@ public class MountPointImpl implements MountProvisionInstance {
     @Override
     public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
             RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
-        // TODO Auto-generated method stub
-        return null;
+        return dataReader.registerCommitHandlerListener(commitHandlerListener);
     }
 }
index 19634d79c2203fafe5aaa0156c41bf45a62f905f..5d441bddbd0f23e263c452695da13afe9ecacc3e 100644 (file)
@@ -7,12 +7,16 @@ import java.util.concurrent.ConcurrentMap
 import java.util.concurrent.ConcurrentHashMap
 import static com.google.common.base.Preconditions.*;
 import org.opendaylight.controller.sal.core.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry
 
 class MountPointManagerImpl implements MountProvisionService {
     
     @Property
     DataProviderService dataBroker;
     
+    val ListenerRegistry<MountProvisionListener> listeners = ListenerRegistry.create()
+    
     ConcurrentMap<InstanceIdentifier,MountPointImpl> mounts = new ConcurrentHashMap();
     
     override createMountPoint(InstanceIdentifier path) {
@@ -20,15 +24,26 @@ class MountPointManagerImpl implements MountProvisionService {
         val mount = new MountPointImpl(path);
         registerMountPoint(mount);
         mounts.put(path,mount);
+        notifyMountCreated(path);
         return mount;
     }
     
+    def notifyMountCreated(InstanceIdentifier identifier) {
+        for(listener : listeners) {
+            listener.instance.onMountPointCreated(identifier);
+        }
+    }
+    
     def registerMountPoint(MountPointImpl impl) {
         dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
         dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
         
     }
     
+    override registerProvisionListener(MountProvisionListener listener) {
+        listeners.register(listener)
+    }
+    
     
     override createOrGetMountPoint(InstanceIdentifier path) {
         val mount = mounts.get(path);
index 0d18cb323a8dace4eda4ab023de87fa433d638ed..0021dd8f0f3a707a282ccd1831dc332e1dfadd73 100644 (file)
@@ -3,6 +3,7 @@ package org.opendaylight.controller.sal.dom.broker.osgi;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.osgi.framework.ServiceReference;
 
@@ -24,4 +25,9 @@ public class MountProviderServiceProxy extends AbstractBrokerServiceProxy<MountP
     public MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path) {
         return getDelegate().createOrGetMountPoint(path);
     }
+    
+    @Override
+    public ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener) {
+        return getDelegate().registerProvisionListener(listener);
+    }
 }
index bfe352ad41322cf78404426a5582afc22a4e074d..da0790c599763318412dbe630a1508d30064326e 100644 (file)
@@ -1,61 +1,55 @@
 package org.opendaylight.controller.sal.connect.netconf
 
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.controller.netconf.client.NetconfClient
-import org.opendaylight.controller.sal.core.api.RpcImplementation
-import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
+import com.google.common.base.Optional
+import com.google.common.collect.FluentIterable
+import io.netty.util.concurrent.EventExecutor
+import java.io.InputStream
 import java.net.InetSocketAddress
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.api.SimpleNode
-import org.opendaylight.yangtools.yang.common.QName
+import java.net.URI
 import java.util.Collections
+import java.util.List
+import java.util.Set
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Future
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.controller.netconf.api.NetconfMessage
+import org.opendaylight.controller.netconf.client.NetconfClient
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.controller.sal.core.api.Provider
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
-import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
+import org.opendaylight.controller.sal.core.api.Provider
+import org.opendaylight.controller.sal.core.api.RpcImplementation
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService
 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
 import org.opendaylight.protocol.framework.ReconnectStrategy
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import com.google.common.collect.FluentIterable
-import org.opendaylight.yangtools.yang.model.api.SchemaContext
-import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders
+import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
-import java.io.InputStream
-import org.slf4j.LoggerFactory
+import org.opendaylight.yangtools.yang.parser.impl.util.YangSourceContext
 import org.slf4j.Logger
-import org.opendaylight.controller.netconf.client.AbstractNetconfClientNotifySessionListener
-import org.opendaylight.controller.netconf.client.NetconfClientSession
-import org.opendaylight.controller.netconf.api.NetconfMessage
-import io.netty.util.concurrent.EventExecutor
+import org.slf4j.LoggerFactory
 
-import java.util.Map
-import java.util.Set
-import com.google.common.collect.ImmutableMap
+import static com.google.common.base.Preconditions.*
+import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*
 
-import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider
-import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider
-import com.google.common.base.Optional
-import com.google.common.collect.ImmutableList
-import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders
-import static com.google.common.base.Preconditions.*;
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Future
-import org.opendaylight.controller.netconf.client.NetconfClientSessionListener
-import io.netty.util.concurrent.Promise
-import org.opendaylight.controller.netconf.util.xml.XmlElement
-import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants
-import java.util.concurrent.ExecutionException
-import java.util.concurrent.locks.ReentrantLock
+import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
+import org.opendaylight.controller.netconf.util.xml.XmlUtil
 
 class NetconfDevice implements Provider, // 
 DataReader<InstanceIdentifier, CompositeNode>, //
@@ -86,7 +80,8 @@ AutoCloseable {
     @Property
     var AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider;
 
-    private NetconfDeviceSchemaContextProvider schemaContextProvider
+    @Property
+    private NetconfDeviceSchemaContextProvider deviceContextProvider
 
     protected val Logger logger
 
@@ -105,9 +100,12 @@ AutoCloseable {
 
     @Property
     var NetconfClientDispatcher dispatcher
-    
+
     static val InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance();
 
+    @Property
+    var SchemaSourceProvider<InputStream> remoteSourceProvider
+
     public new(String name) {
         this.name = name;
         this.logger = LoggerFactory.getLogger(NetconfDevice.name + "#" + name);
@@ -120,11 +118,12 @@ AutoCloseable {
         checkState(schemaSourceProvider != null, "Schema Source Provider must be set.")
         checkState(eventExecutor != null, "Event executor must be set.");
 
-        val listener = new NetconfDeviceListener(this,eventExecutor);
+        val listener = new NetconfDeviceListener(this, eventExecutor);
         val task = startClientTask(dispatcher, listener)
-        if(mountInstance != null) {
+        if (mountInstance != null) {
             confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this);
             operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this);
+            commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, this)
         }
         return processingExecutor.submit(task) as Future<Void>;
 
@@ -132,27 +131,28 @@ AutoCloseable {
     }
 
     def Optional<SchemaContext> getSchemaContext() {
-        if (schemaContextProvider == null) {
+        if (deviceContextProvider == null) {
             return Optional.absent();
         }
-        return schemaContextProvider.currentContext;
+        return deviceContextProvider.currentContext;
     }
 
     private def Runnable startClientTask(NetconfClientDispatcher dispatcher, NetconfDeviceListener listener) {
+
         return [ |
             logger.info("Starting Netconf Client on: {}", socketAddress);
             client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener);
             logger.debug("Initial capabilities {}", initialCapabilities);
             var SchemaSourceProvider<String> delegate;
-            if (initialCapabilities.contains(NetconfMapping.IETF_NETCONF_MONITORING_MODULE)) {
-                delegate = new NetconfDeviceSchemaSourceProvider(this);
-            } else {
-                logger.info("Device does not support IETF Netconf Monitoring.", socketAddress);
+            if (NetconfRemoteSchemaSourceProvider.isSupportedFor(initialCapabilities)) {
+                delegate = new NetconfRemoteSchemaSourceProvider(this);
+            }  else {
+                logger.info("Netconf server {} does not support IETF Netconf Monitoring", socketAddress);
                 delegate = SchemaSourceProviders.<String>noopProvider();
             }
-            val sourceProvider = schemaSourceProvider.createInstanceFor(delegate);
-            schemaContextProvider = new NetconfDeviceSchemaContextProvider(this, sourceProvider);
-            schemaContextProvider.createContextFromCapabilities(initialCapabilities);
+            remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate);
+            deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider);
+            deviceContextProvider.createContextFromCapabilities(initialCapabilities);
             if (mountInstance != null && schemaContext.isPresent) {
                 mountInstance.schemaContext = schemaContext.get();
             }
@@ -175,18 +175,31 @@ AutoCloseable {
     override getSupportedRpcs() {
         Collections.emptySet;
     }
-    
+
     def createSubscription(String streamName) {
         val it = ImmutableCompositeNode.builder()
         QName = NETCONF_CREATE_SUBSCRIPTION_QNAME
-        addLeaf("stream",streamName);
-        invokeRpc(QName,toInstance())
+        addLeaf("stream", streamName);
+        invokeRpc(QName, toInstance())
     }
 
     override invokeRpc(QName rpc, CompositeNode input) {
-        val message = rpc.toRpcMessage(input);
-        val result = client.sendMessage(message, messegeRetryCount, messageTimeoutCount);
-        return result.toRpcResult();
+        try {
+            val message = rpc.toRpcMessage(input,schemaContext);
+            val result = sendMessageImpl(message, messegeRetryCount, messageTimeoutCount);
+            return result.toRpcResult(rpc, schemaContext);
+
+        } catch (Exception e) {
+            logger.error("Rpc was not processed correctly.", e)
+            throw e;
+        }
+    }
+
+    def NetconfMessage sendMessageImpl(NetconfMessage message, int retryCount, int timeout) {
+        logger.debug("Send message {}",XmlUtil.toString(message.document))
+        val result = client.sendMessage(message, retryCount, timeout);
+        NetconfMapping.checkValidReply(message, result)
+        return result;
     }
 
     override getProviderFunctionality() {
@@ -221,7 +234,7 @@ AutoCloseable {
         return null === transaction.readOperationalData(path);
     }
 
-    def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
+    static def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
 
         var Node<?> current = node;
         for (arg : identifier.path) {
@@ -229,12 +242,17 @@ AutoCloseable {
                 return null;
             } else if (current instanceof CompositeNode) {
                 val currentComposite = (current as CompositeNode);
-
-                current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision());
-                if (current == null) {
-                    current = currentComposite.getFirstSimpleByName(arg.nodeType.withoutRevision());
+                
+                current = currentComposite.getFirstCompositeByName(arg.nodeType);
+                if(current == null) {
+                    current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision());
+                }
+                if(current == null) {
+                    current = currentComposite.getFirstSimpleByName(arg.nodeType);
                 }
                 if (current == null) {
+                    current = currentComposite.getFirstSimpleByName(arg.nodeType.withoutRevision());
+                } if (current == null) {
                     return null;
                 }
             }
@@ -243,7 +261,9 @@ AutoCloseable {
     }
 
     override requestCommit(DataModification<InstanceIdentifier, CompositeNode> modification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        val twoPhaseCommit = new NetconfDeviceTwoPhaseCommitTransaction(this, modification);
+        twoPhaseCommit.prepare()
+        return twoPhaseCommit;
     }
 
     def getInitialCapabilities() {
@@ -257,8 +277,18 @@ AutoCloseable {
                 val parts = split("\\?");
                 val namespace = parts.get(0);
                 val queryParams = FluentIterable.from(parts.get(1).split("&"));
-                val revision = queryParams.findFirst[startsWith("revision=")].replaceAll("revision=", "");
-                val moduleName = queryParams.findFirst[startsWith("module=")].replaceAll("module=", "");
+                var revision = queryParams.findFirst[startsWith("revision=")]?.replaceAll("revision=", "");
+                val moduleName = queryParams.findFirst[startsWith("module=")]?.replaceAll("module=", "");
+                if (revision === null) {
+                    logger.warn("Netconf device was not reporting revision correctly, trying to get amp;revision=");
+                    revision = queryParams.findFirst[startsWith("&amp;revision=")]?.replaceAll("revision=", "");
+                    if (revision != null) {
+                        logger.warn("Netconf device returned revision incorectly escaped for {}", it)
+                    }
+                }
+                if (revision == null) {
+                    return QName.create(URI.create(namespace), null, moduleName);
+                }
                 return QName.create(namespace, revision, moduleName);
             ].toSet();
         }
@@ -273,96 +303,6 @@ AutoCloseable {
 
 }
 
-package class NetconfDeviceListener extends NetconfClientSessionListener {
-
-    val NetconfDevice device
-    val EventExecutor eventExecutor
-
-    new(NetconfDevice device,EventExecutor eventExecutor) {
-        this.device = device
-        this.eventExecutor = eventExecutor
-    }
-
-    var Promise<NetconfMessage> messagePromise;
-    val promiseLock = new ReentrantLock;
-    
-    override onMessage(NetconfClientSession session, NetconfMessage message) {
-        if (isNotification(message)) {
-            onNotification(session, message);
-        } else try {
-            promiseLock.lock
-            if (messagePromise != null) {
-                messagePromise.setSuccess(message);
-                messagePromise = null;
-            }
-        } finally {
-            promiseLock.unlock
-        }
-    }
-
-    /**
-     * Method intended to customize notification processing.
-     * 
-     * @param session
-     *            {@see
-     *            NetconfClientSessionListener#onMessage(NetconfClientSession,
-     *            NetconfMessage)}
-     * @param message
-     *            {@see
-     *            NetconfClientSessionListener#onMessage(NetconfClientSession,
-     *            NetconfMessage)}
-     */
-    def void onNotification(NetconfClientSession session, NetconfMessage message) {
-        device.logger.debug("Received NETCONF notification.",message);
-        val domNotification = message?.toCompositeNode?.notificationBody;
-        if(domNotification != null) {
-            device?.mountInstance?.publish(domNotification);
-        }
-    }
-    
-    private static def CompositeNode getNotificationBody(CompositeNode node) {
-        for(child : node.children) {
-            if(child instanceof CompositeNode) {
-                return child as CompositeNode;
-            }
-        }
-    }
-
-    override getLastMessage(int attempts, int attemptMsDelay) throws InterruptedException {
-        val promise = promiseReply();
-        val messageAvailable = promise.await(attempts + attemptMsDelay);
-        if (messageAvailable) {
-            try {
-                return promise.get();
-            } catch (ExecutionException e) {
-                throw new IllegalStateException(e);
-            }
-        }
-
-        throw new IllegalStateException("Unsuccessful after " + attempts + " attempts.");
-
-    // throw new TimeoutException("Message was not received on time.");
-    }
-
-    def Promise<NetconfMessage> promiseReply() {
-        promiseLock.lock
-        try {
-        if (messagePromise == null) {
-            messagePromise = eventExecutor.newPromise();
-            return messagePromise;
-        }
-        return messagePromise;
-        } finally {
-            promiseLock.unlock
-        }
-    }
-
-    def boolean isNotification(NetconfMessage message) {
-        val xmle = XmlElement.fromDomDocument(message.getDocument());
-        return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(xmle.getName());
-    }
-}
-
 package class NetconfDeviceSchemaContextProvider {
 
     @Property
@@ -380,22 +320,29 @@ package class NetconfDeviceSchemaContextProvider {
     }
 
     def createContextFromCapabilities(Iterable<QName> capabilities) {
-
-        val modelsToParse = ImmutableMap.<QName, InputStream>builder();
-        for (cap : capabilities) {
-            val source = sourceProvider.getSchemaSource(cap.localName, Optional.fromNullable(cap.formattedRevision));
-            if (source.present) {
-                modelsToParse.put(cap, source.get());
-            }
+        val sourceContext = YangSourceContext.createFrom(capabilities, sourceProvider)
+        if (!sourceContext.missingSources.empty) {
+            device.logger.warn("Sources for following models are missing {}", sourceContext.missingSources);
+        }
+        device.logger.debug("Trying to create schema context from {}", sourceContext.validSources)
+        val modelsToParse = YangSourceContext.getValidInputStreams(sourceContext);
+        if (!sourceContext.validSources.empty) {
+            val schemaContext = tryToCreateContext(modelsToParse);
+            currentContext = Optional.fromNullable(schemaContext);
+        } else {
+            currentContext = Optional.absent();
         }
-        val context = tryToCreateContext(modelsToParse.build);
-        currentContext = Optional.fromNullable(context);
+        if (currentContext.present) {
+            device.logger.debug("Schema context successfully created.");
+        }
+
     }
 
-    def SchemaContext tryToCreateContext(Map<QName, InputStream> modelsToParse) {
+    def SchemaContext tryToCreateContext(List<InputStream> modelsToParse) {
         val parser = new YangParserImpl();
         try {
-            val models = parser.parseYangModelsFromStreams(ImmutableList.copyOf(modelsToParse.values));
+
+            val models = parser.parseYangModelsFromStreams(modelsToParse);
             val result = parser.resolveSchemaContext(models);
             return result;
         } catch (Exception e) {
@@ -404,33 +351,3 @@ package class NetconfDeviceSchemaContextProvider {
         }
     }
 }
-
-package class NetconfDeviceSchemaSourceProvider implements SchemaSourceProvider<String> {
-
-    val NetconfDevice device;
-
-    new(NetconfDevice device) {
-        this.device = device;
-    }
-
-    override getSchemaSource(String moduleName, Optional<String> revision) {
-        val it = ImmutableCompositeNode.builder() //
-        setQName(QName::create(NetconfState.QNAME, "get-schema")) //
-        addLeaf("format", "yang")
-        addLeaf("identifier", moduleName)
-        if (revision.present) {
-            addLeaf("version", revision.get())
-        }
-
-        device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision)
-        val schemaReply = device.invokeRpc(getQName(), toInstance());
-
-        if (schemaReply.successful) {
-            val schemaBody = schemaReply.result.getFirstSimpleByName(
-                QName::create(NetconfState.QNAME.namespace, null, "data"))?.value;
-            device.logger.info("YANG Schema successfully received for: {}:{}", moduleName, revision);
-            return Optional.of(schemaBody as String);
-        }
-        return Optional.absent();
-    }
-}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java
new file mode 100644 (file)
index 0000000..8623d90
--- /dev/null
@@ -0,0 +1,155 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import com.google.common.base.Objects;
+
+import io.netty.util.concurrent.EventExecutor;
+import io.netty.util.concurrent.Promise;
+
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.NetconfMapping;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.w3c.dom.Document;
+
+@SuppressWarnings("all")
+class NetconfDeviceListener extends NetconfClientSessionListener {
+    private final NetconfDevice device;
+    private final EventExecutor eventExecutor;
+
+    public NetconfDeviceListener(final NetconfDevice device, final EventExecutor eventExecutor) {
+        this.device = device;
+        this.eventExecutor = eventExecutor;
+    }
+
+    private Promise<NetconfMessage> messagePromise;
+    private ConcurrentMap<String, Promise<NetconfMessage>> promisedMessages;
+
+    private final ReentrantLock promiseLock = new ReentrantLock();
+
+    public void onMessage(final NetconfClientSession session, final NetconfMessage message) {
+        if (isNotification(message)) {
+            this.onNotification(session, message);
+        } else {
+            try {
+                this.promiseLock.lock();
+                boolean _notEquals = (!Objects.equal(this.messagePromise, null));
+                if (_notEquals) {
+                    this.device.logger.debug("Setting promised reply {} with message {}", this.messagePromise, message);
+                    this.messagePromise.setSuccess(message);
+                    this.messagePromise = null;
+                }
+            } finally {
+                this.promiseLock.unlock();
+            }
+        }
+    }
+
+    /**
+     * Method intended to customize notification processing.
+     * 
+     * @param session
+     *            {@see
+     *            NetconfClientSessionListener#onMessage(NetconfClientSession,
+     *            NetconfMessage)}
+     * @param message
+     *            {@see
+     *            NetconfClientSessionListener#onMessage(NetconfClientSession,
+     *            NetconfMessage)}
+     */
+    public void onNotification(final NetconfClientSession session, final NetconfMessage message) {
+        this.device.logger.debug("Received NETCONF notification.", message);
+        CompositeNode _notificationBody = null;
+        CompositeNode _compositeNode = null;
+        if (message != null) {
+            _compositeNode = NetconfMapping.toCompositeNode(message,device.getSchemaContext());
+        }
+        if (_compositeNode != null) {
+            _notificationBody = NetconfDeviceListener.getNotificationBody(_compositeNode);
+        }
+        final CompositeNode domNotification = _notificationBody;
+        boolean _notEquals = (!Objects.equal(domNotification, null));
+        if (_notEquals) {
+            MountProvisionInstance _mountInstance = null;
+            if (this.device != null) {
+                _mountInstance = this.device.getMountInstance();
+            }
+            if (_mountInstance != null) {
+                _mountInstance.publish(domNotification);
+            }
+        }
+    }
+
+    private static CompositeNode getNotificationBody(final CompositeNode node) {
+        List<Node<? extends Object>> _children = node.getChildren();
+        for (final Node<? extends Object> child : _children) {
+            if ((child instanceof CompositeNode)) {
+                return ((CompositeNode) child);
+            }
+        }
+        return null;
+    }
+
+    public NetconfMessage getLastMessage(final int attempts, final int attemptMsDelay) throws InterruptedException {
+        final Promise<NetconfMessage> promise = this.promiseReply();
+        this.device.logger.debug("Waiting for reply {}", promise);
+        int _plus = (attempts * attemptMsDelay);
+        final boolean messageAvailable = promise.await(_plus);
+        if (messageAvailable) {
+            try {
+                try {
+                    return promise.get();
+                } catch (Throwable _e) {
+                    throw Exceptions.sneakyThrow(_e);
+                }
+            } catch (final Throwable _t) {
+                if (_t instanceof ExecutionException) {
+                    final ExecutionException e = (ExecutionException) _t;
+                    IllegalStateException _illegalStateException = new IllegalStateException(e);
+                    throw _illegalStateException;
+                } else {
+                    throw Exceptions.sneakyThrow(_t);
+                }
+            }
+        }
+        String _plus_1 = ("Unsuccessful after " + Integer.valueOf(attempts));
+        String _plus_2 = (_plus_1 + " attempts.");
+        IllegalStateException _illegalStateException_1 = new IllegalStateException(_plus_2);
+        throw _illegalStateException_1;
+    }
+
+    public synchronized Promise<NetconfMessage> promiseReply() {
+        this.device.logger.debug("Promising reply.");
+        this.promiseLock.lock();
+        try {
+            boolean _equals = Objects.equal(this.messagePromise, null);
+            if (_equals) {
+                Promise<NetconfMessage> _newPromise = this.eventExecutor.<NetconfMessage> newPromise();
+                this.messagePromise = _newPromise;
+                return this.messagePromise;
+            }
+            return this.messagePromise;
+        } finally {
+            this.promiseLock.unlock();
+        }
+    }
+
+    public boolean isNotification(final NetconfMessage message) {
+        Document _document = message.getDocument();
+        final XmlElement xmle = XmlElement.fromDomDocument(_document);
+        String _name = xmle.getName();
+        return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(_name);
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java
new file mode 100644 (file)
index 0000000..216a27a
--- /dev/null
@@ -0,0 +1,134 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+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.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*;
+
+public class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<InstanceIdentifier, CompositeNode> {
+
+    private NetconfDevice device;
+    private final DataModification<InstanceIdentifier, CompositeNode> modification;
+    private boolean candidateSupported = true;
+
+    public NetconfDeviceTwoPhaseCommitTransaction(NetconfDevice device,
+            DataModification<InstanceIdentifier, CompositeNode> modification) {
+        super();
+        this.device = device;
+        this.modification = modification;
+    }
+
+    public void prepare() {
+        for (InstanceIdentifier toRemove : modification.getRemovedConfigurationData()) {
+            sendRemove(toRemove);
+        }
+        for(Entry<InstanceIdentifier, CompositeNode> toUpdate : modification.getUpdatedConfigurationData().entrySet()) {
+            sendMerge(toUpdate.getKey(),toUpdate.getValue());
+        }
+
+    }
+
+    private void sendMerge(InstanceIdentifier key, CompositeNode value) {
+        sendEditRpc(createEditStructure(key, Optional.<String>absent(), Optional.of(value)));
+    }
+
+    private void sendRemove(InstanceIdentifier toRemove) {
+        sendEditRpc(createEditStructure(toRemove, Optional.of("remove"), Optional.<CompositeNode> absent()));
+    }
+
+    private void sendEditRpc(CompositeNode editStructure) {
+        CompositeNodeBuilder<ImmutableCompositeNode> builder = configurationRpcBuilder();
+        builder.setQName(NETCONF_EDIT_CONFIG_QNAME);
+        builder.add(editStructure);
+        
+        RpcResult<CompositeNode> rpcResult = device.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, builder.toInstance());
+        Preconditions.checkState(rpcResult.isSuccessful(),"Rpc Result was unsuccessful");
+        
+    }
+
+    private CompositeNodeBuilder<ImmutableCompositeNode> configurationRpcBuilder() {
+        CompositeNodeBuilder<ImmutableCompositeNode> ret = ImmutableCompositeNode.builder();
+        
+        Node<?> targetNode;
+        if(candidateSupported) {
+            targetNode = ImmutableCompositeNode.create(NETCONF_CANDIDATE_QNAME, ImmutableList.<Node<?>>of());
+        } else {
+            targetNode = ImmutableCompositeNode.create(NETCONF_RUNNING_QNAME, ImmutableList.<Node<?>>of());
+        }
+        Node<?> targetWrapperNode = ImmutableCompositeNode.create(NETCONF_TARGET_QNAME, ImmutableList.<Node<?>>of(targetNode));
+        ret.add(targetWrapperNode);
+        return ret;
+    }
+
+    private CompositeNode createEditStructure(InstanceIdentifier dataPath, Optional<String> action,
+            Optional<CompositeNode> lastChildOverride) {
+        List<PathArgument> path = dataPath.getPath();
+        List<PathArgument> reversed = Lists.reverse(path);
+        CompositeNode previous = null;
+        boolean isLast = true;
+        for (PathArgument arg : reversed) {
+            CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
+            builder.setQName(arg.getNodeType());
+
+            if (arg instanceof NodeIdentifierWithPredicates) {
+                for (Entry<QName, Object> entry : ((NodeIdentifierWithPredicates) arg).getKeyValues().entrySet()) {
+                    builder.addLeaf(entry.getKey(), entry.getValue());
+                }
+            }
+            if (isLast) {
+                if (action.isPresent()) {
+                    builder.setAttribute(NETCONF_ACTION_QNAME, action.get());
+                }
+                if (lastChildOverride.isPresent()) {
+                    List<Node<?>> children = lastChildOverride.get().getChildren();
+                    builder.addAll(children);
+                }
+            } else {
+                builder.add(previous);
+            }
+            previous = builder.toInstance();
+            isLast = false;
+        }
+        return ImmutableCompositeNode.create(NETCONF_CONFIG_QNAME, ImmutableList.<Node<?>>of(previous));
+    }
+
+    @Override
+    public RpcResult<Void> finish() throws IllegalStateException {
+        CompositeNodeBuilder<ImmutableCompositeNode> commitInput = ImmutableCompositeNode.builder();
+        commitInput.setQName(NETCONF_COMMIT_QNAME);
+        RpcResult<?> rpcResult = device.invokeRpc(NetconfMapping.NETCONF_COMMIT_QNAME, commitInput.toInstance());
+        return (RpcResult<Void>) rpcResult;
+    }
+
+    @Override
+    public DataModification<InstanceIdentifier, CompositeNode> getModification() {
+        return this.modification;
+    }
+
+    @Override
+    public RpcResult<Void> rollback() throws IllegalStateException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
index 794b58294eeb13d54ad8385e4f75dac3e3f5c695..c151e42fbb803e26565e53eb965a6903ebfa98da 100644 (file)
@@ -22,6 +22,10 @@ import java.util.List
 import com.google.common.collect.ImmutableList
 import org.opendaylight.yangtools.yang.data.api.SimpleNode
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
+import com.google.common.base.Preconditions
+import com.google.common.base.Optional
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils
 
 class NetconfMapping {
 
@@ -36,8 +40,19 @@ class NetconfMapping {
     public static val NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter");
     public static val NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type");
     public static val NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config");
+    public static val NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config");
+    public static val NETCONF_DELETE_CONFIG_QNAME = QName.create(NETCONF_QNAME, "delete-config");
+    public static val NETCONF_ACTION_QNAME = QName.create(NETCONF_QNAME, "action");
+    public static val NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit");
+    
+    public static val NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config");
     public static val NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source");
+    public static val NETCONF_TARGET_QNAME = QName.create(NETCONF_QNAME, "target");
+    
+    public static val NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate");
     public static val NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running");
+    
+    
     public static val NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply");
     public static val NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok");
     public static val NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
@@ -80,11 +95,11 @@ class NetconfMapping {
         }
     }
 
-    static def CompositeNode toCompositeNode(NetconfMessage message) {
-        return message.toRpcResult().result;
+    static def CompositeNode toCompositeNode(NetconfMessage message,Optional<SchemaContext> ctx) {
+        return null//message.toRpcResult().result;
     }
 
-    static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node) {
+    static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node,Optional<SchemaContext> ctx) {
         val rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node));
         val w3cPayload = NodeUtils.buildShadowDomTree(rpcPayload);
         w3cPayload.documentElement.setAttribute("message-id", "m-" + messageId.andIncrement);
@@ -106,12 +121,41 @@ class NetconfMapping {
         
     }
 
-    static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message) {
-        val rawRpc = message.document.toCompositeNode() as CompositeNode;
-
+    static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message,QName rpc,Optional<SchemaContext> context) {
+        var CompositeNode rawRpc;
+        if(context.present) {
+            if(isDataRetrievalReply(rpc)) {
+                
+                val xmlData = message.document.dataSubtree
+                val dataNodes = XmlDocumentUtils.toDomNodes(xmlData,Optional.of(context.get.dataDefinitions))
+                
+                val it = ImmutableCompositeNode.builder()
+                setQName(NETCONF_RPC_REPLY_QNAME)
+                add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME,dataNodes));
+                
+                rawRpc = it.toInstance;
+                //sys(xmlData)
+            } else {
+                val rpcSchema = context.get.operations.findFirst[QName == rpc]
+                rawRpc = message.document.toCompositeNode() as CompositeNode;
+            }
+            
+            
+            
+        } else {
+            rawRpc = message.document.toCompositeNode() as CompositeNode;
+        }
         //rawRpc.
         return Rpcs.getRpcResult(true, rawRpc, Collections.emptySet());
     }
+    
+    def static Element getDataSubtree(Document doc) {
+        doc.getElementsByTagNameNS(NETCONF_URI.toString,"data").item(0) as Element
+    }
+    
+    def static boolean isDataRetrievalReply(QName it) {
+        return NETCONF_URI == namespace && ( localName == NETCONF_GET_CONFIG_QNAME.localName || localName == NETCONF_GET_QNAME.localName) 
+    }
 
     static def wrap(QName name, Node<?> node) {
         if (node != null) {
@@ -141,6 +185,14 @@ class NetconfMapping {
     }
 
     public static def Node<?> toCompositeNode(Document document) {
-        return XmlDocumentUtils.toNode(document) as Node<?>
+        return XmlDocumentUtils.toDomNode(document) as Node<?>
     }
+    
+    public static def checkValidReply(NetconfMessage input, NetconfMessage output) {
+        val inputMsgId = input.document.documentElement.getAttribute("message-id")
+        val outputMsgId = output.document.documentElement.getAttribute("message-id")
+        Preconditions.checkState(inputMsgId == outputMsgId,"Rpc request and reply message IDs must be same.");
+        
+    }
+    
 }
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java
new file mode 100644 (file)
index 0000000..12be689
--- /dev/null
@@ -0,0 +1,69 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.Set;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+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.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String> {
+
+    public static final QName IETF_NETCONF_MONITORING = QName.create(
+            "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
+    public static final QName GET_SCHEMA_QNAME = QName.create(IETF_NETCONF_MONITORING, "get-schema");
+    public static final QName GET_DATA_QNAME = QName.create(IETF_NETCONF_MONITORING, "data");
+
+    NetconfDevice device;
+
+    public NetconfRemoteSchemaSourceProvider(NetconfDevice device) {
+        super();
+        this.device = device;
+    }
+
+    @Override
+    public Optional<String> getSchemaSource(String moduleName, Optional<String> revision) {
+        CompositeNodeBuilder<ImmutableCompositeNode> request = ImmutableCompositeNode.builder(); //
+        request.setQName(GET_SCHEMA_QNAME) //
+                .addLeaf("format", "yang") //
+                .addLeaf("identifier", moduleName); //
+        if (revision.isPresent()) {
+            request.addLeaf("version", revision.get());
+        }
+
+        device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision);
+        RpcResult<CompositeNode> schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance());
+        if (schemaReply.isSuccessful()) {
+            String schemaBody = getSchemaFromRpc(schemaReply.getResult());
+            if (schemaBody != null) {
+                device.logger.info("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision);
+                return Optional.of(schemaBody);
+            }
+        }
+        device.logger.info("YANG shcema was not successfully retrieved.");
+        return Optional.absent();
+    }
+
+    private String getSchemaFromRpc(CompositeNode result) {
+        if (result == null) {
+            return null;
+        }
+        SimpleNode<?> simpleNode = result.getFirstSimpleByName(GET_DATA_QNAME.withoutRevision());
+        Object potential = simpleNode.getValue();
+        if (potential instanceof String) {
+            return (String) potential;
+        }
+        return null;
+    }
+    
+    public static final boolean isSupportedFor(Set<QName> capabilities) {
+        return capabilities.contains(IETF_NETCONF_MONITORING);
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java
deleted file mode 100644 (file)
index e151fca..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.opendaylight.controller.sal.connect.netconf;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import com.google.common.base.Strings;
-
-public class XmlDocumentUtils {
-
-    public static Node<?> toNode(Document doc) {
-        return toCompositeNode(doc.getDocumentElement());
-    }
-
-    private static Node<?> toCompositeNode(Element element) {
-        String orgNamespace = element.getNamespaceURI();
-        URI biNamespace = null;
-        if (orgNamespace != null) {
-            biNamespace = URI.create(orgNamespace);
-        }
-        QName qname = new QName(biNamespace, element.getLocalName());
-
-        List<Node<?>> values = new ArrayList<>();
-        NodeList nodes = element.getChildNodes();
-        boolean isSimpleObject = true;
-        String value = null;
-        for (int i = 0; i < nodes.getLength(); i++) {
-            org.w3c.dom.Node child = nodes.item(i);
-            if (child instanceof Element) {
-                isSimpleObject = false;
-                values.add(toCompositeNode((Element) child));
-            }
-            if (isSimpleObject && child instanceof org.w3c.dom.Text) {
-                value = element.getTextContent();
-                if (!Strings.isNullOrEmpty(value)) {
-                    isSimpleObject = true;
-                }
-            }
-        }
-
-        if (isSimpleObject) {
-            return new SimpleNodeTOImpl<>(qname, null, value);
-        }
-        return new CompositeNodeTOImpl(qname, null, values);
-    }
-}