From: Robert Varga Date: Thu, 26 May 2016 23:13:56 +0000 (+0200) Subject: BUG-5280: introduce base Transaction request/success X-Git-Tag: release/boron~104 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=e4a1f1fa1f3efb4442c1141224b8a2df714efcb4 BUG-5280: introduce base Transaction request/success Change-Id: I23b83c3912975497f6ab2fac73451f51e613bc2e Signed-off-by: Robert Varga --- diff --git a/opendaylight/md-sal/cds-access-api/pom.xml b/opendaylight/md-sal/cds-access-api/pom.xml index 05f3c8aa46..3e44316586 100644 --- a/opendaylight/md-sal/cds-access-api/pom.xml +++ b/opendaylight/md-sal/cds-access-api/pom.xml @@ -23,6 +23,13 @@ pom import + + org.opendaylight.controller + mdsal-artifacts + 1.4.0-SNAPSHOT + pom + import + @@ -44,6 +51,12 @@ org.opendaylight.yangtools yang-data-api + + + + org.opendaylight.controller + sal-clustering-commons + 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 index 0000000000..46351fae66 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbortLocalTransactionRequest.java @@ -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 { + 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 index 0000000000..9579ba497d --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractLocalTransactionRequest.java @@ -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 Message type + */ +abstract class AbstractLocalTransactionRequest> extends TransactionRequest { + 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 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 index 0000000000..ddc5fef25f --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractReadTransactionRequest.java @@ -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 Message type + */ +@Beta +public abstract class AbstractReadTransactionRequest> extends TransactionRequest { + 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 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 index 0000000000..11665a74f3 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractReadTransactionRequestProxyV1.java @@ -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 Message type + */ +abstract class AbstractReadTransactionRequestProxyV1> extends AbstractTransactionRequestProxy { + 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 index 0000000000..c9e8d5a26c --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractTransactionRequestProxy.java @@ -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 Message type + */ +abstract class AbstractTransactionRequestProxy> extends AbstractRequestProxy { + 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 index 0000000000..a0648c975d --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/AbstractTransactionSuccessProxy.java @@ -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 Message type + */ +abstract class AbstractTransactionSuccessProxy> extends AbstractSuccessProxy { + 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 index 0000000000..97381cc267 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/CommitLocalTransactionRequest.java @@ -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 { + 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 index 0000000000..7da9df5e73 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionRequest.java @@ -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 { + 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 index 0000000000..ee6d3fd73a --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionRequestProxyV1.java @@ -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 { + 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 index 0000000000..5f081c77cd --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionSuccess.java @@ -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 { + 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 index 0000000000..44a1897def --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ExistsTransactionSuccessProxyV1.java @@ -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 { + 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 index 0000000000..171e5dce3d --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequest.java @@ -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 { + private static final long serialVersionUID = 1L; + private final List 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 modifications, final PersistenceProtocol protocol) { + super(target, sequence, retry, replyTo); + this.modifications = ImmutableList.copyOf(modifications); + this.protocol = protocol; + } + + public Optional getPersistenceProtocol() { + return Optional.ofNullable(protocol); + } + + public List 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 index 0000000000..88c6a8e24e --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequestBuilder.java @@ -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, + Identifiable { + private final List 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 index 0000000000..f493e13384 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ModifyTransactionRequestProxyV1.java @@ -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 { + private static final long serialVersionUID = 1L; + private List modifications; + private Optional 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 index 0000000000..36acfb2925 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/PersistenceProtocol.java @@ -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 index 0000000000..0ee07c0268 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionRequest.java @@ -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 { + 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 index 0000000000..461b1c2c07 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionRequestProxyV1.java @@ -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 { + 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 index 0000000000..e83adee10e --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionSuccess.java @@ -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 { + private static final long serialVersionUID = 1L; + private final Optional> data; + + public ReadTransactionSuccess(final TransactionIdentifier identifier, final long sequence, + final Optional> data) { + this(identifier, sequence, 0, data); + } + + ReadTransactionSuccess(final TransactionIdentifier identifier, final long sequence, final long retry, + final Optional> data) { + super(identifier, sequence, retry); + this.data = Preconditions.checkNotNull(data); + } + + public Optional> getData() { + return data; + } + + @Override + protected AbstractTransactionSuccessProxy 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 index 0000000000..13e1cf0d5a --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/ReadTransactionSuccessProxyV1.java @@ -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 { + private static final long serialVersionUID = 1L; + private Optional> 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 index 0000000000..7dc4b19039 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionCanCommitSuccess.java @@ -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 { + 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 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 index 0000000000..87a6c9a97b --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionCanCommitSuccessProxyV1.java @@ -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 { + 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 index 0000000000..72520c0aec --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionDataModification.java @@ -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 index 0000000000..62acdbbb76 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionDelete.java @@ -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 index 0000000000..d3a86116e6 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionFailure.java @@ -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 { + 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 index 0000000000..1a35ec1165 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionFailureProxyV1.java @@ -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 { + 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 index 0000000000..1d9bffd346 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionMerge.java @@ -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 index 0000000000..413f4fbe53 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionModification.java @@ -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 index 0000000000..6a4a26b3a5 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionRequest.java @@ -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 Message type + */ +@Beta +public abstract class TransactionRequest> extends Request { + 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 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 index 0000000000..ff56340a9e --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionSuccess.java @@ -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 Message type + */ +@Beta +public abstract class TransactionSuccess> extends RequestSuccess { + private static final long serialVersionUID = 1L; + + TransactionSuccess(final TransactionIdentifier identifier, final long sequence, final long retry) { + super(identifier, sequence, retry); + } + + @Override + protected abstract AbstractTransactionSuccessProxy 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 index 0000000000..b46cf38882 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/TransactionWrite.java @@ -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 index 0000000000..8a0053b879 --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/commands/package-info.java @@ -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;