BUG-5280: introduce base Transaction request/success 06/39506/59
authorRobert Varga <rovarga@cisco.com>
Thu, 26 May 2016 23:13:56 +0000 (01:13 +0200)
committerRobert Varga <rovarga@cisco.com>
Wed, 22 Jun 2016 15:09:58 +0000 (17:09 +0200)
Change-Id: I23b83c3912975497f6ab2fac73451f51e613bc2e
Signed-off-by: Robert Varga <rovarga@cisco.com>
32 files changed:
opendaylight/md-sal/cds-access-api/pom.xml
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbortLocalTransactionRequest.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractLocalTransactionRequest.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractReadTransactionRequest.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractReadTransactionRequestProxyV1.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractTransactionRequestProxy.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractTransactionSuccessProxy.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/CommitLocalTransactionRequest.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionRequest.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionRequestProxyV1.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionSuccess.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionSuccessProxyV1.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequest.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequestBuilder.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequestProxyV1.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/PersistenceProtocol.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionRequest.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionRequestProxyV1.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionSuccess.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionSuccessProxyV1.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionCanCommitSuccess.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionCanCommitSuccessProxyV1.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionDataModification.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionDelete.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionFailure.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionFailureProxyV1.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionMerge.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionModification.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionRequest.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionSuccess.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionWrite.java [new file with mode: 0644]
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/package-info.java [new file with mode: 0644]

index 05f3c8aa46430d6461bcf55c893c127c384dfc79..3e4431658675e564353ee9b87aaade0220957dee 100644 (file)
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>mdsal-artifacts</artifactId>
+                <version>1.4.0-SNAPSHOT</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
         </dependencies>
     </dependencyManagement>
 
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-data-api</artifactId>
         </dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-data-api</artifactId>
         </dependency>
+
+        <!-- Needed for serialization of yang-data-api objects -->
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-clustering-commons</artifactId>
+        </dependency>
     </dependencies>
 
     <scm>
     </dependencies>
 
     <scm>
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbortLocalTransactionRequest.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbortLocalTransactionRequest.java
new file mode 100644 (file)
index 0000000..46351fa
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Request to abort a local transaction. Since local transactions do not introduce state on the backend until they
+ * are ready, the purpose of this message is to inform the backend that a message identifier has been used. This is
+ * not important for single transactions, but is critical to ensure transaction ordering within local histories.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class AbortLocalTransactionRequest extends AbstractLocalTransactionRequest<AbortLocalTransactionRequest> {
+    private static final long serialVersionUID = 1L;
+
+    public AbortLocalTransactionRequest(final @Nonnull TransactionIdentifier identifier, final long sequence,
+            final @Nonnull ActorRef replyTo) {
+        this(identifier, sequence, 0, replyTo);
+    }
+
+    AbortLocalTransactionRequest(final @Nonnull TransactionIdentifier identifier, final long sequence,
+            final long retry, final @Nonnull ActorRef replyTo) {
+        super(identifier, sequence, retry, replyTo);
+    }
+
+    private AbortLocalTransactionRequest(final @Nonnull AbortLocalTransactionRequest request, final long retry) {
+        super(request, retry);
+    }
+
+    @Override
+    protected AbortLocalTransactionRequest cloneAsRetry(final long retry) {
+        return new AbortLocalTransactionRequest(this, retry);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractLocalTransactionRequest.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractLocalTransactionRequest.java
new file mode 100644 (file)
index 0000000..9579ba4
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.Request;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Abstract base class for {@link Request}s involving specific transactions local to a member node. These transactions
+ * take advantage of isolation provided by the DataTree, performing transaction modifications on the frontend.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Message type
+ */
+abstract class AbstractLocalTransactionRequest<T extends AbstractLocalTransactionRequest<T>> extends TransactionRequest<T> {
+    private static final long serialVersionUID = 1L;
+
+    AbstractLocalTransactionRequest(final TransactionIdentifier identifier, final long sequence, final long retry,
+        final ActorRef replyTo) {
+        super(identifier, sequence, retry, replyTo);
+    }
+
+    AbstractLocalTransactionRequest(final T request, final long retry) {
+        super(request, retry);
+    }
+
+    @Override
+    protected final AbstractTransactionRequestProxy<T> externalizableProxy(final ABIVersion version) {
+        throw new UnsupportedOperationException("Local transaction request should never be serialized");
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected final T cloneAsVersion(final ABIVersion version) {
+        // These messages cannot be serialized, hence we this method is a no-op
+        return (T)this;
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractReadTransactionRequest.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractReadTransactionRequest.java
new file mode 100644 (file)
index 0000000..ddc5fef
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * Abstract base class for {@link TransactionRequest}s accessing data as visible in the isolated context of a particular
+ * transaction. The path of the data being accessed is returned via {@link #getPath()}.
+ *
+ * This class is visible outside of this package for the purpose of allowing common instanceof checks
+ * and simplified codepaths.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Message type
+ */
+@Beta
+public abstract class AbstractReadTransactionRequest<T extends AbstractReadTransactionRequest<T>> extends TransactionRequest<T> {
+    private static final long serialVersionUID = 1L;
+    private final YangInstanceIdentifier path;
+
+    AbstractReadTransactionRequest(final TransactionIdentifier identifier, final long sequence, final long retry,
+        final ActorRef replyTo, final YangInstanceIdentifier path) {
+        super(identifier, sequence, retry, replyTo);
+        this.path = Preconditions.checkNotNull(path);
+    }
+
+    AbstractReadTransactionRequest(final T request, final ABIVersion version) {
+        super(request, version);
+        this.path = request.getPath();
+    }
+
+    AbstractReadTransactionRequest(final T request, final long retry) {
+        super(request, retry);
+        this.path = request.getPath();
+    }
+
+    public final @Nonnull YangInstanceIdentifier getPath() {
+        return path;
+    }
+
+    @Override
+    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+        return super.addToStringAttributes(toStringHelper).add("path", path);
+    }
+
+    @Override
+    protected abstract AbstractReadTransactionRequestProxyV1<T> externalizableProxy(final ABIVersion version);
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractReadTransactionRequestProxyV1.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractReadTransactionRequestProxyV1.java
new file mode 100644 (file)
index 0000000..11665a7
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputOutput;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * Abstract base class for serialization proxies associated with {@link AbstractReadTransactionRequest}s. It implements
+ * the initial (Boron) serialization format.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Message type
+ */
+abstract class AbstractReadTransactionRequestProxyV1<T extends AbstractReadTransactionRequest<T>> extends AbstractTransactionRequestProxy<T> {
+    private static final long serialVersionUID = 1L;
+    private YangInstanceIdentifier path;
+
+    AbstractReadTransactionRequestProxyV1() {
+        // For Externalizable
+    }
+
+    AbstractReadTransactionRequestProxyV1(final T request) {
+        super(request);
+    }
+
+    @Override
+    public final void writeExternal(final ObjectOutput out) throws IOException {
+        super.writeExternal(out);
+        try (NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(out)) {
+            nnout.writeYangInstanceIdentifier(path);
+        }
+    }
+
+    @Override
+    public final void readExternal(final ObjectInput in) throws ClassNotFoundException, IOException {
+        super.readExternal(in);
+        path = NormalizedNodeInputOutput.newDataInput(in).readYangInstanceIdentifier();
+    }
+
+    @Override
+    protected final T createRequest(final TransactionIdentifier target, final long sequence, final long retry,
+            final ActorRef replyTo) {
+        return createReadRequest(target, sequence, retry, replyTo, path);
+    }
+
+    abstract T createReadRequest(TransactionIdentifier target, long sequence, long retry, ActorRef replyTo,
+            YangInstanceIdentifier path);
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractTransactionRequestProxy.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractTransactionRequestProxy.java
new file mode 100644 (file)
index 0000000..c9e8d5a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import java.io.DataInput;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.AbstractRequestProxy;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Abstract base class for serialization proxies associated with {@link TransactionRequest}s.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Message type
+ */
+abstract class AbstractTransactionRequestProxy<T extends TransactionRequest<T>> extends AbstractRequestProxy<TransactionIdentifier, T> {
+    private static final long serialVersionUID = 1L;
+
+    AbstractTransactionRequestProxy() {
+        // For Externalizable
+    }
+
+    AbstractTransactionRequestProxy(final T request) {
+        super(request);
+    }
+
+    @Override
+    protected final TransactionIdentifier readTarget(final DataInput in) throws IOException {
+        return TransactionIdentifier.readFrom(in);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractTransactionSuccessProxy.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractTransactionSuccessProxy.java
new file mode 100644 (file)
index 0000000..a0648c9
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import java.io.DataInput;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.AbstractSuccessProxy;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Abstract base class for serialization proxies associated with {@link TransactionSuccess}es.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Message type
+ */
+abstract class AbstractTransactionSuccessProxy<T extends TransactionSuccess<T>> extends AbstractSuccessProxy<TransactionIdentifier, T> {
+    private static final long serialVersionUID = 1L;
+
+    AbstractTransactionSuccessProxy() {
+        // For Externalizable
+    }
+
+    AbstractTransactionSuccessProxy(final T request) {
+        super(request);
+    }
+
+    @Override
+    protected final TransactionIdentifier readTarget(final DataInput in) throws IOException {
+        return TransactionIdentifier.readFrom(in);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/CommitLocalTransactionRequest.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/CommitLocalTransactionRequest.java
new file mode 100644 (file)
index 0000000..97381cc
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+
+/**
+ * Request to commit a local transaction. Since local transactions do not introduce state on the backend until they
+ * are ready, this message carries a complete set of modifications.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class CommitLocalTransactionRequest extends AbstractLocalTransactionRequest<CommitLocalTransactionRequest> {
+    private static final long serialVersionUID = 1L;
+    private final DataTreeModification mod;
+    private final boolean coordinated;
+
+    public CommitLocalTransactionRequest(final @Nonnull TransactionIdentifier identifier, final long sequence,
+            final @Nonnull ActorRef replyTo, final @Nonnull DataTreeModification mod, final boolean coordinated) {
+        this(identifier, sequence, 0, replyTo, mod, coordinated);
+    }
+
+    CommitLocalTransactionRequest(final @Nonnull TransactionIdentifier identifier, final long sequence,
+            final long retry, final @Nonnull ActorRef replyTo, final @Nonnull DataTreeModification mod,
+            final boolean coordinated) {
+        super(identifier, sequence, retry, replyTo);
+        this.mod = Preconditions.checkNotNull(mod);
+        this.coordinated = coordinated;
+    }
+
+
+    private CommitLocalTransactionRequest(final CommitLocalTransactionRequest request, final long retry) {
+        super(request, retry);
+        this.mod = request.mod;
+        this.coordinated = request.coordinated;
+    }
+
+    public DataTreeModification getModification() {
+        return mod;
+    }
+
+    /**
+     * Indicate if this is a coordinated, multi-backend request. If this method returns true, the backend must
+     * act as a cohort participating in the three-phase commit (3PC) protocol to commit this transaction.  If this
+     * method returns false, the backend should proceed to commit the transaction and respond once the commit completes
+     * or fails to complete.
+     *
+     * @return Indication of coordinated commit.
+     */
+    public boolean isCoordinated() {
+        return coordinated;
+    }
+
+    @Override
+    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+        return super.addToStringAttributes(toStringHelper).add("coordinated", coordinated);
+    }
+
+    @Override
+    protected CommitLocalTransactionRequest cloneAsRetry(final long retry) {
+        return new CommitLocalTransactionRequest(this, retry);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionRequest.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionRequest.java
new file mode 100644 (file)
index 0000000..7da9df5
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * A transaction request to query if a particular path exists in the current view of a particular transaction.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class ExistsTransactionRequest extends AbstractReadTransactionRequest<ExistsTransactionRequest> {
+    private static final long serialVersionUID = 1L;
+
+    public ExistsTransactionRequest(final @Nonnull TransactionIdentifier identifier, final long sequence,
+            final @Nonnull ActorRef replyTo, final @Nonnull YangInstanceIdentifier path) {
+        this(identifier, sequence, 0, replyTo, path);
+    }
+
+    ExistsTransactionRequest(final @Nonnull TransactionIdentifier identifier, final long sequence,
+            final long retry, final @Nonnull ActorRef replyTo, final @Nonnull YangInstanceIdentifier path) {
+        super(identifier, sequence, retry, replyTo, path);
+    }
+
+    private ExistsTransactionRequest(final ExistsTransactionRequest request, final ABIVersion version) {
+        super(request, version);
+    }
+
+    private ExistsTransactionRequest(final ExistsTransactionRequest request, final long retry) {
+        super(request, retry);
+    }
+
+    @Override
+    protected ExistsTransactionRequest cloneAsVersion(final ABIVersion version) {
+        return new ExistsTransactionRequest(this, version);
+    }
+
+    @Override
+    protected ExistsTransactionRequestProxyV1 externalizableProxy(final ABIVersion version) {
+        return new ExistsTransactionRequestProxyV1(this);
+    }
+
+    @Override
+    protected ExistsTransactionRequest cloneAsRetry(final long retry) {
+        return new ExistsTransactionRequest(this, retry);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionRequestProxyV1.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionRequestProxyV1.java
new file mode 100644 (file)
index 0000000..ee6d3fd
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * Externalizable proxy for use with {@link ExistsTransactionRequest}. It implements the initial (Boron) serialization
+ * format.
+ *
+ * @author Robert Varga
+ */
+final class ExistsTransactionRequestProxyV1 extends AbstractReadTransactionRequestProxyV1<ExistsTransactionRequest> {
+    private static final long serialVersionUID = 1L;
+
+    public ExistsTransactionRequestProxyV1() {
+        // For Externalizable
+    }
+
+    ExistsTransactionRequestProxyV1(final ExistsTransactionRequest request) {
+        super(request);
+    }
+
+    @Override
+    ExistsTransactionRequest createReadRequest(final TransactionIdentifier target, final long sequence,
+            final long retry, final ActorRef replyTo, final YangInstanceIdentifier path) {
+        return new ExistsTransactionRequest(target, sequence, retry, replyTo, path);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionSuccess.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionSuccess.java
new file mode 100644 (file)
index 0000000..5f081c7
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Successuful reply to an {@link ExistsTransactionRequest}. It indicates presence of requested data via
+ * {@link #getExists()}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class ExistsTransactionSuccess extends TransactionSuccess<ExistsTransactionSuccess> {
+    private static final long serialVersionUID = 1L;
+    private final boolean exists;
+
+    public ExistsTransactionSuccess(final TransactionIdentifier target, final long sequence, final boolean exists) {
+        this(target, sequence, 0, exists);
+    }
+
+    ExistsTransactionSuccess(final TransactionIdentifier target, final long sequence, final long retry,
+            final boolean exists) {
+        super(target, sequence, retry);
+        this.exists = exists;
+    }
+
+    public boolean getExists() {
+        return exists;
+    }
+
+    @Override
+    protected ExistsTransactionSuccessProxyV1 externalizableProxy(final ABIVersion version) {
+        return new ExistsTransactionSuccessProxyV1(this);
+    }
+
+    @Override
+    protected ExistsTransactionSuccess cloneAsVersion(final ABIVersion version) {
+        return this;
+    }
+
+    @Override
+    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+        return super.addToStringAttributes(toStringHelper).add("exists", exists);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionSuccessProxyV1.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionSuccessProxyV1.java
new file mode 100644 (file)
index 0000000..44a1897
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Externalizable proxy for use with {@link ExistsTransactionSuccess}. It implements the initial (Boron) serialization
+ * format.
+ *
+ * @author Robert Varga
+ */
+final class ExistsTransactionSuccessProxyV1 extends AbstractTransactionSuccessProxy<ExistsTransactionSuccess> {
+    private static final long serialVersionUID = 1L;
+    private boolean exists;
+
+    public ExistsTransactionSuccessProxyV1() {
+        // For Externalizable
+    }
+
+    ExistsTransactionSuccessProxyV1(final ExistsTransactionSuccess request) {
+        super(request);
+        this.exists = request.getExists();
+    }
+
+    @Override
+    public void writeExternal(final ObjectOutput out) throws IOException {
+        super.writeExternal(out);
+        out.writeBoolean(exists);
+    }
+
+    @Override
+    public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+        super.readExternal(in);
+        exists = in.readBoolean();
+    }
+
+    @Override
+    protected ExistsTransactionSuccess createSuccess(final TransactionIdentifier target, final long sequence,
+            final long retry) {
+        return new ExistsTransactionSuccess(target, sequence, retry, exists);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequest.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequest.java
new file mode 100644 (file)
index 0000000..171e5dc
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.Optional;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * A transaction request to apply a particular set of operations on top of the current transaction. This message is
+ * used to also finish a transaction by specifying a {@link PersistenceProtocol}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class ModifyTransactionRequest extends TransactionRequest<ModifyTransactionRequest> {
+    private static final long serialVersionUID = 1L;
+    private final List<TransactionModification> modifications;
+    private final PersistenceProtocol protocol;
+
+    private ModifyTransactionRequest(final ModifyTransactionRequest request, final long retry) {
+        super(request, retry);
+        this.modifications = request.modifications;
+        this.protocol = request.protocol;
+    }
+
+    ModifyTransactionRequest(final TransactionIdentifier target, final long sequence, final long retry,
+        final ActorRef replyTo, final List<TransactionModification> modifications, final PersistenceProtocol protocol) {
+        super(target, sequence, retry, replyTo);
+        this.modifications = ImmutableList.copyOf(modifications);
+        this.protocol = protocol;
+    }
+
+    public Optional<PersistenceProtocol> getPersistenceProtocol() {
+        return Optional.ofNullable(protocol);
+    }
+
+    public List<TransactionModification> getModifications() {
+        return modifications;
+    }
+
+    @Override
+    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+        return super.addToStringAttributes(toStringHelper).add("operations", modifications).add("protocol", protocol);
+    }
+
+    @Override
+    protected ModifyTransactionRequestProxyV1 externalizableProxy(final ABIVersion version) {
+        return new ModifyTransactionRequestProxyV1(this);
+    }
+
+    @Override
+    protected ModifyTransactionRequest cloneAsRetry(final long retry) {
+        return new ModifyTransactionRequest(this, retry);
+    }
+
+    @Override
+    protected ModifyTransactionRequest cloneAsVersion(final ABIVersion version) {
+        return this;
+    }
+
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequestBuilder.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequestBuilder.java
new file mode 100644 (file)
index 0000000..88c6a8e
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.concurrent.NotThreadSafe;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.concepts.Identifiable;
+
+/**
+ * A reusable {@link Builder} for creating {@link ModifyTransactionRequest} message instances. Its internal state is
+ * reset when {@link #build()} is invoked, hence it can be used to create a sequence of messages.
+ *
+ * @author Robert Varga
+ */
+@Beta
+@NotThreadSafe
+public final class ModifyTransactionRequestBuilder implements Builder<ModifyTransactionRequest>,
+        Identifiable<TransactionIdentifier> {
+    private final List<TransactionModification> modifications = new ArrayList<>(1);
+    private final TransactionIdentifier identifier;
+    private final ActorRef replyTo;
+    private PersistenceProtocol protocol = null;
+    private long sequence;
+
+    public ModifyTransactionRequestBuilder(final TransactionIdentifier identifier, final ActorRef replyTo) {
+        this.identifier = Preconditions.checkNotNull(identifier);
+        this.replyTo = Preconditions.checkNotNull(replyTo);
+    }
+
+    @Override
+    public TransactionIdentifier getIdentifier() {
+        return identifier;
+    }
+
+    private void checkFinished() {
+        Preconditions.checkState(protocol != null, "Batch has already been finished");
+    }
+
+    public void setSequence(final long sequence) {
+        checkFinished();
+        Preconditions.checkState(modifications.isEmpty(), "Sequence must be set first");
+        this.sequence = sequence;
+    }
+
+    public void addModification(final TransactionModification modification) {
+        checkFinished();
+        modifications.add(Preconditions.checkNotNull(modification));
+    }
+
+    public void setAbort() {
+        checkFinished();
+        // Transaction is being aborted, no need to transmit operations
+        modifications.clear();
+        protocol = PersistenceProtocol.ABORT;
+    }
+
+    public void setCommit(final boolean coordinated) {
+        checkFinished();
+        protocol = coordinated ? PersistenceProtocol.THREE_PHASE : PersistenceProtocol.SIMPLE;
+    }
+
+    public int size() {
+        return modifications.size();
+    }
+
+    @Override
+    public ModifyTransactionRequest build() {
+        final ModifyTransactionRequest ret = new ModifyTransactionRequest(identifier, sequence, 0, replyTo,
+            modifications, protocol);
+        modifications.clear();
+        protocol = null;
+        sequence = 0;
+        return ret;
+    }
+
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequestProxyV1.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequestProxyV1.java
new file mode 100644 (file)
index 0000000..f493e13
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataInput;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputOutput;
+
+/**
+ * Externalizable proxy for use with {@link ExistsTransactionRequest}. It implements the initial (Boron) serialization
+ * format.
+ *
+ * @author Robert Varga
+ */
+final class ModifyTransactionRequestProxyV1 extends AbstractTransactionRequestProxy<ModifyTransactionRequest> {
+    private static final long serialVersionUID = 1L;
+    private List<TransactionModification> modifications;
+    private Optional<PersistenceProtocol> protocol;
+
+    public ModifyTransactionRequestProxyV1() {
+        // For Externalizable
+    }
+
+    ModifyTransactionRequestProxyV1(final ModifyTransactionRequest request) {
+        super(request);
+        this.modifications = Preconditions.checkNotNull(request.getModifications());
+        this.protocol = request.getPersistenceProtocol();
+    }
+
+
+    @Override
+    public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+        super.readExternal(in);
+
+        protocol = Optional.ofNullable(PersistenceProtocol.readFrom(in));
+
+        final int size = in.readInt();
+        if (size != 0) {
+            modifications = new ArrayList<>(size);
+            final NormalizedNodeDataInput nnin = NormalizedNodeInputOutput.newDataInput(in);
+            for (int i = 0; i < size; ++i) {
+                modifications.add(TransactionModification.readFrom(nnin));
+            }
+        } else {
+            modifications = ImmutableList.of();
+        }
+    }
+
+    @Override
+    public void writeExternal(final ObjectOutput out) throws IOException {
+        super.writeExternal(out);
+
+        out.writeByte(PersistenceProtocol.byteValue(protocol.orElse(null)));
+        out.writeInt(modifications.size());
+        if (!modifications.isEmpty()) {
+            try (NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(out)) {
+                for (TransactionModification op : modifications) {
+                    op.writeTo(nnout);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected ModifyTransactionRequest createRequest(final TransactionIdentifier target, final long sequence,
+            final long retry, final ActorRef replyTo) {
+        return new ModifyTransactionRequest(target, sequence, retry, replyTo, modifications, protocol.orElse(null));
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/PersistenceProtocol.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/PersistenceProtocol.java
new file mode 100644 (file)
index 0000000..36acfb2
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import org.opendaylight.yangtools.concepts.WritableObject;
+
+/**
+ * Enumeration of transaction persistence protocols. These govern which protocol is executed between the frontend
+ * and backend to drive persistence of a particular transaction.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public enum PersistenceProtocol implements WritableObject {
+    /**
+     * Abort protocol. The transaction has been aborted on the frontend and its effects should not be visible
+     * in the global history. This is a simple request/reply protocol.
+     */
+    ABORT {
+        @Override
+        byte byteValue() {
+            return 1;
+        }
+    },
+    /**
+     * Simple commit protocol. The transaction should be committed to the global history. The receiving backend
+     * it the only entity which needs to persist its effects, hence a simple request/reply protocol is sufficient.
+     */
+    SIMPLE {
+        @Override
+        byte byteValue() {
+            return 2;
+        }
+    },
+    /**
+     * Three-phase commit protocol (3PC). The transaction should be committed to the global history, but it is a part
+     * of a transaction spanning multiple entities and coordination is needed to drive persistence.
+     */
+    THREE_PHASE {
+        @Override
+        byte byteValue() {
+            return 3;
+        }
+
+    };
+
+    @Override
+    public final void writeTo(final DataOutput out) throws IOException {
+        out.writeByte(byteValue());
+    }
+
+    abstract byte byteValue();
+
+    public static PersistenceProtocol readFrom(final DataInput in) throws IOException {
+        return valueOf(in.readByte());
+    }
+
+    static int byteValue(final PersistenceProtocol finish) {
+        return finish == null ? 0 : finish.byteValue();
+    }
+
+    static PersistenceProtocol valueOf(final byte b) {
+        switch (b) {
+            case 0:
+                return null;
+            case 1:
+                return ABORT;
+            case 2:
+                return SIMPLE;
+            case 3:
+                return THREE_PHASE;
+            default:
+                throw new IllegalArgumentException("Unhandled byte value " + b);
+        }
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionRequest.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionRequest.java
new file mode 100644 (file)
index 0000000..0ee07c0
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * A transaction request to read a particular path exists in the current view of a particular transaction.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class ReadTransactionRequest extends AbstractReadTransactionRequest<ReadTransactionRequest> {
+    private static final long serialVersionUID = 1L;
+
+    public ReadTransactionRequest(final @Nonnull TransactionIdentifier identifier, final long sequence,
+            final @Nonnull ActorRef replyTo, final @Nonnull YangInstanceIdentifier path) {
+        this(identifier, sequence, 0, replyTo, path);
+    }
+
+    ReadTransactionRequest(final @Nonnull TransactionIdentifier identifier, final long sequence,
+            final long retry, final @Nonnull ActorRef replyTo, final @Nonnull YangInstanceIdentifier path) {
+        super(identifier, sequence, retry, replyTo, path);
+    }
+
+    private ReadTransactionRequest(final ReadTransactionRequest request, final ABIVersion version) {
+        super(request, version);
+    }
+
+    private ReadTransactionRequest(final ReadTransactionRequest request, final long retry) {
+        super(request, retry);
+    }
+
+    @Override
+    protected ReadTransactionRequest cloneAsRetry(final long retry) {
+        return new ReadTransactionRequest(this, retry);
+    }
+
+    @Override
+    protected ReadTransactionRequest cloneAsVersion(final ABIVersion version) {
+        return new ReadTransactionRequest(this, version);
+    }
+
+    @Override
+    protected ReadTransactionRequestProxyV1 externalizableProxy(final ABIVersion version) {
+        return new ReadTransactionRequestProxyV1(this);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionRequestProxyV1.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionRequestProxyV1.java
new file mode 100644 (file)
index 0000000..461b1c2
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * Externalizable proxy for use with {@link ReadTransactionRequest}. It implements the initial (Boron) serialization
+ * format.
+ *
+ * @author Robert Varga
+ */
+final class ReadTransactionRequestProxyV1 extends AbstractReadTransactionRequestProxyV1<ReadTransactionRequest> {
+    private static final long serialVersionUID = 1L;
+
+    public ReadTransactionRequestProxyV1() {
+        // For Externalizable
+    }
+
+    ReadTransactionRequestProxyV1(final ReadTransactionRequest request) {
+        super(request);
+    }
+
+    @Override
+    ReadTransactionRequest createReadRequest(final TransactionIdentifier target, final long sequence, final long retry,
+            final ActorRef replyTo, final YangInstanceIdentifier path) {
+        return new ReadTransactionRequest(target, sequence, retry, replyTo, path);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionSuccess.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionSuccess.java
new file mode 100644 (file)
index 0000000..e83adee
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Successful reply to an {@link ReadTransactionRequest}. It indicates presence of requested data via {@link #getData()}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class ReadTransactionSuccess extends TransactionSuccess<ReadTransactionSuccess> {
+    private static final long serialVersionUID = 1L;
+    private final Optional<NormalizedNode<?, ?>> data;
+
+    public ReadTransactionSuccess(final TransactionIdentifier identifier, final long sequence,
+            final Optional<NormalizedNode<?, ?>> data) {
+        this(identifier, sequence, 0, data);
+    }
+
+    ReadTransactionSuccess(final TransactionIdentifier identifier, final long sequence, final long retry,
+            final Optional<NormalizedNode<?, ?>> data) {
+        super(identifier, sequence, retry);
+        this.data = Preconditions.checkNotNull(data);
+    }
+
+    public Optional<NormalizedNode<?, ?>> getData() {
+        return data;
+    }
+
+    @Override
+    protected AbstractTransactionSuccessProxy<ReadTransactionSuccess> externalizableProxy(final ABIVersion version) {
+        return new ReadTransactionSuccessProxyV1(this);
+    }
+
+    @Override
+    protected ReadTransactionSuccess cloneAsVersion(final ABIVersion version) {
+        return this;
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionSuccessProxyV1.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionSuccessProxyV1.java
new file mode 100644 (file)
index 0000000..13e1cf0
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.base.Optional;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputOutput;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Externalizable proxy for use with {@link ReadTransactionSuccess}. It implements the initial (Boron) serialization
+ * format.
+ *
+ * @author Robert Varga
+ */
+final class ReadTransactionSuccessProxyV1 extends AbstractTransactionSuccessProxy<ReadTransactionSuccess> {
+    private static final long serialVersionUID = 1L;
+    private Optional<NormalizedNode<?, ?>> data;
+
+    public ReadTransactionSuccessProxyV1() {
+        // For Externalizable
+    }
+
+    ReadTransactionSuccessProxyV1(final ReadTransactionSuccess request) {
+        super(request);
+        this.data = request.getData();
+    }
+
+    @Override
+    public void writeExternal(final ObjectOutput out) throws IOException {
+        super.writeExternal(out);
+
+        if (data.isPresent()) {
+            out.writeBoolean(true);
+            try (NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(out)) {
+                nnout.writeNormalizedNode(data.get());
+            }
+        } else {
+            out.writeBoolean(false);
+        }
+
+        out.writeObject(data);
+    }
+
+    @Override
+    public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+        super.readExternal(in);
+
+        if (in.readBoolean()) {
+            data = Optional.of(NormalizedNodeInputOutput.newDataInput(in).readNormalizedNode());
+        } else {
+            data = Optional.absent();
+        }
+    }
+
+    @Override
+    protected ReadTransactionSuccess createSuccess(final TransactionIdentifier target, final long sequence,
+            final long retry) {
+        return new ReadTransactionSuccess(target, sequence, retry, data);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionCanCommitSuccess.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionCanCommitSuccess.java
new file mode 100644 (file)
index 0000000..7dc4b19
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Successful reply to a coordinated commit request. It contains a reference to the actor which is handling the commit
+ * process.
+ *
+ * @author Robert Varga
+ */
+public final class TransactionCanCommitSuccess extends TransactionSuccess<TransactionCanCommitSuccess> {
+    private static final long serialVersionUID = 1L;
+    private final ActorRef cohort;
+
+    public TransactionCanCommitSuccess(final TransactionIdentifier identifier, final long sequence, final long retry,
+            final ActorRef cohort) {
+        super(identifier, sequence, retry);
+        this.cohort = Preconditions.checkNotNull(cohort);
+    }
+
+    public ActorRef getCohort() {
+        return cohort;
+    }
+
+    @Override
+    protected AbstractTransactionSuccessProxy<TransactionCanCommitSuccess> externalizableProxy(final ABIVersion version) {
+        return new TransactionCanCommitSuccessProxyV1(this);
+    }
+
+    @Override
+    protected TransactionCanCommitSuccess cloneAsVersion(final ABIVersion version) {
+        return this;
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionCanCommitSuccessProxyV1.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionCanCommitSuccessProxyV1.java
new file mode 100644 (file)
index 0000000..87a6c9a
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import akka.serialization.JavaSerializer;
+import akka.serialization.Serialization;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Externalizable proxy for use with {@link TransactionCanCommitSuccess}. It implements the initial (Boron)
+ * serialization format.
+ *
+ * @author Robert Varga
+ */
+final class TransactionCanCommitSuccessProxyV1 extends AbstractTransactionSuccessProxy<TransactionCanCommitSuccess> {
+    private static final long serialVersionUID = 1L;
+    private ActorRef cohort;
+
+    public TransactionCanCommitSuccessProxyV1() {
+        // For Externalizable
+    }
+
+    TransactionCanCommitSuccessProxyV1(final TransactionCanCommitSuccess success) {
+        super(success);
+        this.cohort = success.getCohort();
+    }
+
+    @Override
+    public void writeExternal(final ObjectOutput out) throws IOException {
+        super.writeExternal(out);
+        out.writeUTF(Serialization.serializedActorPath(cohort));
+    }
+
+    @Override
+    public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+        super.readExternal(in);
+        cohort = JavaSerializer.currentSystem().value().provider().resolveActorRef(in.readUTF());
+    }
+
+    @Override
+    protected TransactionCanCommitSuccess createSuccess(final TransactionIdentifier target, final long sequence,
+            final long retry) {
+        return new TransactionCanCommitSuccess(target, sequence, retry, cohort);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionDataModification.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionDataModification.java
new file mode 100644 (file)
index 0000000..72520c0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * A {@link TransactionModification} which has a data component.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public abstract class TransactionDataModification extends TransactionModification {
+    private final NormalizedNode<?, ?> data;
+
+    TransactionDataModification(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        super(path);
+        this.data = Preconditions.checkNotNull(data);
+    }
+
+    public final NormalizedNode<?, ?> getData() {
+        return data;
+    }
+
+    @Override
+    final void writeTo(final NormalizedNodeDataOutput out) throws IOException {
+        super.writeTo(out);
+        out.writeNormalizedNode(data);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionDelete.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionDelete.java
new file mode 100644 (file)
index 0000000..62acdbb
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * Delete a particular path.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class TransactionDelete extends TransactionModification {
+    public TransactionDelete(final YangInstanceIdentifier path) {
+        super(path);
+    }
+
+    @Override
+    byte getType() {
+        return TYPE_DELETE;
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionFailure.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionFailure.java
new file mode 100644 (file)
index 0000000..d3a8611
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.RequestException;
+import org.opendaylight.controller.cluster.access.concepts.RequestFailure;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Generic {@link RequestFailure} involving a {@link TransactionRequest}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class TransactionFailure extends RequestFailure<TransactionIdentifier, TransactionFailure> {
+    private static final long serialVersionUID = 1L;
+
+    TransactionFailure(final TransactionIdentifier target, final long sequence, final long retry,
+        final RequestException cause) {
+        super(target, sequence, retry, cause);
+    }
+
+    @Override
+    protected TransactionFailure cloneAsVersion(final ABIVersion version) {
+        return this;
+    }
+
+    @Override
+    protected TransactionFailureProxyV1 externalizableProxy(final ABIVersion version) {
+        return new TransactionFailureProxyV1(this);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionFailureProxyV1.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionFailureProxyV1.java
new file mode 100644 (file)
index 0000000..1a35ec1
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import java.io.DataInput;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.AbstractRequestFailureProxy;
+import org.opendaylight.controller.cluster.access.concepts.RequestException;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Externalizable proxy for use with {@link TransactionFailure}. It implements the initial (Boron) serialization
+ * format.
+ *
+ * @author Robert Varga
+ */
+final class TransactionFailureProxyV1 extends AbstractRequestFailureProxy<TransactionIdentifier, TransactionFailure> {
+    private static final long serialVersionUID = 1L;
+
+    public TransactionFailureProxyV1() {
+        // For Externalizable
+    }
+
+    TransactionFailureProxyV1(final TransactionFailure failure) {
+        super(failure);
+    }
+
+    @Override
+    protected TransactionFailure createFailure(final TransactionIdentifier target, final long sequence,
+            final long retry,  final RequestException cause) {
+        return new TransactionFailure(target, sequence, retry, cause);
+    }
+
+    @Override
+    protected TransactionIdentifier readTarget(final DataInput in) throws IOException {
+        return TransactionIdentifier.readFrom(in);
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionMerge.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionMerge.java
new file mode 100644 (file)
index 0000000..1d9bffd
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Merge a {@link NormalizedNode} tree onto a specific path.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class TransactionMerge extends TransactionDataModification {
+    public TransactionMerge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        super(path, data);
+    }
+
+    @Override
+    byte getType() {
+        return TYPE_MERGE;
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionModification.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionModification.java
new file mode 100644 (file)
index 0000000..413f4fb
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataInput;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * An individual modification of a transaction's state. This class and its subclasses are not serializable, but rather
+ * expose {@link #writeTo(NormalizedNodeDataOutput)} and {@link #readFrom(NormalizedNodeDataInput)} methods for explicit
+ * serialization. The reason for this is that they are usually transmitted in bulk, hence it is advantageous to reuse
+ * a {@link NormalizedNodeDataOutput} instance to achieve better compression.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public abstract class TransactionModification {
+    static final byte TYPE_DELETE = 1;
+    static final byte TYPE_MERGE = 2;
+    static final byte TYPE_WRITE = 3;
+
+    private final YangInstanceIdentifier path;
+
+    TransactionModification(final YangInstanceIdentifier path) {
+        this.path = Preconditions.checkNotNull(path);
+    }
+
+    public final YangInstanceIdentifier getPath() {
+        return path;
+    }
+
+    abstract byte getType();
+
+    void writeTo(final NormalizedNodeDataOutput out) throws IOException {
+        out.writeByte(getType());
+        out.writeYangInstanceIdentifier(path);
+    }
+
+    static TransactionModification readFrom(final NormalizedNodeDataInput in) throws IOException {
+        final byte type = in.readByte();
+        switch (type) {
+            case TYPE_DELETE:
+                return new TransactionDelete(in.readYangInstanceIdentifier());
+            case TYPE_MERGE:
+                return new TransactionMerge(in.readYangInstanceIdentifier(), in.readNormalizedNode());
+            case TYPE_WRITE:
+                return new TransactionWrite(in.readYangInstanceIdentifier(), in.readNormalizedNode());
+            default:
+                throw new IllegalArgumentException("Unhandled type " + type);
+        }
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionRequest.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionRequest.java
new file mode 100644 (file)
index 0000000..6a4a26b
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.Beta;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.Request;
+import org.opendaylight.controller.cluster.access.concepts.RequestException;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Abstract base class for {@link Request}s involving specific transaction. This class is visible outside of this
+ * package solely for the ability to perform a unified instanceof check.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Message type
+ */
+@Beta
+public abstract class TransactionRequest<T extends TransactionRequest<T>> extends Request<TransactionIdentifier, T> {
+    private static final long serialVersionUID = 1L;
+
+    TransactionRequest(final TransactionIdentifier identifier, final long sequence, final long retry,
+        final ActorRef replyTo) {
+        super(identifier, sequence, retry, replyTo);
+    }
+
+    TransactionRequest(final T request, final ABIVersion version) {
+        super(request, version);
+    }
+
+    TransactionRequest(final T request, final long retry) {
+        super(request, retry);
+    }
+
+    @Override
+    public final TransactionFailure toRequestFailure(final RequestException cause) {
+        return new TransactionFailure(getTarget(), getSequence(), getRetry(), cause);
+    }
+
+    @Override
+    protected abstract AbstractTransactionRequestProxy<T> externalizableProxy(final ABIVersion version);
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionSuccess.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionSuccess.java
new file mode 100644 (file)
index 0000000..ff56340
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.controller.cluster.access.concepts.RequestSuccess;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+
+/**
+ * Abstract base class for {@link RequestSuccess}es involving specific transaction. This class is visible outside of
+ * this package solely for the ability to perform a unified instanceof check.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Message type
+ */
+@Beta
+public abstract class TransactionSuccess<T extends TransactionSuccess<T>> extends RequestSuccess<TransactionIdentifier, T> {
+    private static final long serialVersionUID = 1L;
+
+    TransactionSuccess(final TransactionIdentifier identifier, final long sequence, final long retry) {
+        super(identifier, sequence, retry);
+    }
+
+    @Override
+    protected abstract AbstractTransactionSuccessProxy<T> externalizableProxy(ABIVersion version);
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionWrite.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionWrite.java
new file mode 100644 (file)
index 0000000..b46cf38
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 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.cluster.access.commands;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Modification to write (and replace) a subtree at specified path with another subtree.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class TransactionWrite extends TransactionDataModification {
+    public TransactionWrite(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        super(path, data);
+    }
+
+    @Override
+    byte getType() {
+        return TYPE_WRITE;
+    }
+}
diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/package-info.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/package-info.java
new file mode 100644 (file)
index 0000000..8a0053b
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2016 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
+ */
+/**
+ * This package defines the messages used to interact with the CDS backend implementation.
+ */
+package org.opendaylight.controller.cluster.access.commands;