/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.cassandra.transport;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;

import org.apache.commons.lang3.ArrayUtils;

The native (CQL binary) protocol version. Some versions may be in beta, which means that the client must specify the beta flag in the frame for the version to be considered valid. Beta versions must have the word "beta" in their description, this is mandated by the specs.
/** * The native (CQL binary) protocol version. * * Some versions may be in beta, which means that the client must * specify the beta flag in the frame for the version to be considered valid. * Beta versions must have the word "beta" in their description, this is mandated * by the specs. * */
public enum ProtocolVersion implements Comparable<ProtocolVersion> { // The order is important as it defines the chronological history of versions, which is used // to determine if a feature is supported or some serdes formats V1(1, "v1", false), // no longer supported V2(2, "v2", false), // no longer supported V3(3, "v3", false), V4(4, "v4", false), V5(5, "v5-beta", true);
The version number
/** The version number */
private final int num;
A description of the version, beta versions should have the word "-beta"
/** A description of the version, beta versions should have the word "-beta" */
private final String descr;
Set this to true for beta versions
/** Set this to true for beta versions */
private final boolean beta; ProtocolVersion(int num, String descr, boolean beta) { this.num = num; this.descr = descr; this.beta = beta; }
The supported versions stored as an array, these should be private and are required for fast decoding
/** The supported versions stored as an array, these should be private and are required for fast decoding*/
private final static ProtocolVersion[] SUPPORTED_VERSIONS = new ProtocolVersion[] { V3, V4, V5 }; final static ProtocolVersion MIN_SUPPORTED_VERSION = SUPPORTED_VERSIONS[0]; final static ProtocolVersion MAX_SUPPORTED_VERSION = SUPPORTED_VERSIONS[SUPPORTED_VERSIONS.length - 1];
All supported versions, published as an enumset
/** All supported versions, published as an enumset */
public final static EnumSet<ProtocolVersion> SUPPORTED = EnumSet.copyOf(Arrays.asList((ProtocolVersion[]) ArrayUtils.addAll(SUPPORTED_VERSIONS)));
Old unsupported versions, this is OK as long as we never add newer unsupported versions
/** Old unsupported versions, this is OK as long as we never add newer unsupported versions */
public final static EnumSet<ProtocolVersion> UNSUPPORTED = EnumSet.complementOf(SUPPORTED);
The preferred versions
/** The preferred versions */
public final static ProtocolVersion CURRENT = V4; public final static Optional<ProtocolVersion> BETA = Optional.of(V5); public static List<String> supportedVersions() { List<String> ret = new ArrayList<>(SUPPORTED.size()); for (ProtocolVersion version : SUPPORTED) ret.add(version.toString()); return ret; } public static ProtocolVersion decode(int versionNum, ProtocolVersionLimit ceiling) { ProtocolVersion ret = versionNum >= MIN_SUPPORTED_VERSION.num && versionNum <= ceiling.getMaxVersion().num ? SUPPORTED_VERSIONS[versionNum - MIN_SUPPORTED_VERSION.num] : null; if (ret == null) { // if this is not a supported version check the old versions for (ProtocolVersion version : UNSUPPORTED) { // if it is an old version that is no longer supported this ensures that we reply // with that same version if (version.num == versionNum) throw new ProtocolException(ProtocolVersion.invalidVersionMessage(versionNum), version); } // If the version is invalid reply with the highest version that we support throw new ProtocolException(invalidVersionMessage(versionNum), ceiling.getMaxVersion()); } return ret; } public boolean isBeta() { return beta; } public static String invalidVersionMessage(int version) { return String.format("Invalid or unsupported protocol version (%d); supported versions are (%s)", version, String.join(", ", ProtocolVersion.supportedVersions())); } public int asInt() { return num; } @Override public String toString() { // This format is mandated by the protocl specs for the SUPPORTED message, see OptionsMessage execute(). return String.format("%d/%s", num, descr); } public final boolean isGreaterThan(ProtocolVersion other) { return num > other.num; } public final boolean isGreaterOrEqualTo(ProtocolVersion other) { return num >= other.num; } public final boolean isSmallerThan(ProtocolVersion other) { return num < other.num; } public final boolean isSmallerOrEqualTo(ProtocolVersion other) { return num <= other.num; } }