Merge "Cosmetics: check in pom.xml files as _sort_pom_ wants them to be"
authorEd Warnicke <eaw@cisco.com>
Tue, 20 May 2014 21:55:37 +0000 (21:55 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 20 May 2014 21:55:37 +0000 (21:55 +0000)
62 files changed:
.gitignore
opendaylight/commons/opendaylight/pom.xml
opendaylight/distribution/opendaylight/pom.xml
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/topology/TopologyMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java
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/RpcInvocationStrategy.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPutsTest.java [moved from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPuts.java with 98% similarity]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleDataBroker.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingListenerInvoker.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataPreconditionFailedException.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataTree.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataPreconditionFailedException.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTree.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidate.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeSnapshot.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/StoreUtils.java with 98% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java with 69% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationApplyOperation.java with 83% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationType.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java with 91% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/NodeModification.java with 96% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/OperationWithModification.java with 89% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java with 93% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreMetadataNode.java with 97% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreNodeCompositeBuilder.java with 96% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java [moved from opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationMetadataTreeTest.java with 81% similarity]
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperationRoot.java with 95% similarity]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/Context.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcClient.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RoutingTableProvider.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandler.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/Message.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientRequestHandlerTest.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/MockRoutingTable.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImplTest.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandlerTest.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/MessagingUtil.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/RemoteServerTestClient.java

index 6fc003b..f8cf74f 100644 (file)
@@ -25,3 +25,5 @@ classes
 out/
 .externalToolBuilders
 maven-eclipse.xml
+.DS_STORE
+.metadata
index b1f10ff..89fd22d 100644 (file)
         <artifactId>concepts</artifactId>
         <version>${yangtools.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>object-cache-api</artifactId>
+        <version>${yangtools.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>object-cache-guava</artifactId>
+        <version>${yangtools.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>restconf-client-api</artifactId>
index 04818e7..48e661f 100644 (file)
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>concepts</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>object-cache-api</artifactId>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>object-cache-guava</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>restconf-client-api</artifactId>
index 00ce312..57682bc 100644 (file)
@@ -11,13 +11,17 @@ import java.util.Arrays
 import java.util.Dictionary
 import java.util.Hashtable
 import org.apache.felix.dm.Component
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext
-import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider
 import org.opendaylight.controller.sal.binding.api.NotificationService
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.compatibility.adsal.DataPacketServiceAdapter
 import org.opendaylight.controller.sal.compatibility.topology.TopologyAdapter
+import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
 import org.opendaylight.controller.sal.core.Node
 import org.opendaylight.controller.sal.core.NodeConnector
@@ -26,6 +30,7 @@ import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerSer
 import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
 import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
+import org.opendaylight.controller.sal.packet.IPluginInDataPacketService
 import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService
 import org.opendaylight.controller.sal.reader.IPluginInReadService
 import org.opendaylight.controller.sal.reader.IPluginOutReadService
@@ -34,22 +39,15 @@ import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
 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
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
 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
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
 
 class ComponentActivator extends ComponentActivatorAbstractBase {
 
index f54defd..8908504 100644 (file)
@@ -10,11 +10,13 @@ package org.opendaylight.controller.sal.compatibility
 import java.util.ArrayList
 import java.util.Collections
 import java.util.List
+import java.util.Map
 import java.util.Set
-import java.util.ArrayList;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.CopyOnWriteArrayList
+import java.util.concurrent.locks.Lock
+import java.util.concurrent.locks.ReentrantLock
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
 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
@@ -76,10 +78,6 @@ import org.slf4j.LoggerFactory
 
 import static extension org.opendaylight.controller.sal.common.util.Arguments.*
 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
-import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
-import java.util.concurrent.ConcurrentHashMap
-import java.util.Map
-import java.util.HashMap
 
 class InventoryAndReadAdapter implements IPluginInReadService,
                                              IPluginInInventoryService,
index 9a19e10..2d49056 100644 (file)
@@ -8,9 +8,9 @@
 package org.opendaylight.controller.sal.compatibility.topology
 
 import com.google.common.collect.FluentIterable
-import java.util.Collections
 import java.util.List
 import java.util.concurrent.CopyOnWriteArrayList
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
 import org.opendaylight.controller.sal.core.ConstructionException
 import org.opendaylight.controller.sal.core.Edge
 import org.opendaylight.controller.sal.core.Node
@@ -21,13 +21,12 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.slf4j.LoggerFactory
 
 import static com.google.common.base.Preconditions.*
+
 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
-import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
-import org.slf4j.LoggerFactory
 
 class TopologyMapping {
     private static val LOG = LoggerFactory.getLogger(TopologyMapping);
index 63c5664..81ccb35 100644 (file)
@@ -10,8 +10,8 @@ package org.opendaylight.controller.sal.compatibility.test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
 import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
 import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
 import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
 
@@ -19,17 +19,53 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.junit.Test;
-import org.opendaylight.controller.sal.action.*;
+import org.opendaylight.controller.sal.action.Action;
+import org.opendaylight.controller.sal.action.Flood;
+import org.opendaylight.controller.sal.action.FloodAll;
+import org.opendaylight.controller.sal.action.HwPath;
+import org.opendaylight.controller.sal.action.Loopback;
+import org.opendaylight.controller.sal.action.PopVlan;
+import org.opendaylight.controller.sal.action.PushVlan;
+import org.opendaylight.controller.sal.action.SetDlDst;
+import org.opendaylight.controller.sal.action.SetDlSrc;
+import org.opendaylight.controller.sal.action.SetDlType;
+import org.opendaylight.controller.sal.action.SetNextHop;
+import org.opendaylight.controller.sal.action.SetNwDst;
+import org.opendaylight.controller.sal.action.SetNwSrc;
+import org.opendaylight.controller.sal.action.SetNwTos;
+import org.opendaylight.controller.sal.action.SetTpDst;
+import org.opendaylight.controller.sal.action.SetTpSrc;
+import org.opendaylight.controller.sal.action.SetVlanCfi;
+import org.opendaylight.controller.sal.action.SetVlanId;
+import org.opendaylight.controller.sal.action.SetVlanPcp;
+import org.opendaylight.controller.sal.action.SwPath;
 import org.opendaylight.controller.sal.compatibility.MDFlowMapping;
 import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
 import org.opendaylight.controller.sal.flowprogrammer.Flow;
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAllActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.HwPathActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.LoopbackActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNextHopActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanCfiActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
@@ -140,7 +176,7 @@ public class TestFromSalConversionsUtils {
             if (layer4Match instanceof SctpMatch) {
                 assertEquals("Sctp source port is incorrect.", 0xffff, (int) ((SctpMatch) layer4Match)
                         .getSctpSourcePort().getValue());
-                assertEquals("Sctp dest port is incorrect.", (int) 0xfffe, (int) ((SctpMatch) layer4Match)
+                assertEquals("Sctp dest port is incorrect.", 0xfffe, (int) ((SctpMatch) layer4Match)
                         .getSctpDestinationPort().getValue());
                 sctpFound = true;
             }
@@ -151,9 +187,9 @@ public class TestFromSalConversionsUtils {
             assertEquals("Wrong protocol", TCP, match.getIpMatch().getIpProtocol().byteValue());
             layer4Match = match.getLayer4Match();
             if (layer4Match instanceof TcpMatch) {
-                assertEquals("Tcp source port is incorrect.", (int) 0xabcd, (int) ((TcpMatch) layer4Match)
+                assertEquals("Tcp source port is incorrect.", 0xabcd, (int) ((TcpMatch) layer4Match)
                         .getTcpSourcePort().getValue());
-                assertEquals("Tcp dest port is incorrect.", (int) 0xdcba, (int) ((TcpMatch) layer4Match)
+                assertEquals("Tcp dest port is incorrect.", 0xdcba, (int) ((TcpMatch) layer4Match)
                         .getTcpDestinationPort().getValue());
                 sctpFound = true;
             }
@@ -164,9 +200,9 @@ public class TestFromSalConversionsUtils {
             assertEquals("Wrong protocol", UDP, match.getIpMatch().getIpProtocol().byteValue());
             layer4Match = match.getLayer4Match();
             if (layer4Match instanceof UdpMatch) {
-                assertEquals("Udp source port is incorrect.", (int) 0xcdef, (int) ((UdpMatch) layer4Match)
+                assertEquals("Udp source port is incorrect.", 0xcdef, (int) ((UdpMatch) layer4Match)
                         .getUdpSourcePort().getValue());
-                assertEquals("Udp dest port is incorrect.", (int) 0xfedc, (int) ((UdpMatch) layer4Match)
+                assertEquals("Udp dest port is incorrect.", 0xfedc, (int) ((UdpMatch) layer4Match)
                         .getUdpDestinationPort().getValue());
                 sctpFound = true;
             }
@@ -227,13 +263,13 @@ public class TestFromSalConversionsUtils {
                     assertEquals("Wrong value of vlad ID in PushVlanAction.", (Integer) 4095,
                             ((PushVlanActionCase) innerAction).getPushVlanAction().getVlanId().getValue());
                 } else if (innerAction instanceof SetDlDstActionCase) {
-                    assertEquals("Wrong MAC destination address in SetDlDstAction.", "ff:ee:dd:cc:bb:aa", 
+                    assertEquals("Wrong MAC destination address in SetDlDstAction.", "ff:ee:dd:cc:bb:aa",
                             ((SetDlDstActionCase) innerAction).getSetDlDstAction().getAddress().getValue());
                 } else if (innerAction instanceof SetDlSrcActionCase) {
-                    assertEquals("Wrong MAC source address in SetDlDstAction.", "ff:ee:dd:cc:bb:aa", 
+                    assertEquals("Wrong MAC source address in SetDlDstAction.", "ff:ee:dd:cc:bb:aa",
                             ((SetDlSrcActionCase) innerAction).getSetDlSrcAction().getAddress().getValue());
                 } else if (innerAction instanceof SetDlTypeActionCase) {
-                    assertEquals("Wrong data link type in SetDlTypeAction.", (long) 513,
+                    assertEquals("Wrong data link type in SetDlTypeAction.", 513,
                             (long) ((SetDlTypeActionCase) innerAction).getSetDlTypeAction().getDlType().getValue());
                 } else if (innerAction instanceof SetNextHopActionCase) {
                     Address address = ((SetNextHopActionCase) innerAction).getSetNextHopAction().getAddress();
index 3f9d5c7..f1be5c6 100644 (file)
@@ -13,18 +13,17 @@ import java.util.AbstractMap.SimpleEntry;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map.Entry;
-import java.util.concurrent.Callable;
 
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
-import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 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.InstanceIdentifier.Item;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
@@ -44,6 +43,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
@@ -364,9 +364,9 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         } else if (List.class.isAssignableFrom(returnType)) {
             try {
                 return ClassLoaderUtils.withClassLoader(method.getDeclaringClass().getClassLoader(),
-                        new Callable<Class>() {
+                        new Supplier<Class>() {
                             @Override
-                            public Class call() {
+                            public Class get() {
                                 Type listResult = ClassLoaderUtils.getFirstGenericParameter(method
                                         .getGenericReturnType());
                                 if (listResult instanceof Class
index ddc79ae..e08e9a4 100644 (file)
@@ -443,9 +443,6 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
     }
 
     private static class BackwardsCompatibleConfigurationDataChangeInvoker implements BindingDataChangeListener, Delegator<DataChangeListener> {
-
-
-        @SuppressWarnings("rawtypes")
         private final org.opendaylight.controller.md.sal.common.api.data.DataChangeListener<?,?> delegate;
 
         public BackwardsCompatibleConfigurationDataChangeInvoker(final DataChangeListener listener) {
index b27c80d..5bbebe6 100644 (file)
@@ -62,7 +62,6 @@ import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.binding.Augmentable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
@@ -73,12 +72,11 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.Notification;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
 import org.slf4j.Logger;
@@ -87,7 +85,6 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSet.Builder;
 import com.google.common.util.concurrent.Futures;
@@ -736,224 +733,13 @@ public class BindingIndependentConnector implements //
                         }
                     }
                     checkState(targetMethod != null, "Rpc method not found");
-                    Optional<Class<?>> outputClass = BindingReflections.resolveRpcOutputClass(targetMethod);
-                    Optional<Class<? extends DataContainer>> inputClass = BindingReflections
-                            .resolveRpcInputClass(targetMethod);
-
-                    RpcInvocationStrategy strategy = null;
-                    if (outputClass.isPresent()) {
-                        if (inputClass.isPresent()) {
-                            strategy = new DefaultInvocationStrategy(rpc, targetMethod, outputClass.get(), inputClass
-                                    .get());
-                        } else {
-                            strategy = new NoInputInvocationStrategy(rpc, targetMethod, outputClass.get());
-                        }
-                    } else if (inputClass.isPresent()) {
-                        strategy = new NoOutputInvocationStrategy(rpc, targetMethod, inputClass.get());
-                    } else {
-                        strategy = new NoInputNoOutputInvocationStrategy(rpc, targetMethod);
-                    }
-                    return strategy;
+                    return  new RpcInvocationStrategy(rpc,targetMethod, mappingService, biRpcRegistry);
                 }
 
             });
         }
     }
 
-    private abstract class RpcInvocationStrategy {
-
-        protected final Method targetMethod;
-        protected final QName rpc;
-
-        public RpcInvocationStrategy(final QName rpc, final Method targetMethod) {
-            this.targetMethod = targetMethod;
-            this.rpc = rpc;
-        }
-
-        public abstract Future<RpcResult<?>> forwardToDomBroker(DataObject input);
-
-        public abstract RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput)
-                throws Exception;
-
-        public RpcResult<CompositeNode> invokeOn(final RpcService rpcService, final CompositeNode domInput)
-                throws Exception {
-            return uncheckedInvoke(rpcService, domInput);
-        }
-    }
-
-    private class DefaultInvocationStrategy extends RpcInvocationStrategy {
-
-        @SuppressWarnings("rawtypes")
-        private final WeakReference<Class> inputClass;
-
-        @SuppressWarnings("rawtypes")
-        private final WeakReference<Class> outputClass;
-
-        @SuppressWarnings({ "rawtypes", "unchecked" })
-        public DefaultInvocationStrategy(final QName rpc, final Method targetMethod, final Class<?> outputClass,
-                final Class<? extends DataContainer> inputClass) {
-            super(rpc, targetMethod);
-            this.outputClass = new WeakReference(outputClass);
-            this.inputClass = new WeakReference(inputClass);
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput)
-                throws Exception {
-            DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
-            Future<RpcResult<?>> futureResult = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
-            if (futureResult == null) {
-                return Rpcs.getRpcResult(false);
-            }
-            RpcResult<?> bindingResult = futureResult.get();
-            final Object resultObj = bindingResult.getResult();
-            if (resultObj instanceof DataObject) {
-                final CompositeNode output = mappingService.toDataDom((DataObject) resultObj);
-                return Rpcs.getRpcResult(true, output, Collections.<RpcError> emptySet());
-            }
-            return Rpcs.getRpcResult(true);
-        }
-
-        @Override
-        public ListenableFuture<RpcResult<?>> forwardToDomBroker(final DataObject input) {
-            if (biRpcRegistry == null) {
-                return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
-            }
-
-            CompositeNode xml = mappingService.toDataDom(input);
-            CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
-
-            return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml),
-                    new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
-                        @Override
-                        public RpcResult<?> apply(final RpcResult<CompositeNode> input) {
-                            Object baResultValue = null;
-                            if (input.getResult() != null) {
-                                baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(),
-                                        input.getResult());
-                            }
-                            return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors());
-                        }
-                    });
-        }
-    }
-
-    private class NoInputInvocationStrategy extends RpcInvocationStrategy {
-
-        @SuppressWarnings("rawtypes")
-        private final WeakReference<Class> outputClass;
-
-        @SuppressWarnings({ "rawtypes", "unchecked" })
-        public NoInputInvocationStrategy(final QName rpc, final Method targetMethod, final Class<?> outputClass) {
-            super(rpc, targetMethod);
-            this.outputClass = new WeakReference(outputClass);
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput)
-                throws Exception {
-            Future<RpcResult<?>> futureResult = (Future<RpcResult<?>>) targetMethod.invoke(rpcService);
-            if (futureResult == null) {
-                return Rpcs.getRpcResult(false);
-            }
-            RpcResult<?> bindingResult = futureResult.get();
-            final Object resultObj = bindingResult.getResult();
-            if (resultObj instanceof DataObject) {
-                final CompositeNode output = mappingService.toDataDom((DataObject) resultObj);
-                return Rpcs.getRpcResult(true, output, Collections.<RpcError> emptySet());
-            }
-            return Rpcs.getRpcResult(true);
-        }
-
-        @Override
-        public Future<RpcResult<?>> forwardToDomBroker(final DataObject input) {
-            if (biRpcRegistry != null) {
-                CompositeNode xml = mappingService.toDataDom(input);
-                CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
-                return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml),
-                        new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
-                            @Override
-                            public RpcResult<?> apply(final RpcResult<CompositeNode> input) {
-                                Object baResultValue = null;
-                                if (input.getResult() != null) {
-                                    baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(),
-                                            input.getResult());
-                                }
-                                return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors());
-                            }
-                        });
-            } else {
-                return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
-            }
-        }
-    }
-
-    private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy {
-
-        public NoInputNoOutputInvocationStrategy(final QName rpc, final Method targetMethod) {
-            super(rpc, targetMethod);
-        }
-
-        @Override
-        public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final 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());
-        }
-
-        @Override
-        public Future<RpcResult<?>> forwardToDomBroker(final DataObject input) {
-            return Futures.immediateFuture(null);
-        }
-    }
-
-    private class NoOutputInvocationStrategy extends RpcInvocationStrategy {
-
-        @SuppressWarnings("rawtypes")
-        private final WeakReference<Class> inputClass;
-
-        @SuppressWarnings({ "rawtypes", "unchecked" })
-        public NoOutputInvocationStrategy(final QName rpc, final Method targetMethod,
-                final Class<? extends DataContainer> inputClass) {
-            super(rpc, targetMethod);
-            this.inputClass = new WeakReference(inputClass);
-        }
-
-        @Override
-        public RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput)
-                throws Exception {
-            DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
-            Future<RpcResult<?>> result = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
-            if (result == null) {
-                return Rpcs.getRpcResult(false);
-            }
-            RpcResult<?> bindingResult = result.get();
-            return Rpcs.getRpcResult(true);
-        }
-
-        @Override
-        public ListenableFuture<RpcResult<?>> forwardToDomBroker(final DataObject input) {
-            if (biRpcRegistry == null) {
-                return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
-            }
-
-            CompositeNode xml = mappingService.toDataDom(input);
-            CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
-
-            return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml),
-                    new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
-                        @Override
-                        public RpcResult<?> apply(final RpcResult<CompositeNode> input) {
-                            return Rpcs.<Void> getRpcResult(input.isSuccessful(), null, input.getErrors());
-                        }
-                    });
-        }
-    }
-
     public boolean isRpcForwarding() {
         return rpcForwarding;
     }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java
new file mode 100644 (file)
index 0000000..d08b217
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ ** Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ **
+ ** This program and the accompanying materials are made available under the
+ ** terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ ** and is available at http://www.eclipse.org/legal/epl-v10.html
+ **/
+
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/*
+ * RPC's can have both input, output, one or the other, or neither.
+ *
+ * This class handles the permutations and provides two means of invocation:
+ * 1. forwardToDomBroker
+ * 2.
+ *
+ * Weak References to the input and output classes are used to allow these classes to
+ * be from another OSGi bundle/class loader which may come and go.
+ *
+ */
+public class RpcInvocationStrategy {
+
+    private final BindingIndependentMappingService mappingService;
+    private final RpcProvisionRegistry biRpcRegistry;
+    protected final Method targetMethod;
+    protected final QName rpc;
+
+    @SuppressWarnings("rawtypes")
+    private final WeakReference<Class> inputClass;
+
+    @SuppressWarnings("rawtypes")
+    private final WeakReference<Class> outputClass;
+
+    @SuppressWarnings({ "rawtypes" })
+    public RpcInvocationStrategy(final QName rpc,
+                                 final Method targetMethod,
+                                 final BindingIndependentMappingService mappingService,
+                                 final RpcProvisionRegistry biRpcRegistry ) {
+
+        this.targetMethod = targetMethod;
+        this.rpc = rpc;
+
+        Optional<Class<?>> outputClassOption = BindingReflections.resolveRpcOutputClass(targetMethod);
+        Optional<Class<? extends DataContainer>> inputClassOption = BindingReflections.resolveRpcInputClass(targetMethod);
+
+        if ( outputClassOption != null && outputClassOption.isPresent() ) {
+            this.outputClass = new WeakReference(outputClassOption.get() ) ;
+        } else {
+            this.outputClass = null ;
+        }
+        if ( inputClassOption != null && inputClassOption.isPresent() ) {
+            this.inputClass = new WeakReference(inputClassOption.get() ) ;
+        } else {
+            this.inputClass = null ;
+        }
+
+        this.mappingService = mappingService;
+        this.biRpcRegistry = biRpcRegistry;
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    public ListenableFuture<RpcResult<?>> forwardToDomBroker(final DataObject input) {
+
+        if(biRpcRegistry == null) {
+            return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
+        }
+
+        CompositeNode inputXml = null;
+        if( input != null ) {
+            CompositeNode xml = mappingService.toDataDom(input);
+            inputXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
+        } else {
+            inputXml = ImmutableCompositeNode.create( rpc, Collections.<Node<?>>emptyList() );
+        }
+
+        Function<RpcResult<CompositeNode>, RpcResult<?>> transformationFunction =
+                                       new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
+            @Override
+            public RpcResult<?> apply(RpcResult<CompositeNode> result) {
+
+                Object output = null;
+
+                if( getOutputClass() != null ) {
+                    if (result.getResult() != null) {
+                        output = mappingService.dataObjectFromDataDom(getOutputClass().get(),
+                                                                    result.getResult());
+                    }
+                }
+
+                return Rpcs.getRpcResult(result.isSuccessful(), output, result.getErrors());
+            }
+        };
+
+        return Futures.transform(biRpcRegistry.invokeRpc(rpc, inputXml), transformationFunction);
+    }
+
+    @SuppressWarnings("unchecked")
+    private RpcResult<CompositeNode> uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) throws Exception {
+
+        Future<RpcResult<?>> futureResult = null;
+
+        if( inputClass != null ){
+            DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
+            futureResult = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
+
+        } else {
+            futureResult = (Future<RpcResult<?>>) targetMethod.invoke(rpcService);
+        }
+
+        if (futureResult == null) {
+            return Rpcs.getRpcResult(false);
+        }
+
+        RpcResult<?> bindingResult = futureResult.get();
+
+        Collection<RpcError> errors = bindingResult.getErrors();
+        if( errors == null ) {
+            errors = Collections.<RpcError>emptySet();
+        }
+
+        final Object resultObj = bindingResult.getResult();
+        CompositeNode output = null;
+        if (resultObj instanceof DataObject) {
+            output = mappingService.toDataDom((DataObject)resultObj);
+        }
+        return Rpcs.getRpcResult( bindingResult.isSuccessful(), output, errors);
+    }
+
+    public RpcResult<CompositeNode> invokeOn(final RpcService rpcService, final CompositeNode domInput) throws Exception {
+        return uncheckedInvoke(rpcService, domInput);
+    }
+
+    @SuppressWarnings("rawtypes")
+    public WeakReference<Class> getOutputClass() {
+        return outputClass;
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java
new file mode 100644 (file)
index 0000000..c5aea8f
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+* Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v1.0 which accompanies this distribution,
+* and is available at http://www.eclipse.org/legal/epl-v10.html
+*/
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class RpcInvocationStrategyTest {
+
+    @Mock
+    private BindingIndependentMappingService mockMappingService;
+    @Mock
+    private RpcProvisionRegistry mockbiRpcRegistry;
+
+    private RpcInvocationStrategy rpcInvocationStrategy;
+    private ListenableFuture<RpcResult<DataObject>> futureDataObj;
+    private ListenableFuture<RpcResult<CompositeNode>> futureCompNode;
+    private final RpcError rpcError = mock(RpcError.class);
+    private final Collection<RpcError> errors = new ArrayList<RpcError>();
+
+    private final CompositeNode inputInvokeOn = mock(CompositeNode.class);
+    private final CompositeNode outputInvokeOn = mock(CompositeNode.class);
+
+    private final DataObject toDataDomInput = mock(DataObject.class);
+    private final CompositeNode toDataDomReturn = mock(CompositeNode.class);
+    private final CompositeNode invokeRpcResult = mock(CompositeNode.class);
+
+    private final DataObject inputForward = mock(DataObject.class);
+    private final DataObject outputForward = mock(DataObject.class);
+
+    private QName mockQName;
+    private URI urn;
+
+    private final MockRpcService mockRpcService = new MockRpcService();
+
+    public class MockRpcService implements RpcService {
+
+        public Future<?> rpcnameWithInputNoOutput(DataObject input) {
+            return futureDataObj;
+        }
+
+        public Future<RpcResult<DataObject>> rpcnameWithInputWithOutput(DataObject input) {
+            return futureDataObj;
+        }
+
+        public Future<RpcResult<DataObject>> rpcnameNoInputWithOutput() {
+            return futureDataObj;
+        }
+
+        public Future<?> rpcnameNoInputNoOutput() {
+            return futureDataObj;
+        }
+    }
+
+    public RpcInvocationStrategyTest() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Before
+    public void testInit() throws Exception {
+        urn = new URI(new String("urn:a:valid:urn"));
+    }
+
+    private void setupForForwardToDom(boolean hasOutput, boolean hasInput, int expectedErrorSize) {
+
+        if (expectedErrorSize > 0)
+            errors.add(rpcError);
+        RpcResult<CompositeNode> result = Rpcs.getRpcResult(true, invokeRpcResult, errors);
+        futureCompNode = Futures.immediateFuture(result);
+        if( hasInput )
+        {
+            when(mockMappingService.toDataDom(inputForward)).thenReturn(toDataDomReturn);
+        }
+        when(mockbiRpcRegistry.invokeRpc(eq(mockQName), any(CompositeNode.class))).thenReturn(
+                futureCompNode);
+        if (hasOutput) {
+            when(
+                    mockMappingService.dataObjectFromDataDom(eq(rpcInvocationStrategy
+                            .getOutputClass().get()), any(CompositeNode.class))).thenReturn(
+                    outputForward);
+        }
+
+    }
+
+    private void validateForwardToDomBroker(ListenableFuture<RpcResult<?>> forwardToDomBroker,
+            boolean expectedSuccess, DataObject expectedResult, int expectedErrorSize)
+            throws InterruptedException, ExecutionException {
+        assertNotNull(forwardToDomBroker);
+        assertEquals(expectedSuccess, forwardToDomBroker.get().isSuccessful());
+        assertEquals(expectedResult, forwardToDomBroker.get().getResult());
+        assertEquals(expectedErrorSize, forwardToDomBroker.get().getErrors().size());
+    }
+
+    private void setupTestMethod(String rpcName, String testMethodName, boolean hasInput)
+            throws NoSuchMethodException {
+        mockQName = new QName(urn, new Date(0L), new String("prefix"), new String(rpcName));
+        java.lang.reflect.Method rpcMethod = hasInput ? MockRpcService.class.getMethod(rpcName,
+                DataObject.class) : MockRpcService.class.getMethod(rpcName);
+        rpcInvocationStrategy = new RpcInvocationStrategy(mockQName, rpcMethod, mockMappingService,
+                mockbiRpcRegistry);
+    }
+
+    /*
+     * forwardToDomBroker tests
+     */
+    @Test
+    public void testForwardToDomBroker_WithInputNoOutput() throws Exception {
+        setupTestMethod("rpcnameWithInputNoOutput", "testForwardToDomBroker_WithInputNoOutput",
+                true);
+        setupForForwardToDom(false, true, 0);
+        ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
+                .forwardToDomBroker(inputForward);
+
+        validateForwardToDomBroker(forwardToDomBroker, true, null, 0);
+    }
+
+    @Test
+    public void testForwardToDomBroker_WithInputNoOutput_error() throws Exception {
+        setupTestMethod("rpcnameWithInputNoOutput",
+                "testForwardToDomBroker_WithInputNoOutput_error", true);
+        setupForForwardToDom(false, true, 1);
+        ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
+                .forwardToDomBroker(inputForward);
+
+        validateForwardToDomBroker(forwardToDomBroker, true, null, 1);
+    }
+
+    @Test
+    public void testForwardToDomBroker_WithInputWithOutput() throws Exception {
+        setupTestMethod("rpcnameWithInputWithOutput", "testForwardToDomBroker_WithInputWithOutput",
+                true);
+        setupForForwardToDom(true, true, 0);
+        ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
+                .forwardToDomBroker(inputForward);
+        validateForwardToDomBroker(forwardToDomBroker, true, outputForward, 0);
+    }
+
+    @Test
+    public void testForwardToDomBroker_NoInputWithOutput() throws Exception {
+        setupTestMethod("rpcnameNoInputWithOutput", "testForwardToDomBroker_NoInputWithOutput",
+                false);
+        setupForForwardToDom(true, false, 0);
+        ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
+                .forwardToDomBroker(null);
+        validateForwardToDomBroker(forwardToDomBroker, true, outputForward, 0);
+    }
+
+    @Test
+    public void testForwardToDomBroker_NoInputNoOutput() throws Exception {
+        setupTestMethod("rpcnameNoInputNoOutput", "testForwardToDomBroker_NoInputNoOutput", false);
+        setupForForwardToDom(false, false, 0);
+        ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
+                .forwardToDomBroker(null);
+        validateForwardToDomBroker(forwardToDomBroker, true, null, 0);
+    }
+
+    /*
+     * invokeOn Tests
+     */
+    private void setupRpcResultsWithOutput(int expectedErrorSize) {
+        if (expectedErrorSize > 0)
+            errors.add(rpcError);
+        RpcResult<CompositeNode> resultCompNode = Rpcs.getRpcResult(true, inputInvokeOn, errors);
+        futureCompNode = Futures.immediateFuture(resultCompNode);
+        RpcResult<DataObject> resultDataObj = Rpcs.getRpcResult(true, toDataDomInput, errors);
+        futureDataObj = Futures.immediateFuture(resultDataObj);
+
+        when(mockMappingService.toDataDom(toDataDomInput)).thenReturn(outputInvokeOn);
+    }
+
+    private void setupRpcResultsNoOutput(int expectedErrorSize) {
+        if (expectedErrorSize > 0)
+            errors.add(rpcError);
+        RpcResult<CompositeNode> resultCompNode = Rpcs.getRpcResult(true, inputInvokeOn, errors);
+        futureCompNode = Futures.immediateFuture(resultCompNode);
+        RpcResult<DataObject> resultDataObj = Rpcs.getRpcResult(true, null, errors);
+        futureDataObj = Futures.immediateFuture(resultDataObj);
+    }
+
+    private void validateReturnedImmediateFuture(
+            ListenableFuture<RpcResult<CompositeNode>> immediateFuture, boolean expectedSuccess,
+            CompositeNode expectedReturn, int expectedErrorSize) throws InterruptedException,
+            ExecutionException {
+        assertNotNull(immediateFuture);
+        assertEquals(expectedSuccess, immediateFuture.get().isSuccessful());
+        assertEquals(expectedReturn, immediateFuture.get().getResult());
+        assertEquals(expectedErrorSize, immediateFuture.get().getErrors().size());
+    }
+
+    @Test
+    public void testInvokeOn_NoInputNoOutput() throws Exception {
+        setupTestMethod("rpcnameNoInputNoOutput", "testInvokeOn_NoInputNoOutput", false);
+        setupRpcResultsNoOutput(0);
+        ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
+                .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
+        validateReturnedImmediateFuture(immediateFuture, true, null, 0);
+    }
+
+    @Test
+    public void testInvokeOn_NoInputNoOutput_errors() throws Exception {
+        setupTestMethod("rpcnameNoInputNoOutput", "testInvokeOn_NoInputNoOutput", false);
+        setupRpcResultsNoOutput(1);
+        ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
+                .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
+        validateReturnedImmediateFuture(immediateFuture, true, null, 1);
+    }
+
+    @Test
+    public void testInvokeOn_WithInputNoOutput() throws Exception {
+        setupTestMethod("rpcnameWithInputNoOutput", "testInvokeOn_WithInputNoOutput", true);
+        setupRpcResultsNoOutput(0);
+        ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
+                .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
+        validateReturnedImmediateFuture(immediateFuture, true, null, 0);
+    }
+
+    @Test
+    public void testInvokeOn_WithInputWithOutput() throws Exception {
+        setupTestMethod("rpcnameWithInputWithOutput", "testInvokeOn_WithInputWithOutput", true);
+        setupRpcResultsWithOutput(0);
+        ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
+                .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
+        validateReturnedImmediateFuture(immediateFuture, true, outputInvokeOn, 0);
+    }
+
+    @Test
+    public void testInvokeOn_NoInputWithOutput() throws Exception {
+        setupTestMethod("rpcnameNoInputWithOutput", "testInvokeOn_NoInputWithOutput", false);
+        setupRpcResultsWithOutput(0);
+        ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
+                .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
+        validateReturnedImmediateFuture(immediateFuture, true, outputInvokeOn, 0);
+    }
+}
@@ -48,7 +48,7 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
-public class MultipleAugmentationPuts extends AbstractDataServiceTest implements DataChangeListener {
+public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implements DataChangeListener {
 
     private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
     private static final String NODE_ID = "openflow:1";
@@ -76,7 +76,7 @@ public class MultipleAugmentationPuts extends AbstractDataServiceTest implements
      *
      * @throws Exception
      */
-    @Test
+    @Test( timeout = 15000)
     public void testAugmentSerialization() throws Exception {
 
         baDataService.registerDataChangeListener(NODES_INSTANCE_ID_BA, this);
index f869254..a7c6b0c 100644 (file)
@@ -285,7 +285,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         }
 
         @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
             ImmutableMap.Builder<QName, Object> keys = ImmutableMap.builder();
             for (QName key : keyDefinition) {
 
@@ -325,7 +325,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         }
 
         @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
             return Builders.unkeyedListEntryBuilder().withNodeIdentifier(getIdentifier());
         }
 
@@ -343,7 +343,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         }
 
         @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
             return Builders.containerBuilder().withNodeIdentifier(getIdentifier());
         }
 
@@ -377,7 +377,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         }
 
         @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
             return Builders.orderedLeafSetBuilder().withNodeIdentifier(getIdentifier());
         }
 
@@ -397,7 +397,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         }
 
         @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
             return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier());
         }
 
@@ -602,7 +602,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         }
 
         @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) {
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final CompositeNode compositeNode) {
             return Builders.choiceBuilder().withNodeIdentifier(getIdentifier());
         }
 
index b2217a6..5b34fba 100644 (file)
@@ -1,36 +1,28 @@
 package org.opendaylight.controller.md.sal.dom.broker.impl.compat;
 
 import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 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.impl.util.compat.DataNormalizer;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
 import org.opendaylight.controller.sal.common.DataStoreIdentifier;
 import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.data.DataValidator;
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
-import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 
 public class BackwardsCompatibleDataBroker implements DataProviderService, SchemaContextListener {
 
-    DOMDataBroker backingBroker;
-    DataNormalizer normalizer;
-    private final ListenerRegistry<DataChangeListener> fakeRegistry = ListenerRegistry.create();
-
+    private final DOMDataBroker backingBroker;
+    private DataNormalizer normalizer;
 
     public BackwardsCompatibleDataBroker(final DOMDataBroker newBiDataImpl) {
         backingBroker = newBiDataImpl;
@@ -43,7 +35,7 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
 
     @Override
     public CompositeNode readConfigurationData(final InstanceIdentifier legacyPath) {
-        BackwardsCompatibleTransaction<?> tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer);
+        final BackwardsCompatibleTransaction<?> tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer);
         try {
             return tx.readConfigurationData(legacyPath);
         } finally {
@@ -53,7 +45,7 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
 
     @Override
     public CompositeNode readOperationalData(final InstanceIdentifier legacyPath) {
-        BackwardsCompatibleTransaction<?> tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer);
+        final BackwardsCompatibleTransaction<?> tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer);
         try {
             return tx.readOperationalData(legacyPath);
         } finally {
@@ -67,9 +59,19 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
     }
 
     @Override
-    public ListenerRegistration<DataChangeListener> registerDataChangeListener(final InstanceIdentifier path,
+    public ListenerRegistration<DataChangeListener> registerDataChangeListener(final InstanceIdentifier legacyPath,
             final DataChangeListener listener) {
-        return fakeRegistry .register(listener);
+        final InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
+
+        final TranslatingListenerInvoker translatingCfgListener =
+                TranslatingListenerInvoker.createConfig(listener, normalizer);
+        translatingCfgListener.register(backingBroker, normalizedPath);
+
+        final TranslatingListenerInvoker translatingOpListener =
+                TranslatingListenerInvoker.createOperational(listener, normalizer);
+        translatingOpListener.register(backingBroker, normalizedPath);
+
+        return new DelegateListenerRegistration(translatingCfgListener, translatingOpListener, listener);
     }
 
     @Override
@@ -90,7 +92,7 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
         return null;
     }
 
-    // Obsolote functionality
+    // Obsolete functionality
 
     @Override
     public void addValidator(final DataStoreIdentifier store, final DataValidator validator) {
@@ -124,25 +126,26 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
         throw new UnsupportedOperationException("Data Reader contract is not supported.");
     }
 
-    private final class TranslatingListenerInvoker implements DOMDataChangeListener, Delegator<DataChangeListener> {
-
+    private static class DelegateListenerRegistration implements ListenerRegistration<DataChangeListener> {
+        private final TranslatingListenerInvoker translatingCfgListener;
+        private final TranslatingListenerInvoker translatingOpListener;
+        private final DataChangeListener listener;
 
-        private DataChangeListener delegate;
+        public DelegateListenerRegistration(final TranslatingListenerInvoker translatingCfgListener, final TranslatingListenerInvoker translatingOpListener, final DataChangeListener listener) {
+            this.translatingCfgListener = translatingCfgListener;
+            this.translatingOpListener = translatingOpListener;
+            this.listener = listener;
+        }
 
         @Override
-        public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
-
-            DataChangeEvent<InstanceIdentifier, CompositeNode> legacyChange = null;
-            delegate.onDataChanged(legacyChange);
+        public void close() {
+            translatingCfgListener.close();
+            translatingOpListener.close();
         }
 
         @Override
-        public DataChangeListener getDelegate() {
-
-            return delegate;
+        public DataChangeListener getInstance() {
+            return listener;
         }
-
-
     }
-
 }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java
new file mode 100644 (file)
index 0000000..827e4ca
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.broker.impl.compat;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import com.google.common.collect.Maps;
+
+public abstract class TranslatingDataChangeEvent implements
+        DataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
+
+    private TranslatingDataChangeEvent() {
+    }
+
+    public static DataChangeEvent<InstanceIdentifier, CompositeNode> createOperational(
+            final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change, final DataNormalizer normalizer) {
+        return new OperationalChangeEvent(change, normalizer);
+    }
+
+    public static DataChangeEvent<InstanceIdentifier, CompositeNode> createConfiguration(
+            final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change, final DataNormalizer normalizer) {
+        return new ConfigurationChangeEvent(change, normalizer);
+    }
+
+    @Override
+    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getCreatedOperationalData() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> getRemovedConfigurationData() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> getRemovedOperationalData() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getOriginalOperationalData() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public CompositeNode getOriginalConfigurationSubtree() {
+        return null;
+    }
+
+    @Override
+    public CompositeNode getOriginalOperationalSubtree() {
+        return null;
+    }
+
+    @Override
+    public CompositeNode getUpdatedConfigurationSubtree() {
+        return null;
+    }
+
+    @Override
+    public CompositeNode getUpdatedOperationalSubtree() {
+        return null;
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private final static class OperationalChangeEvent extends TranslatingDataChangeEvent {
+
+        private final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> delegate;
+        private final DataNormalizer normalizer;
+        private Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedCache;
+
+        public OperationalChangeEvent(final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change,
+                                        final DataNormalizer normalizer) {
+            this.delegate = change;
+            this.normalizer = normalizer;
+        }
+
+        @Override
+        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getCreatedOperationalData() {
+            return transformToLegacy(normalizer, delegate.getCreatedData());
+        }
+
+
+        @Override
+        public Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> getRemovedOperationalData() {
+            return delegate.getRemovedPaths();
+        }
+
+        @Override
+        public CompositeNode getOriginalOperationalSubtree() {
+            // first argument is unused
+            return normalizer.toLegacy(null, delegate.getOriginalSubtree());
+        }
+
+        @Override
+        public CompositeNode getUpdatedOperationalSubtree() {
+            // first argument is unused
+            return normalizer.toLegacy(null, delegate.getUpdatedSubtree());
+        }
+
+        @Override
+        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getOriginalOperationalData() {
+            return transformToLegacy(normalizer, delegate.getOriginalData());
+        }
+
+        @Override
+        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
+            if(updatedCache == null) {
+                final Map<InstanceIdentifier, CompositeNode> updated = transformToLegacy(normalizer, delegate.getUpdatedData());
+                final Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> created = getCreatedConfigurationData();
+                final HashMap<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedComposite = new HashMap<>(created.size() + updated.size());
+                updatedComposite.putAll(created);
+                updatedComposite.putAll(updated);
+                updatedCache = Collections.unmodifiableMap(updatedComposite);
+            }
+            return updatedCache;
+        }
+
+        @Override
+        public String toString() {
+            return "OperationalChangeEvent [delegate=" + delegate + "]";
+        }
+
+    }
+
+    private static Map<InstanceIdentifier, CompositeNode> transformToLegacy(final DataNormalizer normalizer, final Map<InstanceIdentifier, ? extends NormalizedNode<?, ?>> nodes) {
+        final Map<InstanceIdentifier, CompositeNode> legacy = Maps.newHashMap();
+
+        for (final Map.Entry<InstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : nodes.entrySet()) {
+            try {
+                legacy.put(normalizer.toLegacy(entry.getKey()), normalizer.toLegacy(entry.getKey(), entry.getValue()));
+            } catch (final DataNormalizationException e) {
+                throw new IllegalStateException("Unable to transform data change event to legacy format", e);
+            }
+        }
+        return legacy;
+    }
+
+    private final static class ConfigurationChangeEvent extends TranslatingDataChangeEvent {
+
+        private final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> delegate;
+        private final DataNormalizer normalizer;
+        private Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedCache;
+
+        public ConfigurationChangeEvent(final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change,
+                                        final DataNormalizer normalizer) {
+            this.delegate = change;
+            this.normalizer = normalizer;
+        }
+
+        @Override
+        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
+            return transformToLegacy(normalizer, delegate.getCreatedData());
+        }
+
+
+        @Override
+        public Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> getRemovedConfigurationData() {
+            return delegate.getRemovedPaths();
+        }
+
+        @Override
+        public CompositeNode getOriginalConfigurationSubtree() {
+            // first argument is unused
+            return normalizer.toLegacy(null, delegate.getOriginalSubtree());
+        }
+
+        @Override
+        public CompositeNode getUpdatedConfigurationSubtree() {
+            // first argument is unused
+            return normalizer.toLegacy(null, delegate.getUpdatedSubtree());
+        }
+
+        @Override
+        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
+            return transformToLegacy(normalizer, delegate.getOriginalData());
+        }
+
+        @Override
+        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
+            if(updatedCache == null) {
+                final Map<InstanceIdentifier, CompositeNode> updated = transformToLegacy(normalizer, delegate.getUpdatedData());
+                final Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> created = getCreatedConfigurationData();
+                final HashMap<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedComposite = new HashMap<>(created.size() + updated.size());
+                updatedComposite.putAll(created);
+                updatedComposite.putAll(updated);
+                updatedCache = Collections.unmodifiableMap(updatedComposite);
+            }
+            return updatedCache;
+        }
+
+        @Override
+        public String toString() {
+            return "ConfigurationChangeEvent [delegate=" + delegate + "]";
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingListenerInvoker.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingListenerInvoker.java
new file mode 100644 (file)
index 0000000..1ce252d
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.broker.impl.compat;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+abstract class TranslatingListenerInvoker implements AutoCloseable, DOMDataChangeListener, Delegator<DataChangeListener> {
+
+    private final DataChangeListener delegate;
+    private final DataNormalizer normalizer;
+    protected ListenerRegistration<DOMDataChangeListener> reg;
+
+    protected TranslatingListenerInvoker(final DataChangeListener listener, final DataNormalizer normalizer) {
+        this.delegate = listener;
+        this.normalizer = normalizer;
+    }
+
+    static TranslatingListenerInvoker createConfig(final DataChangeListener listener, final DataNormalizer normalizer) {
+        return new TranslatingConfigListenerInvoker(listener, normalizer);
+    }
+
+    static TranslatingListenerInvoker createOperational(final DataChangeListener listener, final DataNormalizer normalizer) {
+        return new TranslatingOperationalListenerInvoker(listener, normalizer);
+    }
+
+    @Override
+    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
+        delegate.onDataChanged(getLegacyEvent(normalizer, normalizedChange));
+    }
+
+    abstract DataChangeEvent<InstanceIdentifier, CompositeNode> getLegacyEvent(final DataNormalizer normalizer,
+                                                                               final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> normalizedChange);
+
+    @Override
+    public DataChangeListener getDelegate() {
+        return delegate;
+    }
+
+    abstract void register(final DOMDataBroker backingBroker, final InstanceIdentifier normalizedPath);
+
+    @Override
+    public void close() {
+        if (reg != null) {
+            reg.close();
+        }
+    }
+
+    static final class TranslatingConfigListenerInvoker extends TranslatingListenerInvoker {
+
+        public TranslatingConfigListenerInvoker(final DataChangeListener listener, final DataNormalizer normalizer) {
+            super(listener, normalizer);
+        }
+
+        DataChangeEvent<InstanceIdentifier, CompositeNode> getLegacyEvent(final DataNormalizer normalizer, final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
+            return TranslatingDataChangeEvent.createConfiguration(normalizedChange, normalizer);
+        }
+
+        @Override
+        void register(final DOMDataBroker backingBroker, final InstanceIdentifier normalizedPath) {
+            reg = backingBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, normalizedPath, this,
+                    AsyncDataBroker.DataChangeScope.SUBTREE);
+        }
+    }
+
+    static final class TranslatingOperationalListenerInvoker extends TranslatingListenerInvoker {
+
+        public TranslatingOperationalListenerInvoker(final DataChangeListener listener, final DataNormalizer normalizer) {
+            super(listener, normalizer);
+        }
+
+        DataChangeEvent<InstanceIdentifier, CompositeNode> getLegacyEvent(final DataNormalizer normalizer, final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
+            return TranslatingDataChangeEvent.createOperational(normalizedChange, normalizer);
+        }
+
+        @Override
+        void register(final DOMDataBroker backingBroker, final InstanceIdentifier normalizedPath) {
+            reg = backingBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, normalizedPath, this,
+                    AsyncDataBroker.DataChangeScope.SUBTREE);
+        }
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataPreconditionFailedException.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataPreconditionFailedException.java
deleted file mode 100644 (file)
index 6baf764..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2014 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.md.sal.dom.store.impl;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-public class DataPreconditionFailedException extends Exception {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 596430355175413427L;
-    private final InstanceIdentifier path;
-
-    public DataPreconditionFailedException(final InstanceIdentifier path) {
-        this.path = path;
-    }
-
-    public DataPreconditionFailedException(final InstanceIdentifier path,final String message) {
-        super(message);
-        this.path = path;
-    }
-
-
-    public DataPreconditionFailedException(final InstanceIdentifier path,final Throwable cause) {
-        super(cause);
-        this.path = path;
-    }
-
-    public DataPreconditionFailedException(final InstanceIdentifier path,final String message, final Throwable cause) {
-        super(message, cause);
-        this.path = path;
-    }
-
-    public DataPreconditionFailedException(final InstanceIdentifier path,final String message, final Throwable cause, final boolean enableSuppression,
-            final boolean writableStackTrace) {
-        super(message, cause, enableSuppression, writableStackTrace);
-        this.path = path;
-    }
-
-    public InstanceIdentifier getPath() {
-        return path;
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataTree.java
deleted file mode 100644 (file)
index 3124199..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2014 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.md.sal.dom.store.impl;
-
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
-/**
- * Read-only snapshot of the data tree.
- */
-final class DataTree {
-    public static final class Snapshot {
-        private final SchemaContext schemaContext;
-        private final StoreMetadataNode rootNode;
-
-        @VisibleForTesting
-        Snapshot(final SchemaContext schemaContext, final StoreMetadataNode rootNode) {
-            this.schemaContext = Preconditions.checkNotNull(schemaContext);
-            this.rootNode = Preconditions.checkNotNull(rootNode);
-        }
-
-        public SchemaContext getSchemaContext() {
-            return schemaContext;
-        }
-
-        public Optional<NormalizedNode<?, ?>> readNode(final InstanceIdentifier path) {
-            return NormalizedNodeUtils.findNode(rootNode.getData(), path);
-        }
-
-        // FIXME: this is a leak of information
-        @Deprecated
-        StoreMetadataNode getRootNode() {
-            return rootNode;
-        }
-
-        @Override
-        public String toString() {
-            return rootNode.getSubtreeVersion().toString();
-        }
-    }
-
-    private static final Logger LOG = LoggerFactory.getLogger(DataTree.class);
-    private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
-    private StoreMetadataNode rootNode;
-    private SchemaContext currentSchemaContext;
-
-    private DataTree(StoreMetadataNode rootNode, final SchemaContext schemaContext) {
-        this.rootNode = Preconditions.checkNotNull(rootNode);
-        this.currentSchemaContext = schemaContext;
-    }
-
-    public synchronized void setSchemaContext(final SchemaContext newSchemaContext) {
-        Preconditions.checkNotNull(newSchemaContext);
-
-        LOG.info("Attepting to install schema context {}", newSchemaContext);
-
-        /*
-         * FIXME: we should walk the schema contexts, both current and new and see
-         *        whether they are compatible here. Reject incompatible changes.
-         */
-
-        // Ready to change the context now, make sure no operations are running
-        rwLock.writeLock().lock();
-        try {
-            this.currentSchemaContext = newSchemaContext;
-        } finally {
-            rwLock.writeLock().unlock();
-        }
-    }
-
-    public static DataTree create(final SchemaContext schemaContext) {
-        final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME);
-        final NormalizedNode<?, ?> data = Builders.containerBuilder().withNodeIdentifier(root).build();
-
-        return new DataTree(StoreMetadataNode.createEmpty(data), schemaContext);
-    }
-
-    public Snapshot takeSnapshot() {
-        rwLock.readLock().lock();
-
-        try {
-            return new Snapshot(currentSchemaContext, rootNode);
-        } finally {
-            rwLock.readLock().unlock();
-        }
-    }
-
-    public void commitSnapshot(Snapshot currentSnapshot, StoreMetadataNode newDataTree) {
-        // Ready to change the context now, make sure no operations are running
-        rwLock.writeLock().lock();
-        try {
-            Preconditions.checkState(currentSnapshot.rootNode == rootNode,
-                    String.format("Store snapshot %s and transaction snapshot %s differ.",
-                            rootNode, currentSnapshot.rootNode));
-
-            this.rootNode = newDataTree;
-        } finally {
-            rwLock.writeLock().unlock();
-        }
-    }
-}
index 7d2ff30..9e11fc7 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
-import static org.opendaylight.controller.md.sal.dom.store.impl.StoreUtils.increase;
 
 import java.util.Collections;
 import java.util.concurrent.Callable;
@@ -17,10 +16,13 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeSnapshot;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.InMemoryDataTreeFactory;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
@@ -31,7 +33,6 @@ import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
@@ -42,22 +43,17 @@ import com.google.common.base.Objects;
 import com.google.common.base.Objects.ToStringHelper;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.primitives.UnsignedLong;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 
 public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, SchemaContextListener {
-
     private static final Logger LOG = LoggerFactory.getLogger(InMemoryDOMDataStore.class);
-    private static final InstanceIdentifier PUBLIC_ROOT_PATH = InstanceIdentifier.builder().build();
-
+    private final DataTree dataTree = InMemoryDataTreeFactory.getInstance().create();
+    private final ListenerTree listenerTree = ListenerTree.create();
+    private final AtomicLong txCounter = new AtomicLong(0);
     private final ListeningExecutorService executor;
     private final String name;
-    private final AtomicLong txCounter = new AtomicLong(0);
-    private final ListenerTree listenerTree = ListenerTree.create();
-    private final DataTree dataTree = DataTree.create(null);
-    private ModificationApplyOperation operationTree = new AlwaysFailOperation();
 
     public InMemoryDOMDataStore(final String name, final ListeningExecutorService executor) {
         this.name = Preconditions.checkNotNull(name);
@@ -76,25 +72,17 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
 
     @Override
     public DOMStoreReadWriteTransaction newReadWriteTransaction() {
-        return new SnapshotBackedReadWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this, operationTree);
+        return new SnapshotBackedReadWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this);
     }
 
     @Override
     public DOMStoreWriteTransaction newWriteOnlyTransaction() {
-        return new SnapshotBackedWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this, operationTree);
+        return new SnapshotBackedWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this);
     }
 
     @Override
     public synchronized void onGlobalContextUpdated(final SchemaContext ctx) {
-        /*
-         * Order of operations is important: dataTree may reject the context
-         * and creation of ModificationApplyOperation may fail. So pre-construct
-         * the operation, then update the data tree and then move the operation
-         * into view.
-         */
-        final ModificationApplyOperation newOperationTree = SchemaAwareApplyOperationRoot.from(ctx);
         dataTree.setSchemaContext(ctx);
-        operationTree = newOperationTree;
     }
 
     @Override
@@ -145,28 +133,6 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
         return name + "-" + txCounter.getAndIncrement();
     }
 
-    private void commit(final DataTree.Snapshot currentSnapshot, final StoreMetadataNode newDataTree,
-            final ResolveDataChangeEventsTask listenerResolver) {
-        LOG.debug("Updating Store snaphot version: {} with version:{}", currentSnapshot, newDataTree.getSubtreeVersion());
-
-        if (LOG.isTraceEnabled()) {
-            LOG.trace("Data Tree is {}", StoreUtils.toStringTree(newDataTree.getData()));
-        }
-
-        /*
-         * The commit has to occur atomically with regard to listener
-         * registrations.
-         */
-        synchronized (this) {
-            dataTree.commitSnapshot(currentSnapshot, newDataTree);
-
-            for (ChangeListenerNotifyTask task : listenerResolver.call()) {
-                LOG.trace("Scheduling invocation of listeners: {}", task);
-                executor.submit(task);
-            }
-        }
-    }
-
     private static abstract class AbstractDOMStoreTransaction implements DOMStoreTransaction {
         private final Object identifier;
 
@@ -197,10 +163,10 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
     }
 
     private static final class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction implements
-            DOMStoreReadTransaction {
-        private DataTree.Snapshot stableSnapshot;
+    DOMStoreReadTransaction {
+        private DataTreeSnapshot stableSnapshot;
 
-        public SnapshotBackedReadTransaction(final Object identifier, final DataTree.Snapshot snapshot) {
+        public SnapshotBackedReadTransaction(final Object identifier, final DataTreeSnapshot snapshot) {
             super(identifier);
             this.stableSnapshot = Preconditions.checkNotNull(snapshot);
             LOG.debug("ReadOnly Tx: {} allocated with snapshot {}", identifier, snapshot);
@@ -221,15 +187,15 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
     }
 
     private static class SnapshotBackedWriteTransaction extends AbstractDOMStoreTransaction implements
-            DOMStoreWriteTransaction {
-        private MutableDataTree mutableTree;
+    DOMStoreWriteTransaction {
+        private DataTreeModification mutableTree;
         private InMemoryDOMDataStore store;
         private boolean ready = false;
 
-        public SnapshotBackedWriteTransaction(final Object identifier, final DataTree.Snapshot snapshot,
-                final InMemoryDOMDataStore store, final ModificationApplyOperation applyOper) {
+        public SnapshotBackedWriteTransaction(final Object identifier, final DataTreeSnapshot snapshot,
+                final InMemoryDOMDataStore store) {
             super(identifier);
-            mutableTree = MutableDataTree.from(snapshot, applyOper);
+            mutableTree = snapshot.newModification();
             this.store = store;
             LOG.debug("Write Tx: {} allocated with snapshot {}", identifier, snapshot);
         }
@@ -295,7 +261,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
             return store.submit(this);
         }
 
-        protected MutableDataTree getMutatedView() {
+        protected DataTreeModification getMutatedView() {
             return mutableTree;
         }
 
@@ -306,18 +272,18 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
     }
 
     private static class SnapshotBackedReadWriteTransaction extends SnapshotBackedWriteTransaction implements
-            DOMStoreReadWriteTransaction {
+    DOMStoreReadWriteTransaction {
 
-        protected SnapshotBackedReadWriteTransaction(final Object identifier, final DataTree.Snapshot snapshot,
-                final InMemoryDOMDataStore store, final ModificationApplyOperation applyOper) {
-            super(identifier, snapshot, store, applyOper);
+        protected SnapshotBackedReadWriteTransaction(final Object identifier, final DataTreeSnapshot snapshot,
+                final InMemoryDOMDataStore store) {
+            super(identifier, snapshot, store);
         }
 
         @Override
         public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final InstanceIdentifier path) {
             LOG.trace("Tx: {} Read: {}", getIdentifier(), path);
             try {
-                return Futures.immediateFuture(getMutatedView().read(path));
+                return Futures.immediateFuture(getMutatedView().readNode(path));
             } catch (Exception e) {
                 LOG.error("Tx: {} Failed Read of {}", getIdentifier(), path, e);
                 throw e;
@@ -328,63 +294,40 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
     private class ThreePhaseCommitImpl implements DOMStoreThreePhaseCommitCohort {
 
         private final SnapshotBackedWriteTransaction transaction;
-        private final NodeModification modification;
+        private final DataTreeModification modification;
 
-        private DataTree.Snapshot storeSnapshot;
-        private Optional<StoreMetadataNode> proposedSubtree;
         private ResolveDataChangeEventsTask listenerResolver;
+        private DataTreeCandidate candidate;
 
         public ThreePhaseCommitImpl(final SnapshotBackedWriteTransaction writeTransaction) {
             this.transaction = writeTransaction;
-            this.modification = transaction.getMutatedView().getRootModification();
+            this.modification = transaction.getMutatedView();
         }
 
         @Override
         public ListenableFuture<Boolean> canCommit() {
-            final DataTree.Snapshot snapshotCapture = dataTree.takeSnapshot();
-            final ModificationApplyOperation snapshotOperation = operationTree;
-
             return executor.submit(new Callable<Boolean>() {
-
                 @Override
-                public Boolean call() throws Exception {
-                    Boolean applicable = false;
+                public Boolean call() {
                     try {
-                        snapshotOperation.checkApplicable(PUBLIC_ROOT_PATH, modification,
-                            Optional.of(snapshotCapture.getRootNode()));
-                        applicable = true;
+                        dataTree.validate(modification);
+                        LOG.debug("Store Transaction: {} can be committed", transaction.getIdentifier());
+                        return true;
                     } catch (DataPreconditionFailedException e) {
                         LOG.warn("Store Tx: {} Data Precondition failed for {}.",transaction.getIdentifier(),e.getPath(),e);
-                        applicable = false;
+                        return false;
                     }
-                    LOG.debug("Store Transaction: {} : canCommit : {}", transaction.getIdentifier(), applicable);
-                    return applicable;
                 }
             });
         }
 
         @Override
         public ListenableFuture<Void> preCommit() {
-            storeSnapshot = dataTree.takeSnapshot();
-            if (modification.getModificationType() == ModificationType.UNMODIFIED) {
-                return Futures.immediateFuture(null);
-            }
             return executor.submit(new Callable<Void>() {
-
                 @Override
-                public Void call() throws Exception {
-                    StoreMetadataNode metadataTree = storeSnapshot.getRootNode();
-
-                    proposedSubtree = operationTree.apply(modification, Optional.of(metadataTree),
-                            increase(metadataTree.getSubtreeVersion()));
-
-                    listenerResolver = ResolveDataChangeEventsTask.create() //
-                            .setRootPath(PUBLIC_ROOT_PATH) //
-                            .setBeforeRoot(Optional.of(metadataTree)) //
-                            .setAfterRoot(proposedSubtree) //
-                            .setModificationRoot(modification) //
-                            .setListenerRoot(listenerTree);
-
+                public Void call() {
+                    candidate = dataTree.prepare(modification);
+                    listenerResolver = ResolveDataChangeEventsTask.create(candidate, listenerTree);
                     return null;
                 }
             });
@@ -392,48 +335,32 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
 
         @Override
         public ListenableFuture<Void> abort() {
-            storeSnapshot = null;
-            proposedSubtree = null;
+            if (candidate != null) {
+                candidate.close();
+                candidate = null;
+            }
+
             return Futures.<Void> immediateFuture(null);
         }
 
         @Override
         public ListenableFuture<Void> commit() {
-            if (modification.getModificationType() == ModificationType.UNMODIFIED) {
-                return Futures.immediateFuture(null);
+            checkState(candidate != null, "Proposed subtree must be computed");
+
+            /*
+             * The commit has to occur atomically with regard to listener
+             * registrations.
+             */
+            synchronized (this) {
+                dataTree.commit(candidate);
+
+                for (ChangeListenerNotifyTask task : listenerResolver.call()) {
+                    LOG.trace("Scheduling invocation of listeners: {}", task);
+                    executor.submit(task);
+                }
             }
 
-            checkState(proposedSubtree != null, "Proposed subtree must be computed");
-            checkState(storeSnapshot != null, "Proposed subtree must be computed");
-            // return ImmediateFuture<>;
-            InMemoryDOMDataStore.this.commit(storeSnapshot, proposedSubtree.get(), listenerResolver);
             return Futures.<Void> immediateFuture(null);
         }
-
-    }
-
-    private static final class AlwaysFailOperation implements ModificationApplyOperation {
-
-        @Override
-        public Optional<StoreMetadataNode> apply(final NodeModification modification,
-                final Optional<StoreMetadataNode> storeMeta, final UnsignedLong subtreeVersion) {
-            throw new IllegalStateException("Schema Context is not available.");
-        }
-
-        @Override
-        public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> storeMetadata) {
-            throw new IllegalStateException("Schema Context is not available.");
-        }
-
-        @Override
-        public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
-            throw new IllegalStateException("Schema Context is not available.");
-        }
-
-        @Override
-        public void verifyStructure(final NodeModification modification) throws IllegalArgumentException {
-            throw new IllegalStateException("Schema Context is not available.");
-        }
-
     }
 }
index 44d5016..db9bb0f 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder;
-import static org.opendaylight.controller.md.sal.dom.store.impl.StoreUtils.append;
+import static org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils.append;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -22,11 +22,12 @@ import java.util.concurrent.Callable;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder;
 import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.SimpleEventFactory;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Node;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Walker;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NodeModification;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.StoreMetadataNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
@@ -38,6 +39,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -62,61 +64,18 @@ import com.google.common.collect.Multimap;
  * </ul>
  *
  */
-public class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListenerNotifyTask>> {
+final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListenerNotifyTask>> {
     private static final Logger LOG = LoggerFactory.getLogger(ResolveDataChangeEventsTask.class);
     private static final DOMImmutableDataChangeEvent NO_CHANGE = builder(DataChangeScope.BASE).build();
 
-    private InstanceIdentifier rootPath;
-    private ListenerTree listenerRoot;
-    private NodeModification modificationRoot;
-    private Optional<StoreMetadataNode> beforeRoot;
-    private Optional<StoreMetadataNode> afterRoot;
     private final Multimap<ListenerTree.Node, DOMImmutableDataChangeEvent> events = HashMultimap.create();
+    private final DataTreeCandidate candidate;
+    private final ListenerTree listenerRoot;
 
-    protected InstanceIdentifier getRootPath() {
-        return rootPath;
-    }
-
-    protected ResolveDataChangeEventsTask setRootPath(final InstanceIdentifier rootPath) {
-        this.rootPath = rootPath;
-        return this;
-    }
-
-    protected ListenerTree getListenerRoot() {
-        return listenerRoot;
-    }
-
-    protected ResolveDataChangeEventsTask setListenerRoot(final ListenerTree listenerRoot) {
-        this.listenerRoot = listenerRoot;
-        return this;
-    }
-
-    protected NodeModification getModificationRoot() {
-        return modificationRoot;
-    }
-
-    protected ResolveDataChangeEventsTask setModificationRoot(final NodeModification modificationRoot) {
-        this.modificationRoot = modificationRoot;
-        return this;
-    }
-
-    protected Optional<StoreMetadataNode> getBeforeRoot() {
-        return beforeRoot;
-    }
-
-    protected ResolveDataChangeEventsTask setBeforeRoot(final Optional<StoreMetadataNode> beforeRoot) {
-        this.beforeRoot = beforeRoot;
-        return this;
-    }
-
-    protected Optional<StoreMetadataNode> getAfterRoot() {
-        return afterRoot;
-    }
-
-    protected ResolveDataChangeEventsTask setAfterRoot(final Optional<StoreMetadataNode> afterRoot) {
-        this.afterRoot = afterRoot;
-        return this;
-    }
+    public ResolveDataChangeEventsTask(DataTreeCandidate candidate, ListenerTree listenerTree) {
+       this.candidate = Preconditions.checkNotNull(candidate);
+       this.listenerRoot = Preconditions.checkNotNull(listenerTree);
+       }
 
     /**
      * Resolves and creates Notification Tasks
@@ -129,11 +88,10 @@ public class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeList
      */
     @Override
     public Iterable<ChangeListenerNotifyTask> call() {
-        LOG.trace("Resolving events for {}", modificationRoot);
-
         try (final Walker w = listenerRoot.getWalker()) {
-            resolveAnyChangeEvent(rootPath, Collections.singleton(w.getRootNode()), modificationRoot, beforeRoot,
-                    afterRoot);
+            resolveAnyChangeEvent(candidate.getRootPath(), Collections.singleton(w.getRootNode()),
+                       candidate.getModificationRoot(), Optional.fromNullable(candidate.getBeforeRoot()),
+                       Optional.fromNullable(candidate.getAfterRoot()));
             return createNotificationTasks();
         }
     }
@@ -556,7 +514,7 @@ public class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeList
         }
     }
 
-    public static ResolveDataChangeEventsTask create() {
-        return new ResolveDataChangeEventsTask();
-    }
+       public static ResolveDataChangeEventsTask create(DataTreeCandidate candidate, ListenerTree listenerTree) {
+        return new ResolveDataChangeEventsTask(candidate, listenerTree);
+       }
 }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataPreconditionFailedException.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataPreconditionFailedException.java
new file mode 100644 (file)
index 0000000..bb2111e
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+import com.google.common.base.Preconditions;
+
+public class DataPreconditionFailedException extends Exception {
+    private static final long serialVersionUID = 1L;
+    private final InstanceIdentifier path;
+
+    public DataPreconditionFailedException(final InstanceIdentifier path, final String message) {
+        super(message);
+        this.path = Preconditions.checkNotNull(path);
+    }
+
+    public DataPreconditionFailedException(final InstanceIdentifier path, final String message, final Throwable cause) {
+        super(message, cause);
+        this.path = Preconditions.checkNotNull(path);
+    }
+
+    public InstanceIdentifier getPath() {
+        return path;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTree.java
new file mode 100644 (file)
index 0000000..01e2a29
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree;
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Interface representing a data tree which can be modified in an MVCC fashion.
+ */
+public interface DataTree {
+       /**
+        * Take a read-only point-in-time snapshot of the tree.
+        *
+        * @return Data tree snapshot.
+        */
+       DataTreeSnapshot takeSnapshot();
+
+       /**
+        * Make the data tree use a new schema context. The context will be used
+        * only by subsequent operations.
+        *
+        * @param newSchemaContext new SchemaContext
+        * @throws IllegalArgumentException if the new context is incompatible
+        */
+    void setSchemaContext(SchemaContext newSchemaContext);
+
+    /**
+     * Validate whether a particular modification can be applied to the data tree.
+     */
+    void validate(DataTreeModification modification) throws DataPreconditionFailedException;
+
+    /**
+     * Prepare a modification for commit.
+     *
+     * @param modification
+     * @return candidate data tree
+     */
+    DataTreeCandidate prepare(DataTreeModification modification);
+
+    /**
+     * Commit a data tree candidate.
+     *
+     * @param candidate data tree candidate
+     */
+    void commit(DataTreeCandidate candidate);
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidate.java
new file mode 100644 (file)
index 0000000..79ce37e
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NodeModification;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.StoreMetadataNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public interface DataTreeCandidate extends AutoCloseable {
+       @Override
+       void close();
+
+       InstanceIdentifier getRootPath();
+
+       @Deprecated
+       NodeModification getModificationRoot();
+
+       @Deprecated
+       StoreMetadataNode getBeforeRoot();
+
+       @Deprecated
+       StoreMetadataNode getAfterRoot();
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeFactory.java
new file mode 100644 (file)
index 0000000..7422c11
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree;
+
+/**
+ * Factory interface for creating data trees.
+ */
+public interface DataTreeFactory {
+       /**
+        * Create a new data tree.
+        *
+        * @return A data tree instance.
+        */
+       DataTree create();
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java
new file mode 100644 (file)
index 0000000..cff90a4
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Class encapsulation of set of modifications to a base tree. This tree is backed
+ * by a read-only snapshot and tracks modifications on top of that. The modification
+ * has the ability to rebase itself to a new snapshot.
+ */
+public interface DataTreeModification extends DataTreeSnapshot {
+       void delete(InstanceIdentifier path);
+       void merge(InstanceIdentifier path, NormalizedNode<?, ?> data);
+       void write(InstanceIdentifier path, NormalizedNode<?, ?> data);
+       void seal();
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeSnapshot.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeSnapshot.java
new file mode 100644 (file)
index 0000000..a94acc5
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import com.google.common.base.Optional;
+
+/**
+ * Read-only snapshot of a {@link DataTree}. The snapshot is stable and isolated,
+ * e.g. data tree changes occurring after the snapshot has been taken are not
+ * visible through the snapshot.
+ */
+public interface DataTreeSnapshot {
+    /**
+     * Read a particular node from the snapshot.
+     *
+     * @param path Path of the node
+     * @return Optional result encapsulating the presence and value of the node
+     */
+    Optional<NormalizedNode<?, ?>> readNode(InstanceIdentifier path);
+
+    /**
+     * Create a new data tree modification based on this snapshot, using the
+     * specified data application strategy.
+     *
+     * @param strategy data modification strategy
+     * @return A new data tree modification
+     */
+    DataTreeModification newModification();
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java
new file mode 100644 (file)
index 0000000..b2faf79
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree.data;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+import com.google.common.base.Preconditions;
+
+abstract class AbstractDataTreeCandidate implements DataTreeCandidate {
+       private final InstanceIdentifier rootPath;
+       private final NodeModification modificationRoot;
+
+       protected AbstractDataTreeCandidate(final InstanceIdentifier rootPath, NodeModification modificationRoot) {
+               this.rootPath = Preconditions.checkNotNull(rootPath);
+               this.modificationRoot = Preconditions.checkNotNull(modificationRoot);
+       }
+
+       @Override
+       public final InstanceIdentifier getRootPath() {
+               return rootPath;
+       }
+
+       @Override
+       public final NodeModification getModificationRoot() {
+               return modificationRoot;
+       }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java
new file mode 100644 (file)
index 0000000..4e3aa49
--- /dev/null
@@ -0,0 +1,31 @@
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+
+import com.google.common.base.Optional;
+import com.google.common.primitives.UnsignedLong;
+
+final class AlwaysFailOperation implements ModificationApplyOperation {
+
+    @Override
+    public Optional<StoreMetadataNode> apply(final NodeModification modification,
+            final Optional<StoreMetadataNode> storeMeta, final UnsignedLong subtreeVersion) {
+        throw new IllegalStateException("Schema Context is not available.");
+    }
+
+    @Override
+    public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> storeMetadata) {
+        throw new IllegalStateException("Schema Context is not available.");
+    }
+
+    @Override
+    public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
+        throw new IllegalStateException("Schema Context is not available.");
+    }
+
+    @Override
+    public void verifyStructure(final NodeModification modification) throws IllegalArgumentException {
+        throw new IllegalStateException("Schema Context is not available.");
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java
new file mode 100644 (file)
index 0000000..5a300a0
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree.data;
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ * Read-only snapshot of the data tree.
+ */
+final class InMemoryDataTree implements DataTree {
+    private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTree.class);
+    private static final InstanceIdentifier PUBLIC_ROOT_PATH = InstanceIdentifier.builder().build();
+
+    private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
+    private ModificationApplyOperation applyOper = new AlwaysFailOperation();
+    private SchemaContext currentSchemaContext;
+    private StoreMetadataNode rootNode;
+
+    public InMemoryDataTree(StoreMetadataNode rootNode, final SchemaContext schemaContext) {
+        this.rootNode = Preconditions.checkNotNull(rootNode);
+
+        if (schemaContext != null) {
+            // Also sets applyOper
+            setSchemaContext(schemaContext);
+        }
+    }
+
+    @Override
+    public synchronized void setSchemaContext(final SchemaContext newSchemaContext) {
+        Preconditions.checkNotNull(newSchemaContext);
+
+        LOG.info("Attepting to install schema context {}", newSchemaContext);
+
+        /*
+         * FIXME: we should walk the schema contexts, both current and new and see
+         *        whether they are compatible here. Reject incompatible changes.
+         */
+
+        // Instantiate new apply operation, this still may fail
+        final ModificationApplyOperation newApplyOper = SchemaAwareApplyOperation.from(newSchemaContext);
+
+        // Ready to change the context now, make sure no operations are running
+        rwLock.writeLock().lock();
+        try {
+            this.applyOper = newApplyOper;
+            this.currentSchemaContext = newSchemaContext;
+        } finally {
+            rwLock.writeLock().unlock();
+        }
+    }
+
+    @Override
+    public InMemoryDataTreeSnapshot takeSnapshot() {
+        rwLock.readLock().lock();
+        try {
+            return new InMemoryDataTreeSnapshot(currentSchemaContext, rootNode, applyOper);
+        } finally {
+            rwLock.readLock().unlock();
+        }
+    }
+
+    @Override
+    public void validate(DataTreeModification modification) throws DataPreconditionFailedException {
+        Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
+
+        final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
+        m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.of(rootNode));
+    }
+
+    @Override
+    public synchronized DataTreeCandidate prepare(DataTreeModification modification) {
+        Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
+
+        final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
+        final NodeModification root = m.getRootModification();
+
+        if (root.getModificationType() == ModificationType.UNMODIFIED) {
+            return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root);
+        }
+
+        rwLock.writeLock().lock();
+        try {
+            // FIXME: rootNode needs to be a read-write snapshot here...
+            final Optional<StoreMetadataNode> newRoot = m.getStrategy().apply(m.getRootModification(), Optional.of(rootNode), StoreUtils.increase(rootNode.getSubtreeVersion()));
+            Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node");
+            return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, rootNode, newRoot.get());
+        } finally {
+            rwLock.writeLock().unlock();
+        }
+    }
+
+    @Override
+    public synchronized void commit(DataTreeCandidate candidate) {
+        if (candidate instanceof NoopDataTreeCandidate) {
+            return;
+        }
+
+        Preconditions.checkArgument(candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass());
+        final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate;
+
+        LOG.debug("Updating Store snapshot version: {} with version:{}", rootNode.getSubtreeVersion(), c.getAfterRoot().getSubtreeVersion());
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Data Tree is {}", StoreUtils.toStringTree(c.getAfterRoot().getData()));
+        }
+
+        // Ready to change the context now, make sure no operations are running
+        rwLock.writeLock().lock();
+        try {
+            Preconditions.checkState(c.getBeforeRoot() == rootNode,
+                    String.format("Store snapshot %s and transaction snapshot %s differ.", rootNode, c.getBeforeRoot()));
+            this.rootNode = c.getAfterRoot();
+        } finally {
+            rwLock.writeLock().unlock();
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java
new file mode 100644 (file)
index 0000000..93719b7
--- /dev/null
@@ -0,0 +1,32 @@
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+import com.google.common.base.Preconditions;
+
+final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
+       private final StoreMetadataNode newRoot;
+       private final StoreMetadataNode oldRoot;
+
+       InMemoryDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot,
+                       final StoreMetadataNode oldRoot, final StoreMetadataNode newRoot) {
+               super(rootPath, modificationRoot);
+               this.newRoot = Preconditions.checkNotNull(newRoot);
+               this.oldRoot = Preconditions.checkNotNull(oldRoot);
+       }
+
+       @Override
+       public void close() {
+               // FIXME: abort operation here :)
+       }
+
+       @Override
+       public StoreMetadataNode getBeforeRoot() {
+               return oldRoot;
+       }
+
+       @Override
+       public StoreMetadataNode getAfterRoot() {
+               return newRoot;
+       }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java
new file mode 100644 (file)
index 0000000..7614611
--- /dev/null
@@ -0,0 +1,35 @@
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeFactory;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * A factory for creating in-memory data trees.
+ */
+public final class InMemoryDataTreeFactory implements DataTreeFactory {
+       private static final InMemoryDataTreeFactory INSTANCE = new InMemoryDataTreeFactory();
+
+       private InMemoryDataTreeFactory() {
+               // Never instantiated externally
+       }
+
+       @Override
+       public InMemoryDataTree create() {
+               final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME);
+               final NormalizedNode<?, ?> data = Builders.containerBuilder().withNodeIdentifier(root).build();
+
+               return new InMemoryDataTree(StoreMetadataNode.createEmpty(data), null);
+       }
+
+       /**
+        * Get an instance of this factory. This method cannot fail.
+        *
+        * @return Data tree factory instance.
+        */
+       public static final InMemoryDataTreeFactory getInstance() {
+               return INSTANCE;
+       }
+}
@@ -5,15 +5,15 @@
  * 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.md.sal.dom.store.impl;
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import static com.google.common.base.Preconditions.checkState;
 
 import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
@@ -26,28 +26,42 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
-/*
- * FIXME: the thread safety of concurrent write/delete/read/seal operations
- *        needs to be evaluated.
- */
-class MutableDataTree {
-    private static final Logger LOG = LoggerFactory.getLogger(MutableDataTree.class);
-    private final AtomicBoolean sealed = new AtomicBoolean();
+final class InMemoryDataTreeModification implements DataTreeModification {
+    private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class);
+
+    /*
+     * FIXME: the thread safety of concurrent write/delete/read/seal operations
+     *        needs to be evaluated.
+     */
+    private static final AtomicIntegerFieldUpdater<InMemoryDataTreeModification> SEALED_UPDATER =
+            AtomicIntegerFieldUpdater.newUpdater(InMemoryDataTreeModification.class, "sealed");
+    private volatile int sealed = 0;
+
     private final ModificationApplyOperation strategyTree;
-    private final NodeModification rootModification;
-    private final DataTree.Snapshot snapshot;
+    private final InMemoryDataTreeSnapshot snapshot;
+    private final NodeModification rootNode;
 
-    private MutableDataTree(final DataTree.Snapshot snapshot, final ModificationApplyOperation strategyTree) {
+    InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final ModificationApplyOperation resolver) {
         this.snapshot = Preconditions.checkNotNull(snapshot);
-        this.strategyTree = Preconditions.checkNotNull(strategyTree);
-        this.rootModification = NodeModification.createUnmodified(snapshot.getRootNode());
+        this.strategyTree = Preconditions.checkNotNull(resolver);
+        this.rootNode = NodeModification.createUnmodified(snapshot.getRootNode());
     }
 
+    NodeModification getRootModification() {
+        return rootNode;
+    }
+
+    ModificationApplyOperation getStrategy() {
+        return strategyTree;
+    }
+
+    @Override
     public void write(final InstanceIdentifier path, final NormalizedNode<?, ?> value) {
         checkSealed();
         resolveModificationFor(path).write(value);
     }
 
+    @Override
     public void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
         checkSealed();
         mergeImpl(resolveModificationFor(path),data);
@@ -66,13 +80,15 @@ class MutableDataTree {
         op.merge(data);
     }
 
+    @Override
     public void delete(final InstanceIdentifier path) {
         checkSealed();
         resolveModificationFor(path).delete();
     }
 
-    public Optional<NormalizedNode<?, ?>> read(final InstanceIdentifier path) {
-        Entry<InstanceIdentifier, NodeModification> modification = TreeNodeUtils.findClosestsOrFirstMatch(rootModification, path, NodeModification.IS_TERMINAL_PREDICATE);
+    @Override
+    public Optional<NormalizedNode<?, ?>> readNode(final InstanceIdentifier path) {
+        Entry<InstanceIdentifier, NodeModification> modification = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, NodeModification.IS_TERMINAL_PREDICATE);
 
         Optional<StoreMetadataNode> result = resolveSnapshot(modification);
         if (result.isPresent()) {
@@ -110,7 +126,7 @@ class MutableDataTree {
     }
 
     private OperationWithModification resolveModificationFor(final InstanceIdentifier path) {
-        NodeModification modification = rootModification;
+        NodeModification modification = rootNode;
         // We ensure strategy is present.
         ModificationApplyOperation operation = resolveModificationStrategy(path);
         for (PathArgument pathArg : path.getPath()) {
@@ -119,26 +135,25 @@ class MutableDataTree {
         return OperationWithModification.from(operation, modification);
     }
 
-    public static MutableDataTree from(final DataTree.Snapshot snapshot, final ModificationApplyOperation resolver) {
-        return new MutableDataTree(snapshot, resolver);
-    }
-
+    @Override
     public void seal() {
-        final boolean success = sealed.compareAndSet(false, true);
+        final boolean success = SEALED_UPDATER.compareAndSet(this, 0, 1);
         Preconditions.checkState(success, "Attempted to seal an already-sealed Data Tree.");
-        rootModification.seal();
+        rootNode.seal();
     }
 
     private void checkSealed() {
-        checkState(!sealed.get(), "Data Tree is sealed. No further modifications allowed.");
+        checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed.");
     }
 
-    protected NodeModification getRootModification() {
-        return rootModification;
+    @Override
+    public String toString() {
+        return "MutableDataTree [modification=" + rootNode + "]";
     }
 
     @Override
-    public String toString() {
-        return "MutableDataTree [modification=" + rootModification + "]";
+    public DataTreeModification newModification() {
+        // FIXME: transaction chaining
+        throw new UnsupportedOperationException("Implement this as part of transaction chaining");
     }
 }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java
new file mode 100644 (file)
index 0000000..ce2d8c9
--- /dev/null
@@ -0,0 +1,47 @@
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeSnapshot;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+final class InMemoryDataTreeSnapshot implements DataTreeSnapshot {
+    private final ModificationApplyOperation applyOper;
+    private final SchemaContext schemaContext;
+    private final StoreMetadataNode rootNode;
+
+    InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final StoreMetadataNode rootNode,
+            final ModificationApplyOperation applyOper) {
+        this.schemaContext = Preconditions.checkNotNull(schemaContext);
+        this.rootNode = Preconditions.checkNotNull(rootNode);
+        this.applyOper = Preconditions.checkNotNull(applyOper);
+    }
+
+    StoreMetadataNode getRootNode() {
+        return rootNode;
+    }
+
+    SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    @Override
+    public Optional<NormalizedNode<?, ?>> readNode(final InstanceIdentifier path) {
+        return NormalizedNodeUtils.findNode(rootNode.getData(), path);
+    }
+
+    @Override
+    public InMemoryDataTreeModification newModification() {
+        return new InMemoryDataTreeModification(this, applyOper);
+    }
+
+    @Override
+    public String toString() {
+        return rootNode.getSubtreeVersion().toString();
+    }
+
+}
\ No newline at end of file
@@ -5,10 +5,9 @@
  * 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.md.sal.dom.store.impl;
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
@@ -38,7 +37,7 @@ import com.google.common.primitives.UnsignedLong;
  *
  *
  */
-public interface ModificationApplyOperation extends StoreTreeNode<ModificationApplyOperation> {
+interface ModificationApplyOperation extends StoreTreeNode<ModificationApplyOperation> {
 
     /**
      *
@@ -80,14 +79,14 @@ public interface ModificationApplyOperation extends StoreTreeNode<ModificationAp
     Optional<ModificationApplyOperation> getChild(PathArgument child);
 
     /**
-    *
-    * Checks if provided node modification could be applied to current metadata node.
-    *
-    * @param modification Modification
-    * @param current Metadata Node to which modification should be applied
-    * @return true if modification is applicable
-    *         false if modification is no applicable
+     *
+     * Checks if provided node modification could be applied to current metadata node.
+     *
+     * @param modification Modification
+     * @param current Metadata Node to which modification should be applied
+     * @return true if modification is applicable
+     *         false if modification is no applicable
      * @throws DataPreconditionFailedException
-    */
+     */
     void checkApplicable(InstanceIdentifier path, NodeModification modification, Optional<StoreMetadataNode> current) throws DataPreconditionFailedException;
 }
@@ -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.md.sal.dom.store.impl.tree;
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import static com.google.common.base.Preconditions.checkState;
 
@@ -14,6 +14,7 @@ import java.util.Map;
 
 import javax.annotation.concurrent.GuardedBy;
 
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -31,6 +32,7 @@ import com.google.common.base.Predicate;
  * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}.
  *
  */
+// FIXME: hide this class
 public class NodeModification implements StoreTreeNode<NodeModification>, Identifiable<PathArgument> {
 
     public static final Predicate<NodeModification> IS_TERMINAL_PREDICATE = new Predicate<NodeModification>() {
@@ -67,7 +69,7 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
      *
      * @return
      */
-    public NormalizedNode<?, ?> getWritenValue() {
+    public NormalizedNode<?, ?> getWrittenValue() {
         return value;
     }
 
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java
new file mode 100644 (file)
index 0000000..1782da2
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree.data;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+final class NoopDataTreeCandidate extends AbstractDataTreeCandidate {
+       protected NoopDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot) {
+               super(rootPath, modificationRoot);
+       }
+
+       @Override
+       public void close() {
+               // NO-OP
+       }
+
+       @Override
+       public StoreMetadataNode getBeforeRoot() {
+               return null;
+       }
+
+       @Override
+       public StoreMetadataNode getAfterRoot() {
+               return null;
+       }
+}
@@ -5,17 +5,15 @@
  * 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.md.sal.dom.store.impl;
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
 import com.google.common.primitives.UnsignedLong;
 
-public class OperationWithModification {
+final class OperationWithModification {
 
     private final NodeModification modification;
 
@@ -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.md.sal.dom.store.impl;
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
@@ -15,10 +15,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreNodeCompositeBuilder;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
@@ -70,7 +68,7 @@ import com.google.common.cache.LoadingCache;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.primitives.UnsignedLong;
 
-public abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
+abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
 
     public static SchemaAwareApplyOperation from(final DataSchemaNode schemaNode) {
         if (schemaNode instanceof ContainerSchemaNode) {
@@ -111,15 +109,17 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
     public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree,
             final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) {
         AugmentationSchema augSchema = null;
-        allAugments: for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) {
-            boolean containsAll = true;
-            for (DataSchemaNode child : potential.getChildNodes()) {
-                if (identifier.getPossibleChildNames().contains(child.getQName())) {
-                    augSchema = potential;
-                    break allAugments;
+
+        allAugments:
+            for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) {
+                for (DataSchemaNode child : potential.getChildNodes()) {
+                    if (identifier.getPossibleChildNames().contains(child.getQName())) {
+                        augSchema = potential;
+                        break allAugments;
+                    }
                 }
             }
-        }
+
         if (augSchema != null) {
             return new AugmentationModificationStrategy(augSchema, resolvedTree);
         }
@@ -135,11 +135,11 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
     @Override
     public void verifyStructure(final NodeModification modification) throws IllegalArgumentException {
         if (modification.getModificationType() == ModificationType.WRITE) {
-            verifyWritenStructure(modification.getWritenValue());
+            verifyWrittenStructure(modification.getWrittenValue());
         }
     }
 
-    protected abstract void verifyWritenStructure(NormalizedNode<?, ?> writenValue);
+    protected abstract void verifyWrittenStructure(NormalizedNode<?, ?> writtenValue);
 
     @Override
     public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
@@ -233,8 +233,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
     protected abstract StoreMetadataNode applySubtreeChange(NodeModification modification,
             StoreMetadataNode currentMeta, UnsignedLong subtreeVersion);
 
-    public static abstract class ValueNodeModificationStrategy<T extends DataSchemaNode> extends
-            SchemaAwareApplyOperation {
+    public static abstract class ValueNodeModificationStrategy<T extends DataSchemaNode> extends SchemaAwareApplyOperation {
 
         private final T schema;
         private final Class<? extends NormalizedNode<?, ?>> nodeClass;
@@ -246,8 +245,8 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         }
 
         @Override
-        protected void verifyWritenStructure(final NormalizedNode<?, ?> writenValue) {
-            checkArgument(nodeClass.isInstance(writenValue), "Node should must be of type %s", nodeClass);
+        protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
+            checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass);
         }
 
         @Override
@@ -274,7 +273,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
                 final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
             UnsignedLong nodeVersion = subtreeVersion;
             return StoreMetadataNode.builder().setNodeVersion(nodeVersion).setSubtreeVersion(subtreeVersion)
-                    .setData(modification.getWritenValue()).build();
+                    .setData(modification.getWrittenValue()).build();
         }
 
         @Override
@@ -329,13 +328,20 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
 
         @SuppressWarnings("rawtypes")
         @Override
-        protected void verifyWritenStructure(final NormalizedNode<?, ?> writenValue) {
-            checkArgument(nodeClass.isInstance(writenValue), "Node should must be of type %s", nodeClass);
-            checkArgument(writenValue instanceof NormalizedNodeContainer);
-            NormalizedNodeContainer writenCont = (NormalizedNodeContainer) writenValue;
-            for (Object child : writenCont.getValue()) {
+        protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
+            checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass);
+            checkArgument(writtenValue instanceof NormalizedNodeContainer);
+
+            NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue;
+            for (Object child : container.getValue()) {
                 checkArgument(child instanceof NormalizedNode);
-                NormalizedNode childNode = (NormalizedNode) child;
+
+                /*
+                 * FIXME: fail-fast semantics:
+                 *
+                 * We can validate the data structure here, aborting the commit
+                 * before it ever progresses to being committed.
+                 */
             }
         }
 
@@ -343,7 +349,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         protected StoreMetadataNode applyWrite(final NodeModification modification,
                 final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
 
-            NormalizedNode<?, ?> newValue = modification.getWritenValue();
+            NormalizedNode<?, ?> newValue = modification.getWrittenValue();
 
             final UnsignedLong nodeVersion;
             if (currentMeta.isPresent()) {
@@ -436,8 +442,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode<?, ?> original);
     }
 
-    public static abstract class DataNodeContainerModificationStrategy<T extends DataNodeContainer> extends
-            NormalizedNodeContainerModificationStrategy {
+    public static abstract class DataNodeContainerModificationStrategy<T extends DataNodeContainer> extends NormalizedNodeContainerModificationStrategy {
 
         private final T schema;
         private final LoadingCache<PathArgument, ModificationApplyOperation> childCache = CacheBuilder.newBuilder()
@@ -487,8 +492,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
 
     }
 
-    public static class ContainerModificationStrategy extends
-            DataNodeContainerModificationStrategy<ContainerSchemaNode> {
+    public static class ContainerModificationStrategy extends DataNodeContainerModificationStrategy<ContainerSchemaNode> {
 
         public ContainerModificationStrategy(final ContainerSchemaNode schemaNode) {
             super(schemaNode, ContainerNode.class);
@@ -502,8 +506,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         }
     }
 
-    public static class UnkeyedListItemModificationStrategy extends
-            DataNodeContainerModificationStrategy<ListSchemaNode> {
+    public static class UnkeyedListItemModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
 
         public UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode) {
             super(schemaNode, UnkeyedListEntryNode.class);
@@ -517,8 +520,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         }
     }
 
-    public static class AugmentationModificationStrategy extends
-            DataNodeContainerModificationStrategy<AugmentationSchema> {
+    public static class AugmentationModificationStrategy extends DataNodeContainerModificationStrategy<AugmentationSchema> {
 
         protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) {
             super(createAugmentProxy(schema,resolved), AugmentationNode.class);
@@ -534,12 +536,10 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
 
     public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy {
 
-        private final ChoiceNode schema;
         private final Map<PathArgument, ModificationApplyOperation> childNodes;
 
         public ChoiceModificationStrategy(final ChoiceNode schemaNode) {
             super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class);
-            this.schema = schemaNode;
             ImmutableMap.Builder<PathArgument, ModificationApplyOperation> child = ImmutableMap.builder();
 
             for (ChoiceCaseNode caze : schemaNode.getCases()) {
@@ -653,7 +653,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         @Override
         protected StoreMetadataNode applyWrite(final NodeModification modification,
                 final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
-            return StoreMetadataNode.createRecursively(modification.getWritenValue(), subtreeVersion);
+            return StoreMetadataNode.createRecursively(modification.getWrittenValue(), subtreeVersion);
         }
 
         @Override
@@ -665,7 +665,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         }
 
         @Override
-        protected void verifyWritenStructure(final NormalizedNode<?, ?> writenValue) {
+        protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
 
         }
 
@@ -737,10 +737,6 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         }
     }
 
-    public void verifyIdentifier(final PathArgument identifier) {
-
-    }
-
     public static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) {
         Set<DataSchemaNode> realChildSchemas = new HashSet<>();
         for(DataSchemaNode augChild : schema.getChildNodes()) {
@@ -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.md.sal.dom.store.impl.tree;
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import static com.google.common.base.Preconditions.checkState;
 
@@ -13,6 +13,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
@@ -23,6 +24,7 @@ import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.primitives.UnsignedLong;
 
+// FIXME: this should not be public
 public class StoreMetadataNode implements Immutable, Identifiable<PathArgument>, StoreTreeNode<StoreMetadataNode> {
 
     private final UnsignedLong nodeVersion;
@@ -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.md.sal.dom.store.impl.tree;
+package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
@@ -20,7 +20,7 @@ import com.google.common.primitives.UnsignedLong;
  *
  */
 @SuppressWarnings("rawtypes")
-public class StoreNodeCompositeBuilder {
+class StoreNodeCompositeBuilder {
 
     private final StoreMetadataNode.Builder metadata;
 
index 9cbf428..357a516 100644 (file)
@@ -8,29 +8,22 @@
 package org.opendaylight.controller.sal.dom.broker
 
 import java.util.Hashtable
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService
 import org.opendaylight.controller.sal.core.api.data.DataProviderService
 import org.opendaylight.controller.sal.core.api.data.DataStore
 import org.opendaylight.controller.sal.core.api.model.SchemaService
-import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
 import org.opendaylight.controller.sal.core.api.mount.MountService
 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter
 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProviders
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener
 import org.osgi.framework.BundleContext
 import org.osgi.framework.ServiceRegistration
-import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProviders
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry
-import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker
-import org.opendaylight.controller.md.sal.dom.broker.impl.DOMDataBrokerImpl
-import com.google.common.util.concurrent.MoreExecutors
-import com.google.common.collect.ImmutableMap
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType
-import org.opendaylight.controller.sal.core.spi.data.DOMStore
-import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore
-import java.util.concurrent.Executors
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
 
 class BrokerConfigActivator implements AutoCloseable {
 
@@ -1,4 +1,11 @@
-package org.opendaylight.controller.md.sal.dom.store.impl;
+/*
+ * Copyright (c) 2014 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.md.sal.dom.store.impl.tree.data;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -19,7 +26,9 @@ import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.ma
 
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.TestModel;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
@@ -89,14 +98,16 @@ public class ModificationMetadataTreeTest {
                     .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_ONE_NAME)) //
                     .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_TWO_NAME)) //
                     .build()) //
-            .build();
+                    .build();
 
     private SchemaContext schemaContext;
+    private ModificationApplyOperation applyOper;
 
     @Before
     public void prepare() {
         schemaContext = TestModel.createTestContext();
         assertNotNull("Schema context must not be null.", schemaContext);
+        applyOper = SchemaAwareApplyOperation.from(schemaContext);
     }
 
     /**
@@ -131,16 +142,16 @@ public class ModificationMetadataTreeTest {
                 .withNodeIdentifier(new NodeIdentifier(TEST_QNAME))
                 .withChild(
                         mapNodeBuilder(OUTER_LIST_QNAME)
-                                .withChild(mapEntry(OUTER_LIST_QNAME, ID_QNAME, ONE_ID))
-                                .withChild(BAR_NODE).build()).build();
+                        .withChild(mapEntry(OUTER_LIST_QNAME, ID_QNAME, ONE_ID))
+                        .withChild(BAR_NODE).build()).build();
     }
 
     @Test
     public void basicReadWrites() {
-        MutableDataTree modificationTree = MutableDataTree.from(new DataTree.Snapshot(schemaContext,
-                StoreMetadataNode.createRecursively(createDocumentOne(), UnsignedLong.valueOf(5))),
+        DataTreeModification modificationTree = new InMemoryDataTreeModification(new InMemoryDataTreeSnapshot(schemaContext,
+                StoreMetadataNode.createRecursively(createDocumentOne(), UnsignedLong.valueOf(5)), applyOper),
                 new SchemaAwareApplyOperationRoot(schemaContext));
-        Optional<NormalizedNode<?, ?>> originalBarNode = modificationTree.read(OUTER_LIST_2_PATH);
+        Optional<NormalizedNode<?, ?>> originalBarNode = modificationTree.readNode(OUTER_LIST_2_PATH);
         assertTrue(originalBarNode.isPresent());
         assertSame(BAR_NODE, originalBarNode.get());
 
@@ -149,22 +160,23 @@ public class ModificationMetadataTreeTest {
 
         // reads node to /outer-list/1/inner_list/two/value
         // and checks if node is already present
-        Optional<NormalizedNode<?, ?>> barTwoCModified = modificationTree.read(TWO_TWO_VALUE_PATH);
+        Optional<NormalizedNode<?, ?>> barTwoCModified = modificationTree.readNode(TWO_TWO_VALUE_PATH);
         assertTrue(barTwoCModified.isPresent());
         assertEquals(ImmutableNodes.leafNode(VALUE_QNAME, "test"), barTwoCModified.get());
 
         // delete node to /outer-list/1/inner_list/two/value
         modificationTree.delete(TWO_TWO_VALUE_PATH);
-        Optional<NormalizedNode<?, ?>> barTwoCAfterDelete = modificationTree.read(TWO_TWO_VALUE_PATH);
+        Optional<NormalizedNode<?, ?>> barTwoCAfterDelete = modificationTree.readNode(TWO_TWO_VALUE_PATH);
         assertFalse(barTwoCAfterDelete.isPresent());
     }
 
 
-    public MutableDataTree createEmptyModificationTree() {
+    public DataTreeModification createEmptyModificationTree() {
         /**
          * Creates empty Snapshot with associated schema context.
          */
-        DataTree t = DataTree.create(schemaContext);
+        DataTree t = InMemoryDataTreeFactory.getInstance().create();
+        t.setSchemaContext(schemaContext);
 
         /**
          *
@@ -172,15 +184,13 @@ public class ModificationMetadataTreeTest {
          * context.
          *
          */
-        MutableDataTree modificationTree = MutableDataTree.from(t.takeSnapshot(), new SchemaAwareApplyOperationRoot(
-                schemaContext));
-        return modificationTree;
+        return t.takeSnapshot().newModification();
     }
 
     @Test
     public void createFromEmptyState() {
 
-        MutableDataTree modificationTree = createEmptyModificationTree();
+        DataTreeModification modificationTree = createEmptyModificationTree();
         /**
          * Writes empty container node to /test
          *
@@ -195,14 +205,14 @@ public class ModificationMetadataTreeTest {
         /**
          * Reads list node from /test/outer-list
          */
-        Optional<NormalizedNode<?, ?>> potentialOuterList = modificationTree.read(OUTER_LIST_PATH);
+        Optional<NormalizedNode<?, ?>> potentialOuterList = modificationTree.readNode(OUTER_LIST_PATH);
         assertTrue(potentialOuterList.isPresent());
 
         /**
          * Reads container node from /test and verifies that it contains test
          * node
          */
-        Optional<NormalizedNode<?, ?>> potentialTest = modificationTree.read(TEST_PATH);
+        Optional<NormalizedNode<?, ?>> potentialTest = modificationTree.readNode(TEST_PATH);
         ContainerNode containerTest = assertPresentAndType(potentialTest, ContainerNode.class);
 
         /**
@@ -217,23 +227,23 @@ public class ModificationMetadataTreeTest {
 
     @Test
     public void writeSubtreeReadChildren() {
-        MutableDataTree modificationTree = createEmptyModificationTree();
+        DataTreeModification modificationTree = createEmptyModificationTree();
         modificationTree.write(TEST_PATH, createTestContainer());
-        Optional<NormalizedNode<?, ?>> potential = modificationTree.read(TWO_TWO_PATH);
-        MapEntryNode node = assertPresentAndType(potential, MapEntryNode.class);
+        Optional<NormalizedNode<?, ?>> potential = modificationTree.readNode(TWO_TWO_PATH);
+        assertPresentAndType(potential, MapEntryNode.class);
     }
 
     @Test
     public void writeSubtreeDeleteChildren() {
-        MutableDataTree modificationTree = createEmptyModificationTree();
+        DataTreeModification modificationTree = createEmptyModificationTree();
         modificationTree.write(TEST_PATH, createTestContainer());
 
         // We verify data are present
-        Optional<NormalizedNode<?, ?>> potentialBeforeDelete = modificationTree.read(TWO_TWO_PATH);
-        MapEntryNode node = assertPresentAndType(potentialBeforeDelete, MapEntryNode.class);
+        Optional<NormalizedNode<?, ?>> potentialBeforeDelete = modificationTree.readNode(TWO_TWO_PATH);
+        assertPresentAndType(potentialBeforeDelete, MapEntryNode.class);
 
         modificationTree.delete(TWO_TWO_PATH);
-        Optional<NormalizedNode<?, ?>> potentialAfterDelete = modificationTree.read(TWO_TWO_PATH);
+        Optional<NormalizedNode<?, ?>> potentialAfterDelete = modificationTree.readNode(TWO_TWO_PATH);
         assertFalse(potentialAfterDelete.isPresent());
 
     }
index 89274c9..1839de1 100644 (file)
@@ -17,8 +17,10 @@ import java.io.File;
 import java.io.InputStream;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.URI;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
@@ -27,8 +29,10 @@ import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClient
 import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.connect.netconf.InventoryUtils;
 import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
 import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceListener;
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
 import org.opendaylight.protocol.framework.ReconnectStrategy;
 import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
 import org.opendaylight.protocol.framework.TimedReconnectStrategy;
@@ -36,6 +40,8 @@ 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.netconf.node.inventory.rev140108.NetconfNode;
 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.model.util.repo.AbstractCachingSchemaSourceProvider;
 import org.opendaylight.yangtools.yang.model.util.repo.FilesystemSchemaCachingProvider;
 import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
index 8f95e73..e721084 100644 (file)
@@ -180,10 +180,10 @@ public class ClientImpl implements RemoteRpcClient {
    * @param  routeId route identifier
    * @return         remote network address
    */
-  private String lookupRemoteAddressForGlobalRpc(RpcRouter.RouteIdentifier routeId){
+  private String lookupRemoteAddressForGlobalRpc(RpcRouter.RouteIdentifier<?, ?, ?> routeId){
     checkNotNull(routeId, "route must not be null");
 
-    Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> routingTable = routingTableProvider.getRoutingTable();
+    Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> routingTable = routingTableProvider.getRoutingTable();
     checkNotNull(routingTable.isPresent(), "Routing table is null");
 
     String address = null;
@@ -202,10 +202,10 @@ public class ClientImpl implements RemoteRpcClient {
    * @param  routeId route identifier
    * @return         remote network address
    */
-  private String lookupRemoteAddressForRpc(RpcRouter.RouteIdentifier routeId){
+  private String lookupRemoteAddressForRpc(RpcRouter.RouteIdentifier<?, ?, ?> routeId){
     checkNotNull(routeId, "route must not be null");
 
-    Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> routingTable = routingTableProvider.getRoutingTable();
+    Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> routingTable = routingTableProvider.getRoutingTable();
     checkNotNull(routingTable.isPresent(), "Routing table is null");
 
     String address = routingTable.get().getLastAddedRoute(routeId);
@@ -230,7 +230,7 @@ public class ClientImpl implements RemoteRpcClient {
    */
   private void closeZmqContext() {
     ExecutorService exec = Executors.newSingleThreadExecutor();
-    FutureTask zmqTermination = new FutureTask(new Runnable() {
+    FutureTask<?> zmqTermination = new FutureTask<Void>(new Runnable() {
 
       @Override
       public void run() {
index 9e66c20..37bff7b 100644 (file)
@@ -7,19 +7,19 @@
 
 package org.opendaylight.controller.sal.connector.remoterpc;
 
-import org.zeromq.ZMQ;
-
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.Enumeration;
 
+import org.zeromq.ZMQ;
+
 /**
  * Provides a ZeroMQ Context object
  */
 public class Context {
-  private ZMQ.Context zmqContext = ZMQ.context(1);
+  private final ZMQ.Context zmqContext = ZMQ.context(1);
   private String uri;
   private final String DEFAULT_RPC_PORT = "5554";
 
@@ -69,7 +69,7 @@ public class Context {
    */
   private String findIpAddress() {
     String hostAddress = null;
-    Enumeration e = null;
+    Enumeration<?> e = null;
     try {
       e = NetworkInterface.getNetworkInterfaces();
     } catch (SocketException e1) {
@@ -79,7 +79,7 @@ public class Context {
 
       NetworkInterface n = (NetworkInterface) e.nextElement();
 
-      Enumeration ee = n.getInetAddresses();
+      Enumeration<?> ee = n.getInetAddresses();
       while (ee.hasMoreElements()) {
         InetAddress i = (InetAddress) ee.nextElement();
         if ((i instanceof Inet4Address) && (i.isSiteLocalAddress()))
index a564a0a..94e3232 100644 (file)
@@ -8,14 +8,11 @@
 
 package org.opendaylight.controller.sal.connector.remoterpc;
 
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation;
-
 public interface RemoteRpcClient extends AutoCloseable{
 
     void setRoutingTableProvider(RoutingTableProvider provider);
-    
+
     void stop();
-    
+
     void start();
 }
index 53fbb92..76df256 100644 (file)
@@ -58,7 +58,7 @@ public class RemoteRpcProvider implements
   private ProviderSession brokerSession;
   private RpcProvisionRegistry rpcProvisionRegistry;
   private BundleContext context;
-  private ServiceTracker clusterTracker;
+  private ServiceTracker<?, ?> clusterTracker;
 
   public RemoteRpcProvider(ServerImpl server, ClientImpl client) {
     this.server = server;
@@ -170,8 +170,8 @@ public class RemoteRpcProvider implements
 
   }
 
-  private RoutingTable<RpcRouter.RouteIdentifier, String> getRoutingTable(){
-    Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> routingTable =
+  private RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> getRoutingTable(){
+    Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> routingTable =
         routingTableProvider.getRoutingTable();
 
     checkState(routingTable.isPresent(), "Routing table is null");
@@ -191,7 +191,7 @@ public class RemoteRpcProvider implements
       RouteIdentifierImpl routeId = new RouteIdentifierImpl();
       routeId.setType(rpc);
 
-      RoutingTable<RpcRouter.RouteIdentifier, String> routingTable = getRoutingTable();
+      RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable = getRoutingTable();
 
       try {
         routingTable.addGlobalRoute(routeId, server.getServerAddress());
@@ -212,7 +212,7 @@ public class RemoteRpcProvider implements
       RouteIdentifierImpl routeId = new RouteIdentifierImpl();
       routeId.setType(rpc);
 
-      RoutingTable<RpcRouter.RouteIdentifier, String> routingTable = getRoutingTable();
+      RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable = getRoutingTable();
 
       try {
         routingTable.removeGlobalRoute(routeId);
@@ -245,9 +245,9 @@ public class RemoteRpcProvider implements
      *
      * @param announcements
      */
-    private void announce(Set<RpcRouter.RouteIdentifier> announcements) {
+    private void announce(Set<RpcRouter.RouteIdentifier<?, ?, ?>> announcements) {
       _logger.debug("Announcing [{}]", announcements);
-      RoutingTable<RpcRouter.RouteIdentifier, String> routingTable = getRoutingTable();
+      RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable = getRoutingTable();
       try {
         routingTable.addRoutes(announcements, server.getServerAddress());
       } catch (RoutingTableException | SystemException e) {
@@ -259,9 +259,9 @@ public class RemoteRpcProvider implements
      *
      * @param removals
      */
-    private void remove(Set<RpcRouter.RouteIdentifier> removals){
+    private void remove(Set<RpcRouter.RouteIdentifier<?, ?, ?>> removals){
       _logger.debug("Removing [{}]", removals);
-      RoutingTable<RpcRouter.RouteIdentifier, String> routingTable = getRoutingTable();
+      RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable = getRoutingTable();
       try {
         routingTable.removeRoutes(removals, server.getServerAddress());
       } catch (RoutingTableException | SystemException e) {
@@ -274,9 +274,9 @@ public class RemoteRpcProvider implements
      * @param changes
      * @return
      */
-    private Set<RpcRouter.RouteIdentifier> getRouteIdentifiers(Map<RpcRoutingContext, Set<InstanceIdentifier>> changes) {
+    private Set<RpcRouter.RouteIdentifier<?, ?, ?>> getRouteIdentifiers(Map<RpcRoutingContext, Set<InstanceIdentifier>> changes) {
       RouteIdentifierImpl routeId = null;
-      Set<RpcRouter.RouteIdentifier> routeIdSet = new HashSet<RpcRouter.RouteIdentifier>();
+      Set<RpcRouter.RouteIdentifier<?, ?, ?>> routeIdSet = new HashSet<>();
 
       for (RpcRoutingContext context : changes.keySet()){
         routeId = new RouteIdentifierImpl();
index 71bab28..d960303 100644 (file)
@@ -8,25 +8,24 @@
 
 package org.opendaylight.controller.sal.connector.remoterpc;
 
-import com.google.common.base.Optional;
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
 import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
 import org.opendaylight.controller.sal.connector.remoterpc.impl.RoutingTableImpl;
 import org.osgi.framework.BundleContext;
 import org.osgi.util.tracker.ServiceTracker;
 
+import com.google.common.base.Optional;
+
 public class RoutingTableProvider implements AutoCloseable {
 
     @SuppressWarnings("rawtypes")
     final ServiceTracker<RoutingTable,RoutingTable> tracker;
 
-    private RoutingTableImpl routingTableImpl = null;
+    private RoutingTableImpl<?, ?> routingTableImpl = null;
 
     //final private RouteChangeListener routeChangeListener;
-    
-    
+
+
     public RoutingTableProvider(BundleContext ctx){//,RouteChangeListener rcl) {
         @SuppressWarnings("rawtypes")
         ServiceTracker<RoutingTable, RoutingTable> rawTracker = new ServiceTracker<>(ctx, RoutingTable.class, null);
@@ -35,14 +34,14 @@ public class RoutingTableProvider implements AutoCloseable {
 
         //routeChangeListener = rcl;
     }
-    
-    public Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> getRoutingTable() {
+
+    public Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> getRoutingTable() {
         @SuppressWarnings("unchecked")
-        RoutingTable<RpcRouter.RouteIdentifier,String> tracked = tracker.getService();
+        RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> tracked = tracker.getService();
 
         if(tracked instanceof RoutingTableImpl){
             if(routingTableImpl != tracked){
-             routingTableImpl= (RoutingTableImpl)tracked;
+             routingTableImpl= (RoutingTableImpl<?, ?>)tracked;
              //routingTableImpl.setRouteChangeListener(routeChangeListener);
             }
         }
index d256b99..3acea35 100644 (file)
@@ -7,48 +7,33 @@
  */
 package org.opendaylight.controller.sal.connector.remoterpc;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Sets;
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
-import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
-import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.Enumeration;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 
 /**
  * ZeroMq based implementation of RpcRouter.
  */
 public class ServerImpl implements RemoteRpcServer {
 
-  private Logger _logger = LoggerFactory.getLogger(ServerImpl.class);
+  private final Logger _logger = LoggerFactory.getLogger(ServerImpl.class);
 
   private ExecutorService serverPool;
   protected ServerRequestHandler handler;
@@ -63,7 +48,7 @@ public class ServerImpl implements RemoteRpcServer {
   private volatile State status = State.STOPPED;
 
   private String serverAddress;
-  private int port;
+  private final int port;
 
   public static enum State {
     STARTING, STARTED, STOPPED;
@@ -167,7 +152,7 @@ public class ServerImpl implements RemoteRpcServer {
    */
   private void closeZmqContext() {
     ExecutorService exec = Executors.newSingleThreadExecutor();
-    FutureTask zmqTermination = new FutureTask(new Runnable() {
+    FutureTask<?> zmqTermination = new FutureTask<Void>(new Runnable() {
 
       @Override
       public void run() {
@@ -249,7 +234,7 @@ public class ServerImpl implements RemoteRpcServer {
    * @return
    */
   private String findIpAddress() {
-    Enumeration e = null;
+    Enumeration<?> e = null;
     try {
       e = NetworkInterface.getNetworkInterfaces();
     } catch (SocketException e1) {
@@ -260,7 +245,7 @@ public class ServerImpl implements RemoteRpcServer {
 
       NetworkInterface n = (NetworkInterface) e.nextElement();
 
-      Enumeration ee = n.getInetAddresses();
+      Enumeration<?> ee = n.getInetAddresses();
       while (ee.hasMoreElements()) {
         InetAddress i = (InetAddress) ee.nextElement();
         _logger.debug("Trying address {}", i);
index 2041f03..a25387d 100644 (file)
@@ -8,38 +8,39 @@
 
 package org.opendaylight.controller.sal.connector.remoterpc;
 
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
 import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
 import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.zeromq.ZMQ;
 
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Collection;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicInteger;
-
 /**
  *
  */
 public class ServerRequestHandler implements AutoCloseable{
 
-  private Logger _logger = LoggerFactory.getLogger(ServerRequestHandler.class);
+  private final Logger _logger = LoggerFactory.getLogger(ServerRequestHandler.class);
   private final String DEFAULT_NAME = "remote-rpc-worker";
-  private String dealerAddress;
-  private String serverAddress;
-  private int workerCount;
-  private ZMQ.Context context;
-  private Broker.ProviderSession broker;
+  private final String dealerAddress;
+  private final String serverAddress;
+  private final int workerCount;
+  private final ZMQ.Context context;
+  private final Broker.ProviderSession broker;
 
   private RequestHandlerThreadPool workerPool;
   private final AtomicInteger threadId = new AtomicInteger();
@@ -87,7 +88,7 @@ public class ServerRequestHandler implements AutoCloseable{
    * Worker to handles RPC request
    */
   private class Worker implements Runnable {
-    private String name;
+    private final String name;
 
     public Worker(int id){
       this.name = DEFAULT_NAME + "-" + id;
@@ -187,7 +188,7 @@ public class ServerRequestHandler implements AutoCloseable{
   }
 
   class MessageHandler{
-    private ZMQ.Socket socket;
+    private final ZMQ.Socket socket;
     private Message message;          //parsed message received on zmq server port
     private boolean messageForBroker = false; //if the message is valid and not a "ping" message
 
@@ -236,7 +237,7 @@ public class ServerRequestHandler implements AutoCloseable{
       CompositeNode payload = (result != null) ? result.getResult() : null;
 
       String recipient = null;
-      RpcRouter.RouteIdentifier routeId = null;
+      RpcRouter.RouteIdentifier<?, ?, ?> routeId = null;
 
       if (message != null) {
         recipient = message.getSender();
index 21d02be..cbcfe3e 100644 (file)
@@ -41,7 +41,7 @@ public class Message implements Serializable {
   private MessageType type;
   private String sender;
   private String recipient;
-  private RpcRouter.RouteIdentifier route;
+  private RpcRouter.RouteIdentifier<?, ?, ?> route;
   private Object payload;
 
   public MessageType getType() {
@@ -60,11 +60,11 @@ public class Message implements Serializable {
     this.sender = sender;
   }
 
-  public RpcRouter.RouteIdentifier getRoute() {
+  public RpcRouter.RouteIdentifier<?, ?, ?> getRoute() {
     return route;
   }
 
-  public void setRoute(RpcRouter.RouteIdentifier route) {
+  public void setRoute(RpcRouter.RouteIdentifier<?, ?, ?> route) {
     this.route = route;
   }
 
@@ -123,7 +123,7 @@ public class Message implements Serializable {
     return o.readObject();
   }
 
-  public static class Response extends Message implements RpcRouter.RpcReply {
+  public static class Response extends Message implements RpcRouter.RpcReply<Object> {
     private static final long serialVersionUID = 1L;
     private ResponseCode code; // response code
 
@@ -173,7 +173,7 @@ public class Message implements Serializable {
       return this;
     }
 
-    public MessageBuilder route(RpcRouter.RouteIdentifier route){
+    public MessageBuilder route(RpcRouter.RouteIdentifier<?, ?, ?> route){
       message.setRoute(route);
       return this;
     }
index 0fa12e3..f8d14ce 100644 (file)
@@ -40,8 +40,8 @@ public class ClientImplTest {
 
     //mock routing table
     routingTableProvider = mock(RoutingTableProvider.class);
-    RoutingTable<RpcRouter.RouteIdentifier, String> mockRoutingTable = new MockRoutingTable<String, String>();
-    Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
+    RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> mockRoutingTable = new MockRoutingTable<String, String>();
+    Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
     when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable);
 
     //mock ClientRequestHandler
index 1edd004..0918868 100644 (file)
@@ -99,7 +99,7 @@ public class ClientRequestHandlerTest {
   private Message handleMessageWithTimeout(final Message request) {
     Message response = null;
 
-    FutureTask task = new FutureTask(new Callable<Message>() {
+    FutureTask<?> task = new FutureTask<Message>(new Callable<Message>() {
 
       @Override
       public Message call() {
index 0fe0155..179051e 100644 (file)
@@ -7,16 +7,13 @@
  */
 package org.opendaylight.controller.sal.connector.remoterpc;
 
-import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
+import java.util.HashSet;
+import java.util.Set;
+
 import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
 import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
 import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
 
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * Mock implementation of routing table
  */
@@ -59,7 +56,7 @@ public class MockRoutingTable<K, V> implements RoutingTable {
   }
 
   @Override
-  public Set getRoutes(Object o) {
+  public Set<String> getRoutes(Object o) {
     Set<String> routes = new HashSet<String>();
     routes.add("localhost:5554");
     return routes;
index 886ff42..7ffdf17 100644 (file)
@@ -8,28 +8,34 @@
 package org.opendaylight.controller.sal.connector.remoterpc;
 
 
-import com.google.common.base.Optional;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadPoolExecutor;
+
 import junit.framework.Assert;
-import org.junit.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
 import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
 import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.zeromq.ZMQ;
+
 import zmq.Ctx;
 import zmq.SocketBase;
 
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ThreadPoolExecutor;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import com.google.common.base.Optional;
 
 public class ServerImplTest {
 
@@ -68,12 +74,12 @@ public class ServerImplTest {
     server = new ServerImpl(port);
     server.setBrokerSession(brokerSession);
 
-    RoutingTable<RpcRouter.RouteIdentifier, String> mockRoutingTable = new MockRoutingTable<String, String>();
-    Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
+    RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> mockRoutingTable = new MockRoutingTable<String, String>();
+    Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
     when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable);
 
     when(brokerSession.addRpcRegistrationListener(listener)).thenReturn(null);
-    when(brokerSession.getSupportedRpcs()).thenReturn(Collections.EMPTY_SET);
+    when(brokerSession.getSupportedRpcs()).thenReturn(Collections.<QName>emptySet());
     when(brokerSession.rpc(null, mock(CompositeNode.class))).thenReturn(null);
     server.start();
     Thread.sleep(5000);//wait for server to start
@@ -178,7 +184,7 @@ public class ServerImplTest {
     Thread[] threads = new Thread[Thread.activeCount()];
     Thread.enumerate(threads);
 
-    List<Thread> foundThreads = new ArrayList();
+    List<Thread> foundThreads = new ArrayList<Thread>();
     for (Thread t : threads) {
       if (t.getName().startsWith(name))
         foundThreads.add(t);
index 6e39867..e5fbc76 100644 (file)
@@ -7,7 +7,15 @@
 
 package org.opendaylight.controller.sal.connector.remoterpc;
 
+import static org.mockito.Mockito.mock;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
 import junit.framework.Assert;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -15,22 +23,15 @@ import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.zeromq.ZMQ;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import static org.mockito.Mockito.mock;
-
 public class ServerRequestHandlerTest {
 
   ServerRequestHandler handler;
   ZMQ.Context context;
   ExecutorService executorService = Executors.newCachedThreadPool();
-  private int workerCount = 2;
-  private String mockDealerAddress = "inproc://rpc-request-handler";
-  private String mockServerIp = "localhost";
-  private int mockServerPort = 5554;
+  private final int workerCount = 2;
+  private final String mockDealerAddress = "inproc://rpc-request-handler";
+  private final String mockServerIp = "localhost";
+  private final int mockServerPort = 5554;
 
   @Before
   public void setUp() throws Exception {
@@ -98,7 +99,7 @@ public class ServerRequestHandlerTest {
     Thread[] threads = new Thread[Thread.activeCount()];
     Thread.enumerate(threads);
 
-    List<Thread> foundThreads = new ArrayList();
+    List<Thread> foundThreads = new ArrayList<Thread>();
     for (Thread t : threads) {
       if (t.getName().startsWith(name))
         foundThreads.add(t);
index a68ee57..883aa52 100644 (file)
@@ -7,12 +7,6 @@
 
 package org.opendaylight.controller.sal.connector.remoterpc.utils;
 
-import junit.framework.Assert;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -21,6 +15,13 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
 
+import junit.framework.Assert;
+
+import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
 public class MessagingUtil {
 
   private static final Logger _logger = LoggerFactory.getLogger(MessagingUtil.class);
@@ -160,7 +161,7 @@ public class MessagingUtil {
     if (context == null) return;
 
     ExecutorService exec = Executors.newSingleThreadExecutor();
-    FutureTask zmqTermination = new FutureTask(new Runnable() {
+    FutureTask<?> zmqTermination = new FutureTask<Void>(new Runnable() {
 
       @Override
       public void run() {
index a71ab86..7a4f4a5 100644 (file)
@@ -1,14 +1,14 @@
 package org.opendaylight.controller.sal.connector.remoterpc.utils;
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
 import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
 import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.zeromq.ZMQ;
 
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
 public class RemoteServerTestClient {
 
 
@@ -39,7 +39,7 @@ public class RemoteServerTestClient {
   }
   public Message createAddFlowMessage(String serverAddress ){
 
-    RpcRouter.RouteIdentifier routeIdentifier = getAddFlowRpcIdentifier();
+    RpcRouter.RouteIdentifier<?, ?, ?> routeIdentifier = getAddFlowRpcIdentifier();
 
     Message addFlow = new Message.MessageBuilder()
         .type(Message.MessageType.REQUEST)
@@ -52,7 +52,7 @@ public class RemoteServerTestClient {
     return addFlow;
   }
 
-  private RpcRouter.RouteIdentifier getAddFlowRpcIdentifier(){
+  private RpcRouter.RouteIdentifier<?, ?, ?> getAddFlowRpcIdentifier(){
     throw new UnsupportedOperationException();
   }