From: Robert Varga Date: Tue, 24 May 2016 22:14:29 +0000 (+0200) Subject: BUG-5930: introduce PayloadVersion X-Git-Tag: release/boron~119 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=70b20300990b171743d3c7861e60cdde5d60966f BUG-5930: introduce PayloadVersion This patch defines the concept of a PayloadVersion, which governs state flooding from leader to followers. Change-Id: I412fbe89c75f4a66bb9e780bfdf0d3153a8b5366 Signed-off-by: Robert Varga --- diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/AbstractVersionException.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/AbstractVersionException.java new file mode 100644 index 0000000000..709217d7a5 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/AbstractVersionException.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.datastore.persisted; + +import com.google.common.annotations.Beta; +import com.google.common.base.Preconditions; +import javax.annotation.Nonnull; + +/** + * Abstract base exception used for reporting version mismatches from {@link PayloadVersion}. + * + * @author Robert Varga + */ +@Beta +public abstract class AbstractVersionException extends Exception { + private static final long serialVersionUID = 1L; + private final PayloadVersion closestVersion; + private final int version; + + AbstractVersionException(final String message, final short version, final PayloadVersion closestVersion) { + super(message); + this.closestVersion = Preconditions.checkNotNull(closestVersion); + this.version = Short.toUnsignedInt(version); + } + + /** + * Return the numeric version which has caused this exception. + * + * @return Numeric version + */ + public final int getVersion() { + return version; + } + + /** + * Return the closest version supported by this codebase. + * + * @return Closest supported {@link PayloadVersion} + */ + public final @Nonnull PayloadVersion getClosestVersion() { + return closestVersion; + } + +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/FutureVersionException.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/FutureVersionException.java new file mode 100644 index 0000000000..f6554968ff --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/FutureVersionException.java @@ -0,0 +1,25 @@ +/* + * 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.datastore.persisted; + +import com.google.common.annotations.Beta; + +/** + * Exception thrown from {@link PayloadVersion#valueOf(short)} when the specified version is too new to be supported + * by the codebase. + * + * @author Robert Varga + */ +@Beta +public final class FutureVersionException extends AbstractVersionException { + private static final long serialVersionUID = 1L; + + FutureVersionException(final short version, PayloadVersion closest) { + super("Version " + Short.toUnsignedInt(version) + " is too new", version, closest); + } +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/PastVersionException.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/PastVersionException.java new file mode 100644 index 0000000000..38bdf9bb66 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/PastVersionException.java @@ -0,0 +1,25 @@ +/* + * 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.datastore.persisted; + +import com.google.common.annotations.Beta; + +/** + * Exception thrown from {@link PayloadVersion#valueOf(short)} when the specified version is too old and no longer + * supported by the codebase. + * + * @author Robert Varga + */ +@Beta +public final class PastVersionException extends AbstractVersionException { + private static final long serialVersionUID = 1L; + + PastVersionException(final short version, final PayloadVersion closest) { + super("Version " + Short.toUnsignedInt(version) + " is too old", version, closest); + } +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/PayloadVersion.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/PayloadVersion.java new file mode 100644 index 0000000000..051a375cd6 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/PayloadVersion.java @@ -0,0 +1,126 @@ +/* + * 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.datastore.persisted; + +import com.google.common.annotations.Beta; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.concepts.WritableObject; + +/** + * Enumeration of all ABI versions supported by this implementation of persistence. An ABI version has to be bumped + * whenever: + * - a new event is defined + * - serialization format is changed + * + * This version effectively defines the protocol version between actors participating on a particular shard. A shard + * participant instance should oppose RAFT candidates which produce persistence of an unsupported version. If a follower + * encounters an unsupported version it must not become fully-operational, as it does not have an accurate view + * of shard state. + * + * @author Robert Varga + */ +@Beta +public enum PayloadVersion implements WritableObject { + // NOTE: enumeration values need to be sorted in asceding order of their version to keep Comparable working + + /** + * Version which is older than any other version. This version exists purely for testing purposes. + */ + @VisibleForTesting + TEST_PAST_VERSION(0), + + /** + * Initial ABI version, as shipped with Boron Simultaneous release. + */ + // We seed the initial version to be the same as DataStoreVersions.BORON-VERSION for compatibility reasons. + BORON(5), + + /** + * Version which is newer than any other version. This version exists purely for testing purposes. + */ + @VisibleForTesting + TEST_FUTURE_VERSION(65535); + + private final short value; + + PayloadVersion(final int intVersion) { + Preconditions.checkArgument(intVersion >= 0 && intVersion <= 65535); + value = (short) intVersion; + } + + /** + * Return the unsigned short integer identifying this version. + * + * @return Unsigned short integer identifying this version + */ + public short shortValue() { + return value; + } + + /** + * Return the codebase-native persistence version. This version is the default version allocated to messages + * at runtime. Conversion to previous versions may incur additional overhead (such as object allocation). + * + * @return Current {@link PayloadVersion} + */ + public static @Nonnull PayloadVersion current() { + return BORON; + } + + /** + * Return the {@link PayloadVersion} corresponding to an unsigned short integer. This method is provided for callers + * which provide their own recovery strategy in case of version incompatibility. + * + * @param s Short integer as returned from {@link #shortValue()} + * @return {@link PayloadVersion} + * @throws FutureVersionException if the specified integer identifies a future version + * @throws PastVersionException if the specified integer identifies a past version which is no longer supported + */ + public static @Nonnull PayloadVersion valueOf(final short s) throws FutureVersionException, PastVersionException { + switch (Short.toUnsignedInt(s)) { + case 0: + case 1: + case 2: + case 3: + case 4: + throw new PastVersionException(s, BORON); + case 5: + return BORON; + default: + throw new FutureVersionException(s, BORON); + } + } + + @Override + public void writeTo(final DataOutput out) throws IOException { + out.writeShort(value); + } + + /** + * Read an {@link PayloadVersion} from a {@link DataInput}. This method is provided for callers which do not have + * a recovery strategy for dealing with unsupported versions. + * + * @param in Input from which to read + * @return An {@link PayloadVersion} + * @throws IOException If read fails or an unsupported version is encountered + */ + public static @Nonnull PayloadVersion readFrom(final @Nonnull DataInput in) throws IOException { + final short s = in.readShort(); + try { + return valueOf(s); + } catch (FutureVersionException | PastVersionException e) { + throw new IOException("Unsupported version", e); + } + } + +}