Merge "Working md-sal features, including restconf, toaster, flow-services"
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / ShardTransaction.java
index e3d1e2d9d42e4968f4b81ca0ea33d40c2b7b07f7..312ec9a4ff97f861b1fcbc23220dc44e6920b61a 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorRef;
-import akka.actor.PoisonPill;
 import akka.actor.Props;
 import akka.event.Logging;
 import akka.event.LoggingAdapter;
@@ -17,7 +16,6 @@ import akka.japi.Creator;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.opendaylight.controller.cluster.datastore.messages.CloseTransaction;
-import org.opendaylight.controller.cluster.datastore.messages.CloseTransactionReply;
 import org.opendaylight.controller.cluster.datastore.messages.DeleteData;
 import org.opendaylight.controller.cluster.datastore.messages.DeleteDataReply;
 import org.opendaylight.controller.cluster.datastore.messages.MergeData;
@@ -34,13 +32,15 @@ import org.opendaylight.controller.cluster.datastore.modification.ImmutableCompo
 import org.opendaylight.controller.cluster.datastore.modification.MergeModification;
 import org.opendaylight.controller.cluster.datastore.modification.MutableCompositeModification;
 import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-import java.util.concurrent.ExecutionException;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 /**
  * The ShardTransaction Actor represents a remote transaction
@@ -64,164 +64,212 @@ import java.util.concurrent.ExecutionException;
  * <li> {@link org.opendaylight.controller.cluster.datastore.messages.CloseTransaction}
  * </p>
  */
-public class ShardTransaction extends AbstractUntypedActor {
-
-    private final ActorRef shardActor;
-
-    // FIXME : see below
-    // If transactionChain is not null then this transaction is part of a
-    // transactionChain. Not really clear as to what that buys us
-    private final DOMStoreTransactionChain transactionChain;
-
-    private final DOMStoreReadWriteTransaction transaction;
-
-    private final MutableCompositeModification modification =
-        new MutableCompositeModification();
-
-    private final LoggingAdapter log =
-        Logging.getLogger(getContext().system(), this);
-
-    public ShardTransaction(DOMStoreReadWriteTransaction transaction,
-        ActorRef shardActor) {
-        this(null, transaction, shardActor);
+public abstract class ShardTransaction extends AbstractUntypedActor {
+
+  private final ActorRef shardActor;
+  protected final SchemaContext schemaContext;
+
+  // FIXME : see below
+  // If transactionChain is not null then this transaction is part of a
+  // transactionChain. Not really clear as to what that buys us
+  private final DOMStoreTransactionChain transactionChain;
+
+
+  private final MutableCompositeModification modification =
+      new MutableCompositeModification();
+
+  private final LoggingAdapter log =
+      Logging.getLogger(getContext().system(), this);
+
+  protected ShardTransaction(
+                          ActorRef shardActor, SchemaContext schemaContext) {
+    this(null,  shardActor, schemaContext);
+  }
+
+  protected ShardTransaction(DOMStoreTransactionChain transactionChain,
+                          ActorRef shardActor, SchemaContext schemaContext) {
+    this.transactionChain = transactionChain;
+    //this.transaction = transaction;
+    this.shardActor = shardActor;
+    this.schemaContext = schemaContext;
+  }
+
+
+
+  public static Props props(final DOMStoreReadTransaction transaction,
+                            final ActorRef shardActor, final SchemaContext schemaContext) {
+    return Props.create(new Creator<ShardTransaction>() {
+
+      @Override
+      public ShardTransaction create() throws Exception {
+        return new ShardReadTransaction(transaction, shardActor, schemaContext);
+      }
+    });
+  }
+
+  public static Props props(final DOMStoreTransactionChain transactionChain, final DOMStoreReadTransaction transaction,
+                            final ActorRef shardActor, final SchemaContext schemaContext) {
+    return Props.create(new Creator<ShardTransaction>() {
+
+      @Override
+      public ShardTransaction create() throws Exception {
+        return new ShardReadTransaction(transactionChain, transaction, shardActor, schemaContext);
+      }
+    });
+  }
+
+  public static Props props(final DOMStoreReadWriteTransaction transaction,
+                            final ActorRef shardActor, final SchemaContext schemaContext) {
+    return Props.create(new Creator<ShardTransaction>() {
+
+      @Override
+      public ShardTransaction create() throws Exception {
+        return new ShardReadWriteTransaction(transaction, shardActor, schemaContext);
+      }
+    });
+  }
+
+  public static Props props(final DOMStoreTransactionChain transactionChain, final DOMStoreReadWriteTransaction transaction,
+                            final ActorRef shardActor, final SchemaContext schemaContext) {
+    return Props.create(new Creator<ShardTransaction>() {
+
+      @Override
+      public ShardTransaction create() throws Exception {
+        return new ShardReadWriteTransaction(transactionChain, transaction, shardActor, schemaContext);
+      }
+    });
+  }
+
+
+  public static Props props(final DOMStoreWriteTransaction transaction,
+                            final ActorRef shardActor, final SchemaContext schemaContext) {
+    return Props.create(new Creator<ShardTransaction>() {
+
+      @Override
+      public ShardTransaction create() throws Exception {
+        return new ShardWriteTransaction(transaction, shardActor, schemaContext);
+      }
+    });
+  }
+
+  public static Props props(final DOMStoreTransactionChain transactionChain, final DOMStoreWriteTransaction transaction,
+                            final ActorRef shardActor, final SchemaContext schemaContext) {
+    return Props.create(new Creator<ShardTransaction>() {
+
+      @Override
+      public ShardTransaction create() throws Exception {
+        return new ShardWriteTransaction(transactionChain, transaction, shardActor, schemaContext);
+      }
+    });
+  }
+
+
+  @Override
+  public void handleReceive(Object message) throws Exception {
+     if (message.getClass().equals(CloseTransaction.SERIALIZABLE_CLASS)) {
+      closeTransaction(new CloseTransaction());
+    } else if (message instanceof GetCompositedModification) {
+      // This is here for testing only
+      getSender().tell(new GetCompositeModificationReply(
+          new ImmutableCompositeModification(modification)), getSelf());
+    }else{
+      throw new Exception ("ShardTransaction:handleRecieve received an unknown message"+message);
     }
-
-    public ShardTransaction(DOMStoreTransactionChain transactionChain, DOMStoreReadWriteTransaction transaction,
-        ActorRef shardActor) {
-        this.transactionChain = transactionChain;
-        this.transaction = transaction;
-        this.shardActor = shardActor;
-    }
-
-
-
-    public static Props props(final DOMStoreReadWriteTransaction transaction,
-        final ActorRef shardActor) {
-        return Props.create(new Creator<ShardTransaction>() {
-
-            @Override
-            public ShardTransaction create() throws Exception {
-                return new ShardTransaction(transaction, shardActor);
-            }
-        });
-    }
-
-    public static Props props(final DOMStoreTransactionChain transactionChain, final DOMStoreReadWriteTransaction transaction,
-        final ActorRef shardActor) {
-        return Props.create(new Creator<ShardTransaction>() {
-
-            @Override
-            public ShardTransaction create() throws Exception {
-                return new ShardTransaction(transactionChain, transaction, shardActor);
-            }
-        });
-    }
-
-
-    @Override
-    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 (message instanceof DeleteData) {
-            deleteData((DeleteData) message);
-        } else if (message instanceof ReadyTransaction) {
-            readyTransaction((ReadyTransaction) message);
-        } else if (message instanceof CloseTransaction) {
-            closeTransaction((CloseTransaction) message);
-        } else if (message instanceof GetCompositedModification) {
-            // This is here for testing only
-            getSender().tell(new GetCompositeModificationReply(
-                new ImmutableCompositeModification(modification)), getSelf());
+  }
+
+  abstract protected  void closeTransaction(CloseTransaction message);
+
+  protected void readData(DOMStoreReadTransaction transaction,ReadData message) {
+    final ActorRef sender = getSender();
+    final ActorRef self = getSelf();
+    final YangInstanceIdentifier path = message.getPath();
+    final ListenableFuture<Optional<NormalizedNode<?, ?>>> future =
+        transaction.read(path);
+
+    future.addListener(new Runnable() {
+      @Override
+      public void run() {
+        try {
+          Optional<NormalizedNode<?, ?>> optional = future.get();
+          if (optional.isPresent()) {
+            sender.tell(new ReadDataReply(schemaContext,optional.get()).toSerializable(), self);
+          } else {
+            sender.tell(new ReadDataReply(schemaContext,null).toSerializable(), self);
+          }
+        } catch (Exception e) {
+            sender.tell(new akka.actor.Status.Failure(new ReadFailedException( "An Exception occurred  when reading data from path : "
+                + path.toString(),e)),self);
         }
-    }
 
-    private void readData(ReadData message) {
-        final ActorRef sender = getSender();
-        final ActorRef self = getSelf();
-        final InstanceIdentifier path = message.getPath();
-        final ListenableFuture<Optional<NormalizedNode<?, ?>>> future =
-            transaction.read(path);
-
-        future.addListener(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    Optional<NormalizedNode<?, ?>> optional = future.get();
-                    if (optional.isPresent()) {
-                        sender.tell(new ReadDataReply(optional.get()), self);
-                    } else {
-                        sender.tell(new ReadDataReply(null), self);
-                    }
-                } catch (InterruptedException | ExecutionException e) {
-                    log.error(e,
-                        "An exception happened when reading data from path : "
-                            + path.toString());
-                }
-
-            }
-        }, getContext().dispatcher());
-    }
+      }
+    }, getContext().dispatcher());
+  }
+
 
+  protected void writeData(DOMStoreWriteTransaction transaction, WriteData message) {
+    modification.addModification(
+        new WriteModification(message.getPath(), message.getData(),schemaContext));
+    LOG.debug("writeData at path : " + message.getPath().toString());
 
-    private void writeData(WriteData message) {
-        modification.addModification(
-            new WriteModification(message.getPath(), message.getData()));
+    try {
         transaction.write(message.getPath(), message.getData());
-        getSender().tell(new WriteDataReply(), getSelf());
+        getSender().tell(new WriteDataReply().toSerializable(), getSelf());
+    }catch(Exception e){
+        getSender().tell(new akka.actor.Status.Failure(e), getSelf());
     }
+  }
 
-    private void mergeData(MergeData message) {
-        modification.addModification(
-            new MergeModification(message.getPath(), message.getData()));
+  protected void mergeData(DOMStoreWriteTransaction transaction, MergeData message) {
+    modification.addModification(
+        new MergeModification(message.getPath(), message.getData(), schemaContext));
+    LOG.debug("mergeData at path : " + message.getPath().toString());
+    try {
         transaction.merge(message.getPath(), message.getData());
-        getSender().tell(new MergeDataReply(), getSelf());
+        getSender().tell(new MergeDataReply().toSerializable(), getSelf());
+    }catch(Exception e){
+        getSender().tell(new akka.actor.Status.Failure(e), getSelf());
     }
+  }
 
-    private void deleteData(DeleteData message) {
-        modification.addModification(new DeleteModification(message.getPath()));
+  protected void deleteData(DOMStoreWriteTransaction transaction, DeleteData message) {
+    modification.addModification(new DeleteModification(message.getPath()));
+    try {
         transaction.delete(message.getPath());
-        getSender().tell(new DeleteDataReply(), getSelf());
+        getSender().tell(new DeleteDataReply().toSerializable(), getSelf());
+    }catch(Exception e){
+        getSender().tell(new akka.actor.Status.Failure(e), getSelf());
     }
+  }
 
-    private void readyTransaction(ReadyTransaction message) {
-        DOMStoreThreePhaseCommitCohort cohort = transaction.ready();
-        ActorRef cohortActor = getContext().actorOf(
-            ThreePhaseCommitCohort.props(cohort, shardActor, modification), "cohort");
-        getSender()
-            .tell(new ReadyTransactionReply(cohortActor.path()), getSelf());
+  protected void readyTransaction(DOMStoreWriteTransaction transaction, ReadyTransaction message) {
+    DOMStoreThreePhaseCommitCohort cohort =  transaction.ready();
+    ActorRef cohortActor = getContext().actorOf(
+        ThreePhaseCommitCohort.props(cohort, shardActor, modification), "cohort");
+    getSender()
+        .tell(new ReadyTransactionReply(cohortActor.path()).toSerializable(), getSelf());
 
-    }
-
-    private void closeTransaction(CloseTransaction message) {
-        transaction.close();
-        getSender().tell(new CloseTransactionReply(), getSelf());
-        getSelf().tell(PoisonPill.getInstance(), getSelf());
-    }
+  }
 
 
-    // These classes are in here for test purposes only
+  // These classes are in here for test purposes only
 
 
-    static class GetCompositedModification {
+  static class GetCompositedModification {
 
-    }
+  }
 
 
-    static class GetCompositeModificationReply {
-        private final CompositeModification modification;
+  static class GetCompositeModificationReply {
+    private final CompositeModification modification;
 
 
-        GetCompositeModificationReply(CompositeModification modification) {
-            this.modification = modification;
-        }
+    GetCompositeModificationReply(CompositeModification modification) {
+      this.modification = modification;
+    }
 
 
-        public CompositeModification getModification() {
-            return modification;
-        }
+    public CompositeModification getModification() {
+      return modification;
     }
+  }
 }