- 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>
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;
// property persistent
private final boolean persistent;
+ private SchemaContext schemaContext;
+
private Shard(String name) {
String setting = System.getProperty("shard.persistent");
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());
}
private void updateSchemaContext(UpdateSchemaContext message) {
+ this.schemaContext = message.getSchemaContext();
store.onGlobalContextUpdated(message.getSchemaContext());
}
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());
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;
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
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);
}
});
}
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) {
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
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
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())
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);
}
});
}
@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
@Override public Object toSerializable() {
return ShardTransactionMessages.DeleteData.newBuilder()
- .setInstanceIdentifierPathArguments(
- InstanceIdentifierUtils.getParentPath(path.toString())).build();
+ .setInstanceIdentifierPathArguments(path.toString()).build();
}
public static DeleteData fromSerizalizable(Object serializable){
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){
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);
}
+
}
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") {
@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")) {
@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")) {
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;
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
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")) {
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")) {
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");
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") {
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");
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) {
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");
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");
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");
Assert.assertEquals(1, listMessages.size());
- Assert.assertTrue(listMessages.get(0) instanceof WriteData);
+ Assert.assertEquals(WriteData.SERIALIZABLE_CLASS, listMessages.get(0).getClass());
}
@Test
Assert.assertEquals(1, listMessages.size());
- Assert.assertTrue(listMessages.get(0) instanceof MergeData);
+ Assert.assertEquals(MergeData.SERIALIZABLE_CLASS, listMessages.get(0).getClass());
}
@Test
--- /dev/null
+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);
+ }
+}
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;
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;
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;