Switch to using protocol buffer serialization for the WriteData message 28/8828/7
authorMoiz Raja <moraja@cisco.com>
Tue, 8 Jul 2014 21:57:48 +0000 (14:57 -0700)
committerMoiz Raja <moraja@cisco.com>
Mon, 28 Jul 2014 20:56:31 +0000 (13:56 -0700)
- This commit also fixes an issues with the NodeToNormalizedNodeBuilder where an empty container node was decode with a leaf node within
- MergeData and WriteData are passed in their serialized forms from the TransactionProxy as well

Change-Id: I22eab6059becd427a9f0fae1a9273c8c4e293ee5
Signed-off-by: Moiz Raja <moraja@cisco.com>
13 files changed:
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransactionChain.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionProxy.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DeleteData.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/MergeData.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/WriteData.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/BasicIntegrationTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionChainTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionProxyTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/MergeDataTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeToNormalizedNodeBuilder.java

index a3437e2..71e881c 100644 (file)
@@ -37,6 +37,7 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCoh
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
 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 java.util.HashMap;
 import java.util.Map;
@@ -68,6 +69,8 @@ public class Shard extends UntypedProcessor {
     // property persistent
     private final boolean persistent;
 
+    private SchemaContext schemaContext;
+
     private Shard(String name) {
 
         String setting = System.getProperty("shard.persistent");
@@ -115,7 +118,7 @@ public class Shard extends UntypedProcessor {
         DOMStoreReadWriteTransaction transaction =
             store.newReadWriteTransaction();
         ActorRef transactionActor = getContext().actorOf(
-            ShardTransaction.props(transaction, getSelf()), "shard-" + createTransaction.getTransactionId());
+            ShardTransaction.props(transaction, getSelf(), schemaContext), "shard-" + createTransaction.getTransactionId());
         getSender()
             .tell(new CreateTransactionReply(transactionActor.path().toString(), createTransaction.getTransactionId()).toSerializable(),
                 getSelf());
@@ -159,6 +162,7 @@ public class Shard extends UntypedProcessor {
     }
 
     private void updateSchemaContext(UpdateSchemaContext message) {
+        this.schemaContext = message.getSchemaContext();
         store.onGlobalContextUpdated(message.getSchemaContext());
     }
 
@@ -186,7 +190,7 @@ public class Shard extends UntypedProcessor {
     private void createTransactionChain() {
         DOMStoreTransactionChain chain = store.createTransactionChain();
         ActorRef transactionChain =
-            getContext().actorOf(ShardTransactionChain.props(chain));
+            getContext().actorOf(ShardTransactionChain.props(chain, schemaContext));
         getSender()
             .tell(new CreateTransactionChainReply(transactionChain.path()),
                 getSelf());
index e2b5601..33e1369 100644 (file)
@@ -39,6 +39,7 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCoh
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
 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 java.util.concurrent.ExecutionException;
 
@@ -67,6 +68,7 @@ import java.util.concurrent.ExecutionException;
 public class ShardTransaction extends AbstractUntypedActor {
 
     private final ActorRef shardActor;
+    private final SchemaContext schemaContext;
 
     // FIXME : see below
     // If transactionChain is not null then this transaction is part of a
@@ -82,37 +84,38 @@ public class ShardTransaction extends AbstractUntypedActor {
         Logging.getLogger(getContext().system(), this);
 
     public ShardTransaction(DOMStoreReadWriteTransaction transaction,
-        ActorRef shardActor) {
-        this(null, transaction, shardActor);
+        ActorRef shardActor, SchemaContext schemaContext) {
+        this(null, transaction, shardActor, schemaContext);
     }
 
     public ShardTransaction(DOMStoreTransactionChain transactionChain, DOMStoreReadWriteTransaction transaction,
-        ActorRef shardActor) {
+        ActorRef shardActor, SchemaContext schemaContext) {
         this.transactionChain = transactionChain;
         this.transaction = transaction;
         this.shardActor = shardActor;
+        this.schemaContext = schemaContext;
     }
 
 
 
     public static Props props(final DOMStoreReadWriteTransaction transaction,
-        final ActorRef shardActor) {
+        final ActorRef shardActor, final SchemaContext schemaContext) {
         return Props.create(new Creator<ShardTransaction>() {
 
             @Override
             public ShardTransaction create() throws Exception {
-                return new ShardTransaction(transaction, shardActor);
+                return new ShardTransaction(transaction, shardActor, schemaContext);
             }
         });
     }
 
     public static Props props(final DOMStoreTransactionChain transactionChain, final DOMStoreReadWriteTransaction transaction,
-        final ActorRef shardActor) {
+        final ActorRef shardActor, final SchemaContext schemaContext) {
         return Props.create(new Creator<ShardTransaction>() {
 
             @Override
             public ShardTransaction create() throws Exception {
-                return new ShardTransaction(transactionChain, transaction, shardActor);
+                return new ShardTransaction(transactionChain, transaction, shardActor, schemaContext);
             }
         });
     }
@@ -122,10 +125,10 @@ public class ShardTransaction extends AbstractUntypedActor {
     public void handleReceive(Object message) throws Exception {
         if (message instanceof ReadData) {
             readData((ReadData) message);
-        } else if (message instanceof WriteData) {
-            writeData((WriteData) message);
-        } else if (message instanceof MergeData) {
-            mergeData((MergeData) message);
+        } else if (WriteData.SERIALIZABLE_CLASS.equals(message.getClass())) {
+            writeData(WriteData.fromSerializable(message, schemaContext));
+        } else if (MergeData.SERIALIZABLE_CLASS.equals(message.getClass())) {
+            mergeData(MergeData.fromSerializable(message, schemaContext));
         } else if (DeleteData.SERIALIZABLE_CLASS.equals(message.getClass())) {
             deleteData(DeleteData.fromSerizalizable(message));
         } else if (message instanceof ReadyTransaction) {
index f76dc40..2991a77 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction;
 import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 /**
  * The ShardTransactionChain Actor represents a remote TransactionChain
@@ -24,9 +25,11 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
 public class ShardTransactionChain extends AbstractUntypedActor {
 
     private final DOMStoreTransactionChain chain;
+    private final SchemaContext schemaContext;
 
-    public ShardTransactionChain(DOMStoreTransactionChain chain) {
+    public ShardTransactionChain(DOMStoreTransactionChain chain, SchemaContext schemaContext) {
         this.chain = chain;
+        this.schemaContext = schemaContext;
     }
 
     @Override
@@ -44,7 +47,7 @@ public class ShardTransactionChain extends AbstractUntypedActor {
         DOMStoreReadWriteTransaction transaction =
             chain.newReadWriteTransaction();
         ActorRef transactionActor = getContext().actorOf(ShardTransaction
-            .props(chain, transaction, getContext().parent()), "shard-" + createTransaction.getTransactionId());
+            .props(chain, transaction, getContext().parent(), schemaContext), "shard-" + createTransaction.getTransactionId());
         getSender()
             .tell(ShardTransactionMessages.CreateTransactionReply.newBuilder()
                 .setTransactionActorPath(transactionActor.path().toString())
@@ -53,12 +56,12 @@ public class ShardTransactionChain extends AbstractUntypedActor {
                 getSelf());
     }
 
-    public static Props props(final DOMStoreTransactionChain chain) {
+    public static Props props(final DOMStoreTransactionChain chain, final SchemaContext schemaContext) {
         return Props.create(new Creator<ShardTransactionChain>() {
 
             @Override
             public ShardTransactionChain create() throws Exception {
-                return new ShardTransactionChain(chain);
+                return new ShardTransactionChain(chain, schemaContext);
             }
         });
     }
index 9a77d13..aefe357 100644 (file)
@@ -120,13 +120,13 @@ public class TransactionProxy implements DOMStoreReadWriteTransaction {
     @Override
     public void write(InstanceIdentifier path, NormalizedNode<?, ?> data) {
         final ActorSelection remoteTransaction = remoteTransactionFromIdentifier(path);
-        remoteTransaction.tell(new WriteData(path, data, schemaContext), null);
+        remoteTransaction.tell(new WriteData(path, data, schemaContext).toSerializable(), null);
     }
 
     @Override
     public void merge(InstanceIdentifier path, NormalizedNode<?, ?> data) {
         final ActorSelection remoteTransaction = remoteTransactionFromIdentifier(path);
-        remoteTransaction.tell(new MergeData(path, data, schemaContext), null);
+        remoteTransaction.tell(new MergeData(path, data, schemaContext).toSerializable(), null);
     }
 
     @Override
index 7f9a9fb..babe1c6 100644 (file)
@@ -28,8 +28,7 @@ public class DeleteData implements SerializableMessage {
 
     @Override public Object toSerializable() {
         return ShardTransactionMessages.DeleteData.newBuilder()
-            .setInstanceIdentifierPathArguments(
-                InstanceIdentifierUtils.getParentPath(path.toString())).build();
+            .setInstanceIdentifierPathArguments(path.toString()).build();
     }
 
     public static DeleteData fromSerizalizable(Object serializable){
index 5ab7741..59f1387 100644 (file)
@@ -10,21 +10,29 @@ package org.opendaylight.controller.cluster.datastore.messages;
 
 import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
 import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
 import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
 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;
 
 public class MergeData extends ModifyData{
+
+    public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.MergeData.class;
+
     public MergeData(InstanceIdentifier path, NormalizedNode<?, ?> data,
         SchemaContext context) {
         super(path, data, context);
     }
 
     @Override public Object toSerializable() {
+
+        NormalizedNodeMessages.Node normalizedNode =
+            new NormalizedNodeToNodeCodec(schemaContext).encode(InstanceIdentifierUtils.from(path.toString()), data)
+                .getNormalizedNode();
         return ShardTransactionMessages.MergeData.newBuilder()
-            .setInstanceIdentifierPathArguments(InstanceIdentifierUtils.getParentPath(path.toString()))
-            .setNormalizedNode(new NormalizedNodeToNodeCodec(schemaContext).encode(path, data).getNormalizedNode()).build();
+            .setInstanceIdentifierPathArguments(path.toString())
+            .setNormalizedNode(normalizedNode).build();
     }
 
     public static MergeData fromSerializable(Object serializable, SchemaContext schemaContext){
index 913da06..3cde958 100644 (file)
@@ -8,17 +8,43 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
 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;
 
 public class WriteData extends ModifyData{
 
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.WriteData.class;
+
   public WriteData(InstanceIdentifier path, NormalizedNode<?, ?> data, SchemaContext schemaContext) {
     super(path, data, schemaContext);
   }
 
     @Override public Object toSerializable() {
-        throw new UnsupportedOperationException("toSerializable");
+
+        NormalizedNodeMessages.Node normalizedNode =
+            new NormalizedNodeToNodeCodec(schemaContext).encode(
+                InstanceIdentifierUtils.from(path.toString()), data)
+                .getNormalizedNode();
+        return ShardTransactionMessages.WriteData.newBuilder()
+            .setInstanceIdentifierPathArguments(path.toString())
+            .setNormalizedNode(normalizedNode).build();
+
+    }
+
+    public static WriteData fromSerializable(Object serializable, SchemaContext schemaContext){
+        ShardTransactionMessages.WriteData o = (ShardTransactionMessages.WriteData) serializable;
+        InstanceIdentifier identifier = InstanceIdentifierUtils.from(o.getInstanceIdentifierPathArguments());
+
+        NormalizedNode<?, ?> normalizedNode =
+            new NormalizedNodeToNodeCodec(schemaContext)
+                .decode(identifier, o.getNormalizedNode());
+
+        return new WriteData(identifier, normalizedNode, schemaContext);
     }
+
 }
index 6bef691..e275bc5 100644 (file)
@@ -99,7 +99,7 @@ public class BasicIntegrationTest extends AbstractActorTest {
                     final ActorRef transactionActorRef = watchActor(transaction);
 
                     transaction.tell(new WriteData(TestModel.TEST_PATH,
-                        ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()),
+                        ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
                         getRef());
 
                     Boolean writeDone = new ExpectMsg<Boolean>("WriteDataReply") {
index 8bdc38a..1e68179 100644 (file)
@@ -27,7 +27,7 @@ public class ShardTransactionChainTest extends AbstractActorTest {
   @Test
   public void testOnReceiveCreateTransaction() throws Exception {
     new JavaTestKit(getSystem()) {{
-      final Props props = ShardTransactionChain.props(store.createTransactionChain());
+      final Props props = ShardTransactionChain.props(store.createTransactionChain(), TestModel.createTestContext());
       final ActorRef subject = getSystem().actorOf(props, "testCreateTransaction");
 
       new Within(duration("1 seconds")) {
@@ -62,7 +62,7 @@ public class ShardTransactionChainTest extends AbstractActorTest {
   @Test
   public void testOnReceiveCloseTransactionChain() throws Exception {
     new JavaTestKit(getSystem()) {{
-      final Props props = ShardTransactionChain.props(store.createTransactionChain());
+      final Props props = ShardTransactionChain.props(store.createTransactionChain(), TestModel.createTestContext());
       final ActorRef subject = getSystem().actorOf(props, "testCloseTransactionChain");
 
       new Within(duration("1 seconds")) {
index 28bbdba..abea785 100644 (file)
@@ -28,6 +28,7 @@ import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -39,8 +40,10 @@ public class ShardTransactionTest extends AbstractActorTest {
     private static final InMemoryDOMDataStore store =
         new InMemoryDOMDataStore("OPER", storeExecutor);
 
+    private static final SchemaContext testSchemaContext = TestModel.createTestContext();
+
     static {
-        store.onGlobalContextUpdated(TestModel.createTestContext());
+        store.onGlobalContextUpdated(testSchemaContext);
     }
 
     @Test
@@ -48,7 +51,7 @@ public class ShardTransactionTest extends AbstractActorTest {
         new JavaTestKit(getSystem()) {{
             final ActorRef shard = getSystem().actorOf(Shard.props("config"));
             final Props props =
-                ShardTransaction.props(store.newReadWriteTransaction(), shard);
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
             final ActorRef subject = getSystem().actorOf(props, "testReadData");
 
             new Within(duration("1 seconds")) {
@@ -88,7 +91,7 @@ public class ShardTransactionTest extends AbstractActorTest {
         new JavaTestKit(getSystem()) {{
             final ActorRef shard = getSystem().actorOf(Shard.props("config"));
             final Props props =
-                ShardTransaction.props(store.newReadWriteTransaction(), shard);
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
             final ActorRef subject = getSystem().actorOf(props, "testReadDataWhenDataNotFound");
 
             new Within(duration("1 seconds")) {
@@ -161,7 +164,7 @@ public class ShardTransactionTest extends AbstractActorTest {
         new JavaTestKit(getSystem()) {{
             final ActorRef shard = getSystem().actorOf(Shard.props("config"));
             final Props props =
-                ShardTransaction.props(store.newReadWriteTransaction(), shard);
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
             final ActorRef subject =
                 getSystem().actorOf(props, "testWriteData");
 
@@ -169,7 +172,7 @@ public class ShardTransactionTest extends AbstractActorTest {
                 protected void run() {
 
                     subject.tell(new WriteData(TestModel.TEST_PATH,
-                        ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()),
+                        ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
                         getRef());
 
                     final String out = new ExpectMsg<String>("match hint") {
@@ -199,7 +202,7 @@ public class ShardTransactionTest extends AbstractActorTest {
         new JavaTestKit(getSystem()) {{
             final ActorRef shard = getSystem().actorOf(Shard.props("config"));
             final Props props =
-                ShardTransaction.props(store.newReadWriteTransaction(), shard);
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, testSchemaContext);
             final ActorRef subject =
                 getSystem().actorOf(props, "testMergeData");
 
@@ -207,10 +210,10 @@ public class ShardTransactionTest extends AbstractActorTest {
                 protected void run() {
 
                     subject.tell(new MergeData(TestModel.TEST_PATH,
-                        ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()),
+                        ImmutableNodes.containerNode(TestModel.TEST_QNAME), testSchemaContext).toSerializable(),
                         getRef());
 
-                    final String out = new ExpectMsg<String>("match hint") {
+                    final String out = new ExpectMsg<String>(duration("500 milliseconds"), "match hint") {
                         // do not put code outside this method, will run afterwards
                         protected String match(Object in) {
                             if (in instanceof MergeDataReply) {
@@ -238,7 +241,7 @@ public class ShardTransactionTest extends AbstractActorTest {
         new JavaTestKit(getSystem()) {{
             final ActorRef shard = getSystem().actorOf(Shard.props("config"));
             final Props props =
-                ShardTransaction.props(store.newReadWriteTransaction(), shard);
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
             final ActorRef subject =
                 getSystem().actorOf(props, "testDeleteData");
 
@@ -275,7 +278,7 @@ public class ShardTransactionTest extends AbstractActorTest {
         new JavaTestKit(getSystem()) {{
             final ActorRef shard = getSystem().actorOf(Shard.props("config"));
             final Props props =
-                ShardTransaction.props(store.newReadWriteTransaction(), shard);
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
             final ActorRef subject =
                 getSystem().actorOf(props, "testReadyTransaction");
 
@@ -311,7 +314,7 @@ public class ShardTransactionTest extends AbstractActorTest {
         new JavaTestKit(getSystem()) {{
             final ActorRef shard = getSystem().actorOf(Shard.props("config"));
             final Props props =
-                ShardTransaction.props(store.newReadWriteTransaction(), shard);
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
             final ActorRef subject =
                 getSystem().actorOf(props, "testCloseTransaction");
 
index 4f3a194..ac1ac37 100644 (file)
@@ -122,7 +122,7 @@ public class TransactionProxyTest extends AbstractActorTest {
 
         Assert.assertEquals(1, listMessages.size());
 
-        Assert.assertTrue(listMessages.get(0) instanceof WriteData);
+        Assert.assertEquals(WriteData.SERIALIZABLE_CLASS, listMessages.get(0).getClass());
     }
 
     @Test
@@ -154,7 +154,7 @@ public class TransactionProxyTest extends AbstractActorTest {
 
         Assert.assertEquals(1, listMessages.size());
 
-        Assert.assertTrue(listMessages.get(0) instanceof MergeData);
+        Assert.assertEquals(MergeData.SERIALIZABLE_CLASS, listMessages.get(0).getClass());
     }
 
     @Test
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/MergeDataTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/MergeDataTest.java
new file mode 100644 (file)
index 0000000..75128e6
--- /dev/null
@@ -0,0 +1,47 @@
+package org.opendaylight.controller.cluster.datastore.messages;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+
+public class MergeDataTest {
+
+    @Test
+    public void testBasic(){
+        MergeData mergeData = new MergeData(TestModel.TEST_PATH, ImmutableNodes
+            .containerNode(TestModel.TEST_QNAME),
+            TestModel.createTestContext());
+
+        MergeData output = MergeData
+            .fromSerializable(mergeData.toSerializable(),
+                TestModel.createTestContext());
+
+    }
+
+    @Test
+    public void testNormalizedNodeEncodeDecode(){
+        NormalizedNode<?, ?> expected =
+            ImmutableNodes.containerNode(TestModel.TEST_QNAME);
+
+
+        NormalizedNodeMessages.Container node =
+            new NormalizedNodeToNodeCodec(TestModel.createTestContext())
+                .encode(TestModel.TEST_PATH,
+                    expected);
+
+        String parentPath = node.getParentPath();
+
+        NormalizedNodeMessages.Node normalizedNode =
+            node.getNormalizedNode();
+
+        NormalizedNode<?,?> actual = new NormalizedNodeToNodeCodec(TestModel.createTestContext()).decode(TestModel.TEST_PATH,
+            normalizedNode);
+
+
+        Assert.assertEquals(expected, actual);
+    }
+}
index 95b6f4f..cac3382 100644 (file)
@@ -4,8 +4,8 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
 import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
@@ -14,6 +14,7 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifie
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
@@ -202,7 +203,7 @@ public abstract class NodeToNormalizedNodeBuilder<T extends PathArgument>
 
       logNode(node);
 
-      if (node.getChildCount() == 0) {
+      if (node.getChildCount() == 0 && !node.getType().equals(ContainerNode.class.getSimpleName())) {
         PathArgument childPathArgument =
             NodeIdentifierFactory.getArgument(node.getPath());
         NormalizedNode child = null;