yifan-c commented on code in PR #169:
URL:
https://github.com/apache/cassandra-analytics/pull/169#discussion_r3457207953
##########
cassandra-analytics-common/src/main/java/org/apache/cassandra/bridge/SSTableVersionAnalyzer.java:
##########
Review Comment:
`SSTableVersionAnalyzer` should live in `cassandra-analytics-core`, not
`common`. Its only callers (`AbstractBulkWriterContext`, `CassandraDataLayer`)
are in core, and the version-determination logic it replaces
(`CassandraClusterInfo.getVersionFromSidecar`) has always been in core.
Placing it in common also forces the `DISABLE_SSTABLE_VERSION_BASED_BRIDGE`
Spark config key into the common module, which should remain Spark-agnostic.
Move `SSTableVersionAnalyzer` (and its test) to core, define the constant
solely in `BulkSparkConf`, and reference
`BulkSparkConf.DISABLE_SSTABLE_VERSION_BASED_BRIDGE` from the analyzer's error
messages.
##########
cassandra-analytics-core/src/main/java/org/apache/cassandra/spark/bulkwriter/BulkSparkConf.java:
##########
@@ -117,6 +118,9 @@ public class BulkSparkConf implements Serializable
// Cassandra version of target cluster. Configuration parameter is exposed
to be able to correctly initialize static
// components, before cluster version is discovered via Sidecar.
public static final String CASSANDRA_VERSION =
SETTING_PREFIX + "cassandra.version";
+ // Disable SSTable version-based bridge determination. When true, falls
back to using cassandra.version for bridge selection.
+ // This provides a safety fallback mechanism if SSTable version detection
fails or encounters issues.
+ public static final String DISABLE_SSTABLE_VERSION_BASED_BRIDGE =
SETTING_PREFIX + "bridge.disable_sstable_version_based";
Review Comment:
1. add one more space before `=` to align with the other lines.
2. The exact same config is defined again in SSTableVersionAnalyzer. It is
error-prone. The spark config key should be defined in one single place, and it
should be declared in `BulkSparkConf`.
3. `SSTableVersionAnalyzer` should be relocated to `anayltics-core`
subproject. The reason is that the `common` subproject should be
spark-agnostic. `SSTableVersionAnalyzer` currently reference to spark config
key. Plus, the original version determination code is in `analytics-core` too.
##########
cassandra-analytics-common/src/main/java/org/apache/cassandra/bridge/SSTableVersionAnalyzer.java:
##########
@@ -0,0 +1,247 @@
+/*
+ * 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.bridge;
+
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Analyzes SSTable versions on a cluster to determine the appropriate
+ * Cassandra bridge to load for bulk write/read operations.
+ *
+ * <p>This class provides logic to select Cassandra bridge based on the
highest SSTable
+ * version detected on the cluster and the user's requested format
preference.</p>
+ */
+public final class SSTableVersionAnalyzer
+{
+ private static final Logger LOGGER =
LoggerFactory.getLogger(SSTableVersionAnalyzer.class);
+ static final String DISABLE_SSTABLE_VERSION_BASED_BRIDGE =
+ "spark.cassandra_analytics.bridge.disable_sstable_version_based";
+
+ private SSTableVersionAnalyzer()
+ {
+ // Utility class
+ }
+
+ /**
+ * Determines which CassandraVersion bridge to load based on:
+ * - Highest SSTable version detected on cluster
+ * - User's format preference
+ *
+ * @param sstableVersionsOnCluster Set of SSTable versions found on
cluster nodes
+ * @param requestedFormat User's requested format, example: "big" or "bti"
+ * @param cassandraVersion Cassandra version string for fallback
+ * @param isSSTableVersionBasedBridgeDisabled flag to disable sstable
version based bridge determination
+ * @return CassandraVersion enum indicating which bridge to load
+ * @throws UnsupportedOperationException if cluster doesn't support
requested format
+ * @throws IllegalStateException if SSTable versions are empty/unknown
+ */
+ public static CassandraVersion determineBridgeVersionForWrite(Set<String>
sstableVersionsOnCluster,
+ String
requestedFormat,
+ String
cassandraVersion,
+ boolean
isSSTableVersionBasedBridgeDisabled)
+ {
+ // Check for fallback mode
+ Optional<CassandraVersion> fallback =
resolveFallbackVersion(cassandraVersion, isSSTableVersionBasedBridgeDisabled);
+ if (fallback.isPresent())
+ {
+ return fallback.get();
+ }
Review Comment:
The method `resolveFallbackVersion` is misleading. "Fallback" implies the
method is triggered when SSTable version-based selection has failed, but it
actually represents the original pre-patch behavior — bridge selection driven
by the Cassandra release version — which the user opts into explicitly via
configuration. Nothing has failed when this path is taken.
I'd suggest rename the method to `resolveLegacyVersionBasedBridge` and the
variable to `version`.
##########
cassandra-analytics-core/src/main/java/org/apache/cassandra/spark/bulkwriter/CassandraClusterInfo.java:
##########
@@ -447,22 +413,35 @@ private TokenRangeMapping<RingInstance>
getTokenRangeReplicasFromSidecar()
metadata -> new RingInstance(metadata,
clusterId()));
}
- public String getVersionFromFeature()
Review Comment:
The behavior is changed unexpectedly with the method deletion.
`getVersionFromFeature` is used in `getLowestCassandraVersion` to allow
version override via feature flag. The override behavior should be kept, i.e. a
feature flag can override the determined cassandra version from the sstable
analyzer.
This patch should only introduce the new sstable based cassandra version
determination logic.
##########
cassandra-analytics-core/src/main/java/org/apache/cassandra/spark/bulkwriter/AbstractBulkWriterContext.java:
##########
@@ -98,10 +101,32 @@ protected AbstractBulkWriterContext(@NotNull BulkSparkConf
conf,
this.conf = conf;
this.sparkDefaultParallelism = sparkDefaultParallelism;
- // Build everything fresh on driver
- this.clusterInfo = buildClusterInfo();
+ // Retrieve lowest Cassandra version without building full ClusterInfo
+ String lowestCassandraVersion = getLowestCassandraVersion(conf);
+ Set<String> sstableVersionsOnCluster = null;
+
+ // Get SSTable versions from cluster only if SSTable version-based
selection is enabled
+ // If disabled, skip retrieval to allow job to proceed even when
SSTable version detection fails
+ if (!conf.isSSTableVersionBasedBridgeDisabled())
+ {
+ sstableVersionsOnCluster = getSSTableVersionsOnCluster(conf);
+ }
+
+ // Determine bridge version
+ this.bridgeVersion =
SSTableVersionAnalyzer.determineBridgeVersionForWrite(
+ sstableVersionsOnCluster,
+ CassandraVersion.configuredSSTableFormat(),
+ lowestCassandraVersion,
+ conf.isSSTableVersionBasedBridgeDisabled()
+ );
+
+ // Validate that Kryo registrator exists for this bridge version
+ KryoRegister.validateKryoRegistratorExists(this.bridgeVersion,
lowestCassandraVersion);
Review Comment:
I believe KryoRegistrator is not really the concern; instead, the real
concern is to ensure the bridgeVersion determined is recognized.
To make the API clean, I'd rather suggest the change to ensure that
`SSTableVersionAnalyzer` always returns a recognized bridgeVersion or throw
when unable to determine.
##########
cassandra-analytics-common/src/main/java/org/apache/cassandra/bridge/SSTableVersionAnalyzer.java:
##########
@@ -0,0 +1,247 @@
+/*
+ * 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.bridge;
+
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Analyzes SSTable versions on a cluster to determine the appropriate
+ * Cassandra bridge to load for bulk write/read operations.
+ *
+ * <p>This class provides logic to select Cassandra bridge based on the
highest SSTable
+ * version detected on the cluster and the user's requested format
preference.</p>
+ */
+public final class SSTableVersionAnalyzer
+{
+ private static final Logger LOGGER =
LoggerFactory.getLogger(SSTableVersionAnalyzer.class);
+ static final String DISABLE_SSTABLE_VERSION_BASED_BRIDGE =
+ "spark.cassandra_analytics.bridge.disable_sstable_version_based";
+
+ private SSTableVersionAnalyzer()
+ {
+ // Utility class
+ }
+
+ /**
+ * Determines which CassandraVersion bridge to load based on:
+ * - Highest SSTable version detected on cluster
+ * - User's format preference
+ *
+ * @param sstableVersionsOnCluster Set of SSTable versions found on
cluster nodes
+ * @param requestedFormat User's requested format, example: "big" or "bti"
+ * @param cassandraVersion Cassandra version string for fallback
+ * @param isSSTableVersionBasedBridgeDisabled flag to disable sstable
version based bridge determination
+ * @return CassandraVersion enum indicating which bridge to load
+ * @throws UnsupportedOperationException if cluster doesn't support
requested format
+ * @throws IllegalStateException if SSTable versions are empty/unknown
+ */
+ public static CassandraVersion determineBridgeVersionForWrite(Set<String>
sstableVersionsOnCluster,
+ String
requestedFormat,
+ String
cassandraVersion,
+ boolean
isSSTableVersionBasedBridgeDisabled)
+ {
+ // Check for fallback mode
+ Optional<CassandraVersion> fallback =
resolveFallbackVersion(cassandraVersion, isSSTableVersionBasedBridgeDisabled);
+ if (fallback.isPresent())
+ {
+ return fallback.get();
+ }
+
+ // Validate SSTable versions are present
+ ensureSSTableVersionsNotEmpty(sstableVersionsOnCluster);
+
+ // Find highest Cassandra version based on SSTable versions
+ CassandraVersion highestCassandraVersion =
findHighestCassandraVersion(sstableVersionsOnCluster);
+
+ // Check if highestCassandraVersion supports the requested format
+ boolean supportsRequestedFormat =
highestCassandraVersion.getNativeSStableVersions()
+ .stream()
+ .anyMatch(v -> v.startsWith(requestedFormat + "-"));
+
+ if (supportsRequestedFormat)
+ {
+ return highestCassandraVersion;
+ }
+ else
+ {
+ throw new UnsupportedOperationException(String.format(
+ "Cluster does not support requested SSTable format
'%s'. " +
+ "Bridge version determined is %s, which only
supports formats: %s",
+ requestedFormat,
highestCassandraVersion.versionName(),
+ highestCassandraVersion.sstableFormats()));
+ }
+ }
+
+ /**
+ * Determines which CassandraVersion bridge to load for read operations
based on:
+ * - Highest SSTable version detected on cluster
+ *
+ * @param sstableVersionsOnCluster Set of SSTable versions found on
cluster nodes
+ * @param cassandraVersion Cassandra version string for fallback
+ * @param isSSTableVersionBasedBridgeDisabled flag to disable sstable
version based bridge determination
+ * @return CassandraVersion enum indicating which bridge to load
+ * @throws IllegalStateException if SSTable versions are empty/unknown
+ */
+ public static CassandraVersion determineBridgeVersionForRead(Set<String>
sstableVersionsOnCluster,
+ String
cassandraVersion,
+ boolean
isSSTableVersionBasedBridgeDisabled)
+ {
+ // Check for fallback mode
+ Optional<CassandraVersion> fallback =
resolveFallbackVersion(cassandraVersion, isSSTableVersionBasedBridgeDisabled);
+ if (fallback.isPresent())
+ {
+ return fallback.get();
+ }
+
+ // Validate SSTable versions are present
+ ensureSSTableVersionsNotEmpty(sstableVersionsOnCluster);
+
+ // Find highest Cassandra version based on SSTable versions
+ CassandraVersion bridgeVersion =
findHighestCassandraVersion(sstableVersionsOnCluster);
+
+ LOGGER.debug("Determined bridge version {} for read based on SSTable
versions on cluster: {}",
+ bridgeVersion.versionName(), sstableVersionsOnCluster);
+
+ return bridgeVersion;
+ }
+
+ private static Optional<CassandraVersion> resolveFallbackVersion(String
cassandraVersion,
+ boolean
isSSTableVersionBasedBridgeDisabled)
+ {
+ if (!isSSTableVersionBasedBridgeDisabled)
+ {
+ return Optional.empty();
+ }
+
+ LOGGER.info("SSTable version-based bridge selection is disabled via
configuration. " +
+ "Using cassandra.version for bridge selection: {}",
cassandraVersion);
+ return Optional.of(CassandraVersion.fromVersion(cassandraVersion)
+ .orElseThrow(() -> new
UnsupportedOperationException(
+ String.format("Unsupported
Cassandra version: %s", cassandraVersion))));
+ }
+
+ /**
+ * Ensures that SSTable versions from cluster are not null or empty.
+ *
+ * @param sstableVersionsOnCluster Set of SSTable versions to validate
+ * @throws IllegalStateException if versions are null or empty
+ */
+ private static void ensureSSTableVersionsNotEmpty(Set<String>
sstableVersionsOnCluster)
+ {
+ if (sstableVersionsOnCluster == null ||
sstableVersionsOnCluster.isEmpty())
+ {
+ throw new IllegalStateException(String.format(
+ "Unable to retrieve SSTable versions from cluster. " +
+ "This is required for SSTable version-based bridge selection.
" +
+ "If you want to bypass this check and use cassandra.version
for bridge selection, " +
+ "set %s=true", DISABLE_SSTABLE_VERSION_BASED_BRIDGE));
+ }
+ }
+
+ /**
+ * Finds the highest Cassandra version based on SSTable versions found on
cluster.
+ *
+ * @param sstableVersionsOnCluster Set of SSTable versions found on cluster
+ * @return CassandraVersion corresponding to the highest SSTable version
+ * @throws IllegalStateException if highest version is unknown
+ */
+ private static CassandraVersion findHighestCassandraVersion(Set<String>
sstableVersionsOnCluster)
+ {
+ String highestSSTableVersion =
findHighestSSTableVersion(sstableVersionsOnCluster);
+ return CassandraVersion.fromSSTableVersion(highestSSTableVersion)
+ .orElseThrow(() -> new IllegalStateException(
+ String.format("Unknown SSTable version: %s.
Cannot determine bridge version. " +
+ "SSTable versions on cluster: %s.
" +
+ "To retry the job using a
fallback Cassandra version, " +
Review Comment:
The "fallback" wording is confusing. Refer to my previous comment for the
reasoning.
There is no fallback that happens automatically; therefore it is not a
fallback.
If my understanding is correct, it is to ask user to retry with the original
cassandra.version-based bridge selection. Please update the error message to
reflect the fact.
##########
cassandra-analytics-core/src/main/java/org/apache/cassandra/spark/bulkwriter/CassandraClusterInfo.java:
##########
@@ -390,33 +383,6 @@ public TokenRangeMapping<RingInstance>
getTokenRangeMapping(boolean cached)
}
}
- @Override
- public String getLowestCassandraVersion()
- {
- String currentCassandraVersion = cassandraVersion;
- if (currentCassandraVersion != null)
- {
- return currentCassandraVersion;
- }
-
- synchronized (this)
- {
- if (cassandraVersion == null)
- {
- String versionFromFeature = getVersionFromFeature();
- if (versionFromFeature != null)
- {
- // Forcing writer to use a particular version
- cassandraVersion = versionFromFeature;
- }
Review Comment:
The version override function is removed accidentally.
##########
cassandra-analytics-core/src/main/java/org/apache/cassandra/spark/bulkwriter/cloudstorage/coordinated/CassandraClusterInfoGroup.java:
##########
@@ -211,38 +214,6 @@ public TokenRangeMapping<RingInstance>
getTokenRangeMapping(boolean cached)
return consolidatedTokenRangeMapping;
}
- /**
- * @return the lowest cassandra version among all clusters
- */
- @Override
- public String getLowestCassandraVersion()
- {
- // Return cached value if available (executor-side reconstruction)
- if (cachedLowestCassandraVersion != null)
- {
- return cachedLowestCassandraVersion;
- }
-
- if (clusterInfos.size() == 1)
- {
- return clusterInfos.get(0).getLowestCassandraVersion();
- }
-
- Map<String, String> aggregated =
applyOnEach(ClusterInfo::getLowestCassandraVersion);
- List<CassandraVersionFeatures> versions = aggregated.values()
- .stream()
-
.map(CassandraVersionFeatures::cassandraVersionFeaturesFromCassandraVersion)
- .sorted()
-
.collect(Collectors.toList());
- CassandraVersionFeatures first = versions.get(0);
- CassandraVersionFeatures last = versions.get(versions.size() - 1);
- Preconditions.checkState(first.getMajorVersion() ==
last.getMajorVersion(),
- "Cluster versions are not compatible.
lowest=%s and highest=%s",
- first.getRawVersionString(),
last.getRawVersionString());
Review Comment:
This check should be lifted when sstable-based bridge determination is
enabled. Mismatching major version no longer mean incompatibility necessarily.
##########
cassandra-analytics-core/src/main/java/org/apache/cassandra/spark/bulkwriter/cloudstorage/coordinated/CassandraClusterInfoGroup.java:
##########
@@ -398,9 +369,62 @@ private RuntimeException toRuntimeException(ClusterInfo
clusterInfo, Throwable c
return new RuntimeException("Failed to perform action on cluster: " +
clusterInfo.clusterId(), cause);
}
- @VisibleForTesting
- Map<String, ClusterInfo> clusterInfoByIdUnsafe()
+ /**
+ * Sets the bridge version on all contained CassandraClusterInfo instances.
+ *
+ * @param bridgeVersion the determined Cassandra bridge version
+ */
+ public void setBridgeVersion(CassandraVersion bridgeVersion)
{
- return clusterInfoById;
+ for (ClusterInfo ci : clusterInfos)
+ {
+ ((CassandraClusterInfo) ci).setBridgeVersion(bridgeVersion);
+ }
+ }
+
+ /**
+ * Retrieves the lowest Cassandra version from all contained clusters.
+ *
+ * @return lowest Cassandra version string across all clusters
+ */
+ public String getLowestCassandraVersion()
+ {
+ Map<String, String> clusterVersions = new HashMap<>();
+ for (ClusterInfo ci : clusterInfos)
+ {
+ CassandraClusterInfo cci = (CassandraClusterInfo) ci;
+ clusterVersions.put(ci.clusterId(),
cci.getLowestCassandraVersion());
+ }
+
+ // Find the lowest version across all clusters
+ List<CassandraVersionFeatures> versions = clusterVersions.values()
+ .stream()
+
.map(CassandraVersionFeatures::cassandraVersionFeaturesFromCassandraVersion)
+ .sorted()
+
.collect(Collectors.toList());
+
+ CassandraVersionFeatures first = versions.get(0);
+ CassandraVersionFeatures last = versions.get(versions.size() - 1);
+ Preconditions.checkState(first.getMajorVersion() ==
last.getMajorVersion(),
+ "Cluster versions are not compatible.
lowest=%s and highest=%s",
+ first.getRawVersionString(),
last.getRawVersionString());
+
+ return first.getRawVersionString();
+ }
+
+ /**
+ * Retrieves aggregated SSTable versions from all contained clusters.
+ *
+ * @return set of SSTable versions present across all clusters
+ */
+ public Set<String> getSSTableVersionsOnCluster()
+ {
+ Set<String> aggregatedSSTableVersions = new HashSet<>();
+ for (ClusterInfo ci : clusterInfos)
+ {
+ CassandraClusterInfo cci = (CassandraClusterInfo) ci;
+
aggregatedSSTableVersions.addAll(cci.getSSTableVersionsOnCluster());
+ }
+ return aggregatedSSTableVersions;
}
Review Comment:
Follow the pattern in the original `getLowestCassandraVersion`, i.e. return
cached if available, otherwise get first, finally aggregate when there are
multiple.
##########
cassandra-analytics-core/src/main/java/org/apache/cassandra/spark/bulkwriter/AbstractBulkWriterContext.java:
##########
@@ -98,10 +101,32 @@ protected AbstractBulkWriterContext(@NotNull BulkSparkConf
conf,
this.conf = conf;
this.sparkDefaultParallelism = sparkDefaultParallelism;
- // Build everything fresh on driver
- this.clusterInfo = buildClusterInfo();
+ // Retrieve lowest Cassandra version without building full ClusterInfo
+ String lowestCassandraVersion = getLowestCassandraVersion(conf);
+ Set<String> sstableVersionsOnCluster = null;
+
+ // Get SSTable versions from cluster only if SSTable version-based
selection is enabled
+ // If disabled, skip retrieval to allow job to proceed even when
SSTable version detection fails
+ if (!conf.isSSTableVersionBasedBridgeDisabled())
+ {
+ sstableVersionsOnCluster = getSSTableVersionsOnCluster(conf);
+ }
+
+ // Determine bridge version
+ this.bridgeVersion =
SSTableVersionAnalyzer.determineBridgeVersionForWrite(
+ sstableVersionsOnCluster,
Review Comment:
`sstableVersionsOnCluster` can be `null` when
`isSSTableVersionBasedBridgeDisabled == true`. But
`SSTableVersionAnalyzer.determineBridgeVersionForWrite` disallows `null` value.
In fact, you may not need the boolean parameter
`isSSTableVersionBasedBridgeDisabled` in the method
`SSTableVersionAnalyzer.determineBridgeVersionForWrite`. When
`sstableVersionsOnCluster` is null, it already indicate the feature is
disabled.
Can you update the corresponding code paths to simplify the implementation?
##########
cassandra-analytics-core/src/main/java/org/apache/cassandra/spark/bulkwriter/cloudstorage/coordinated/CassandraClusterInfoGroup.java:
##########
@@ -398,9 +369,62 @@ private RuntimeException toRuntimeException(ClusterInfo
clusterInfo, Throwable c
return new RuntimeException("Failed to perform action on cluster: " +
clusterInfo.clusterId(), cause);
}
- @VisibleForTesting
- Map<String, ClusterInfo> clusterInfoByIdUnsafe()
+ /**
+ * Sets the bridge version on all contained CassandraClusterInfo instances.
+ *
+ * @param bridgeVersion the determined Cassandra bridge version
+ */
+ public void setBridgeVersion(CassandraVersion bridgeVersion)
{
- return clusterInfoById;
+ for (ClusterInfo ci : clusterInfos)
+ {
+ ((CassandraClusterInfo) ci).setBridgeVersion(bridgeVersion);
+ }
+ }
+
+ /**
+ * Retrieves the lowest Cassandra version from all contained clusters.
+ *
+ * @return lowest Cassandra version string across all clusters
+ */
+ public String getLowestCassandraVersion()
+ {
+ Map<String, String> clusterVersions = new HashMap<>();
+ for (ClusterInfo ci : clusterInfos)
+ {
+ CassandraClusterInfo cci = (CassandraClusterInfo) ci;
+ clusterVersions.put(ci.clusterId(),
cci.getLowestCassandraVersion());
+ }
+
+ // Find the lowest version across all clusters
+ List<CassandraVersionFeatures> versions = clusterVersions.values()
+ .stream()
+
.map(CassandraVersionFeatures::cassandraVersionFeaturesFromCassandraVersion)
+ .sorted()
+
.collect(Collectors.toList());
+
+ CassandraVersionFeatures first = versions.get(0);
+ CassandraVersionFeatures last = versions.get(versions.size() - 1);
+ Preconditions.checkState(first.getMajorVersion() ==
last.getMajorVersion(),
+ "Cluster versions are not compatible.
lowest=%s and highest=%s",
+ first.getRawVersionString(),
last.getRawVersionString());
+
+ return first.getRawVersionString();
+ }
+
Review Comment:
Why is the original implementation `getLowestCassandraVersion` in this class
changed?
I do not see an obvious benefit; but the unrelated change is making code
review hard. Please revert the change, unless there is a pressing reason.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]