[CASSANDRA-20736] Add CMS membership directly to ClusterMetadata

This commit is contained in:
Sam Tunnicliffe 2025-06-10 16:03:17 +01:00
parent 5282f81d0a
commit 1cfa689778
11 changed files with 351 additions and 78 deletions

View File

@ -0,0 +1,203 @@
/*
* 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.tcm;
import java.io.IOException;
import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;
import com.google.common.collect.ImmutableSet;
import org.apache.cassandra.db.TypeSizes;
import org.apache.cassandra.io.util.DataInputPlus;
import org.apache.cassandra.io.util.DataOutputPlus;
import org.apache.cassandra.tcm.membership.NodeId;
import org.apache.cassandra.tcm.serialization.MetadataSerializer;
import org.apache.cassandra.tcm.serialization.Version;
import org.apache.cassandra.utils.btree.BTreeSet;
public class CMSMembership implements MetadataValue<CMSMembership>
{
public static final Serializer serializer = new Serializer();
public static final CMSMembership EMPTY = new CMSMembership();
private final Epoch lastModified;
private final BTreeSet<NodeId> fullMembers;
private final BTreeSet<NodeId> joiningMembers;
private CMSMembership()
{
this(Epoch.EMPTY,
BTreeSet.empty(NodeId::compareTo),
BTreeSet.empty(NodeId::compareTo));
}
private CMSMembership(Epoch lastModified, BTreeSet<NodeId> fullMembers, BTreeSet<NodeId> joiningMembers)
{
this.lastModified = lastModified;
this.fullMembers = fullMembers;
this.joiningMembers = joiningMembers;
}
@Override
public CMSMembership withLastModified(Epoch epoch)
{
return lastModified.is(epoch) ? this : new CMSMembership(epoch, fullMembers, joiningMembers);
}
@Override
public Epoch lastModified()
{
return lastModified;
}
public ImmutableSet<NodeId> joiningMembers()
{
return ImmutableSet.copyOf(joiningMembers);
}
public ImmutableSet<NodeId> fullMembers()
{
return ImmutableSet.copyOf(fullMembers);
}
public CMSMembership startJoining(NodeId id)
{
if (joiningMembers.contains(id))
throw new IllegalStateException(id + " is already joining the CMS");
if (fullMembers.contains(id))
throw new IllegalStateException(id + " has already fully joined the CMS");
return new CMSMembership(lastModified, fullMembers, joiningMembers.with(id));
}
public CMSMembership cancelJoining(NodeId id)
{
if (!joiningMembers.contains(id))
throw new IllegalStateException(id + " is not currently joining the CMS");
if (fullMembers.contains(id))
throw new IllegalStateException(id + " has already fully joined the CMS");
return new CMSMembership(lastModified, fullMembers, joiningMembers.without(id));
}
public CMSMembership finishJoining(NodeId id)
{
if (!joiningMembers.contains(id))
throw new IllegalStateException(id + " is not currently joining the CMS");
if (fullMembers.contains(id))
throw new IllegalStateException(id + " has already fully joined the CMS");
return new CMSMembership(lastModified, fullMembers.with(id), joiningMembers.without(id));
}
public CMSMembership leave(NodeId id)
{
if (joiningMembers.contains(id))
throw new IllegalStateException(id + " is currently joining the CMS, ");
if (!fullMembers.contains(id))
throw new IllegalStateException(id + " is not a CMS member");
return new CMSMembership(lastModified, fullMembers.without(id), joiningMembers);
}
@Override
public String toString()
{
return "CMSMembership{" +
"lastModified=" + lastModified +
", fullMembers=" + fullMembers +
", joiningMembers=" + joiningMembers +
'}';
}
@Override
public final boolean equals(Object o)
{
if (!(o instanceof CMSMembership)) return false;
CMSMembership that = (CMSMembership) o;
return Objects.equals(lastModified, that.lastModified) &&
Objects.equals(fullMembers, that.fullMembers) &&
Objects.equals(joiningMembers, that.joiningMembers);
}
@Override
public int hashCode()
{
int result = Objects.hashCode(lastModified);
result = 31 * result + Objects.hashCode(fullMembers);
result = 31 * result + Objects.hashCode(joiningMembers);
return result;
}
public static class Serializer implements MetadataSerializer<CMSMembership>
{
@Override
public void serialize(CMSMembership t, DataOutputPlus out, Version version) throws IOException
{
Epoch.serializer.serialize(t.lastModified, out);
out.writeUnsignedVInt32(t.fullMembers.size());
for (NodeId id : t.fullMembers)
NodeId.serializer.serialize(id, out, version);
out.writeUnsignedVInt32(t.joiningMembers.size());
for (NodeId id : t.joiningMembers)
NodeId.serializer.serialize(id, out, version);
}
@Override
public CMSMembership deserialize(DataInputPlus in, Version version) throws IOException
{
Epoch lastModified = Epoch.serializer.deserialize(in, version);
int fullMemberCount = in.readUnsignedVInt32();
SortedSet<NodeId> fullMembers = new TreeSet<>();
for (int i = 0; i < fullMemberCount; i++)
fullMembers.add(NodeId.serializer.deserialize(in, version));
int joiningMemberCount = in.readUnsignedVInt32();
SortedSet<NodeId> joiningMembers = new TreeSet<>();
for (int i = 0; i < joiningMemberCount; i++)
joiningMembers.add(NodeId.serializer.deserialize(in, version));
return new CMSMembership(lastModified, BTreeSet.of(fullMembers), BTreeSet.of(joiningMembers)) ;
}
@Override
public long serializedSize(CMSMembership t, Version version)
{
long size = Epoch.serializer.serializedSize(t.lastModified);
size += TypeSizes.sizeofUnsignedVInt(t.fullMembers.size());
for (NodeId id : t.fullMembers)
size += NodeId.serializer.serializedSize(id, version);
size += TypeSizes.sizeofUnsignedVInt(t.joiningMembers.size());
for (NodeId id : t.joiningMembers)
size += NodeId.serializer.serializedSize(id, version);
return size;
}
}
}

View File

@ -29,6 +29,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
@ -62,7 +63,6 @@ import org.apache.cassandra.schema.KeyspaceMetadata;
import org.apache.cassandra.schema.KeyspaceParams;
import org.apache.cassandra.schema.Keyspaces;
import org.apache.cassandra.schema.ReplicationParams;
import org.apache.cassandra.schema.SchemaConstants;
import org.apache.cassandra.schema.TableId;
import org.apache.cassandra.service.accord.topology.AccordFastPath;
import org.apache.cassandra.service.accord.topology.AccordStaleReplicas;
@ -89,7 +89,6 @@ import org.apache.cassandra.tcm.serialization.Version;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.Pair;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static org.apache.cassandra.config.CassandraRelevantProperties.LINE_SEPARATOR;
import static org.apache.cassandra.db.TypeSizes.sizeof;
import static org.apache.cassandra.tcm.serialization.Version.MIN_ACCORD_VERSION;
@ -114,6 +113,7 @@ public class ClusterMetadata
public final ConsensusMigrationState consensusMigrationState;
public final ImmutableMap<ExtensionKey<?,?>, ExtensionValue<?>> extensions;
public final AccordStaleReplicas accordStaleReplicas;
public final CMSMembership cmsMembership;
// This isn't serialized as part of ClusterMetadata it's really just a view over the Directory.
public final Locator locator;
@ -121,7 +121,6 @@ public class ClusterMetadata
// These fields are lazy but only for the test purposes, since their computation requires initialization of the log ks
private EndpointsForRange fullCMSReplicas;
private Set<InetAddressAndPort> fullCMSEndpoints;
private Set<NodeId> fullCMSIds;
private volatile Map<ReplicationParams, RangesAtEndpoint> localRangesAllSettled = null;
private static final RangesAtEndpoint EMPTY_LOCAL_RANGES = RangesAtEndpoint.empty(FBUtilities.getBroadcastAddressAndPort());
@ -151,7 +150,8 @@ public class ClusterMetadata
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
ImmutableMap.of(),
AccordStaleReplicas.EMPTY);
AccordStaleReplicas.EMPTY,
CMSMembership.EMPTY);
}
public ClusterMetadata(Epoch epoch,
@ -165,7 +165,8 @@ public class ClusterMetadata
InProgressSequences inProgressSequences,
ConsensusMigrationState consensusMigrationState,
Map<ExtensionKey<?, ?>, ExtensionValue<?>> extensions,
AccordStaleReplicas accordStaleReplicas)
AccordStaleReplicas accordStaleReplicas,
CMSMembership cmsMembership)
{
this(EMPTY_METADATA_IDENTIFIER,
epoch,
@ -179,22 +180,25 @@ public class ClusterMetadata
inProgressSequences,
consensusMigrationState,
extensions,
accordStaleReplicas);
accordStaleReplicas,
cmsMembership);
}
private ClusterMetadata(int metadataIdentifier,
Epoch epoch,
IPartitioner partitioner,
DistributedSchema schema,
Directory directory,
TokenMap tokenMap,
DataPlacements placements,
AccordFastPath accordFastPath,
LockedRanges lockedRanges,
InProgressSequences inProgressSequences,
ConsensusMigrationState consensusMigrationState,
Map<ExtensionKey<?, ?>, ExtensionValue<?>> extensions,
AccordStaleReplicas accordStaleReplicas)
Epoch epoch,
IPartitioner partitioner,
DistributedSchema schema,
Directory directory,
TokenMap tokenMap,
DataPlacements placements,
AccordFastPath accordFastPath,
LockedRanges lockedRanges,
InProgressSequences inProgressSequences,
ConsensusMigrationState consensusMigrationState,
Map<ExtensionKey<?, ?>, ExtensionValue<?>> extensions,
AccordStaleReplicas accordStaleReplicas,
CMSMembership cmsMembership)
{
// TODO: token map is a feature of the specific placement strategy, and so may not be a relevant component of
// ClusterMetadata in the long term. We need to consider how the actual components of metadata can be evolved
@ -214,6 +218,7 @@ public class ClusterMetadata
this.extensions = ImmutableMap.copyOf(extensions);
this.locator = Locator.usingDirectory(directory);
this.accordStaleReplicas = accordStaleReplicas;
this.cmsMembership = cmsMembership;
}
public Set<InetAddressAndPort> fullCMSMembers()
@ -223,9 +228,10 @@ public class ClusterMetadata
if (fullCMSEndpoints == null)
{
if (schema.maybeGetKeyspaceMetadata(SchemaConstants.METADATA_KEYSPACE_NAME).isEmpty())
return Collections.emptySet();
this.fullCMSEndpoints = ImmutableSet.copyOf(placements.get(ReplicationParams.meta(this)).reads.byEndpoint().keySet());
fullCMSEndpoints = ImmutableSet.copyOf(cmsMembership.fullMembers()
.stream()
.map(directory::endpoint)
.collect(Collectors.toSet()));
}
return fullCMSEndpoints;
}
@ -235,13 +241,7 @@ public class ClusterMetadata
if (epoch.isBefore(Epoch.FIRST))
return Collections.emptySet();
if (fullCMSIds == null)
{
if (schema.maybeGetKeyspaceMetadata(SchemaConstants.METADATA_KEYSPACE_NAME).isEmpty())
return Collections.emptySet();
this.fullCMSIds = placements.get(ReplicationParams.meta(this)).reads.byEndpoint().keySet().stream().map(directory::peerId).collect(toImmutableSet());
}
return fullCMSIds;
return cmsMembership.fullMembers();
}
public EndpointsForRange fullCMSMembersAsReplicas()
@ -251,9 +251,10 @@ public class ClusterMetadata
if (fullCMSReplicas == null)
{
if (schema.maybeGetKeyspaceMetadata(SchemaConstants.METADATA_KEYSPACE_NAME).isEmpty())
return EndpointsForRange.empty(MetaStrategy.entireRange);
fullCMSReplicas = placements.get(ReplicationParams.meta(this)).reads.forRange(MetaStrategy.entireRange).get();
EndpointsForRange.Builder builder = EndpointsForRange.builder(MetaStrategy.entireRange);
for (NodeId nodeId : fullCMSMemberIds())
builder.add(MetaStrategy.replica(directory.endpoint(nodeId)));
fullCMSReplicas = builder.build();
}
return fullCMSReplicas;
}
@ -291,7 +292,8 @@ public class ClusterMetadata
capLastModified(inProgressSequences, epoch),
capLastModified(consensusMigrationState, epoch),
capLastModified(extensions, epoch),
capLastModified(accordStaleReplicas, epoch));
capLastModified(accordStaleReplicas, epoch),
capLastModified(cmsMembership, epoch));
}
public ClusterMetadata initializeClusterIdentifier(int clusterIdentifier)
@ -314,7 +316,8 @@ public class ClusterMetadata
inProgressSequences,
consensusMigrationState,
extensions,
accordStaleReplicas);
accordStaleReplicas,
cmsMembership);
}
private static Map<ExtensionKey<?,?>, ExtensionValue<?>> capLastModified(Map<ExtensionKey<?,?>, ExtensionValue<?>> original, Epoch maxEpoch)
@ -495,6 +498,7 @@ public class ClusterMetadata
private final Map<ExtensionKey<?, ?>, ExtensionValue<?>> extensions;
private final Set<MetadataKey> modifiedKeys;
private AccordStaleReplicas accordStaleReplicas;
private CMSMembership cmsMembership;
private Transformer(ClusterMetadata metadata, Epoch epoch)
{
@ -637,6 +641,30 @@ public class ClusterMetadata
return this;
}
public Transformer startJoiningCMS(NodeId id)
{
cmsMembership = cmsMembership.startJoining(id);
return this;
}
public Transformer finishJoiningCMS(NodeId id)
{
cmsMembership = cmsMembership.finishJoining(id);
return this;
}
public Transformer cancelJoiningCMS(NodeId id)
{
cmsMembership = cmsMembership.cancelJoining(id);
return this;
}
public Transformer leaveCMS(NodeId id)
{
cmsMembership = cmsMembership.leave(id);
return this;
}
public Transformer with(DataPlacements placements)
{
this.placements = placements;
@ -834,7 +862,8 @@ public class ClusterMetadata
inProgressSequences,
consensusMigrationState,
extensions,
accordStaleReplicas),
accordStaleReplicas,
cmsMembership),
ImmutableSet.copyOf(modifiedKeys));
}
@ -852,7 +881,8 @@ public class ClusterMetadata
inProgressSequences,
consensusMigrationState,
extensions,
accordStaleReplicas);
accordStaleReplicas,
cmsMembership);
}
@Override
@ -871,6 +901,7 @@ public class ClusterMetadata
", inProgressSequences=" + inProgressSequences +
", consensusMigrationState=" + consensusMigrationState +
", extensions=" + extensions +
", cmsMembership=" + cmsMembership +
", modifiedKeys=" + modifiedKeys +
'}';
}
@ -966,6 +997,9 @@ public class ClusterMetadata
", placements=" + placements +
", lockedRanges=" + lockedRanges +
", consensusMigrationState=" + lockedRanges +
", inProgressSequences=" + inProgressSequences +
", extensions=" + extensions +
", cmsMembership=" + cmsMembership +
'}';
}
@ -994,7 +1028,8 @@ public class ClusterMetadata
inProgressSequences.equals(that.inProgressSequences) &&
consensusMigrationState.equals(that.consensusMigrationState) &&
accordStaleReplicas.equals(that.accordStaleReplicas) &&
extensions.equals(that.extensions);
extensions.equals(that.extensions) &&
cmsMembership.equals(that.cmsMembership);
}
private static final Logger logger = LoggerFactory.getLogger(ClusterMetadata.class);
@ -1037,12 +1072,16 @@ public class ClusterMetadata
{
logger.warn("Extensions differ: {} != {}", extensions, other.extensions);
}
if (!cmsMembership.equals(other.cmsMembership))
{
logger.warn("CMS Membership differ: {} != {}", cmsMembership, other.cmsMembership);
}
}
@Override
public int hashCode()
{
return Objects.hash(epoch, schema, directory, tokenMap, placements, accordFastPath, lockedRanges, inProgressSequences, consensusMigrationState, accordStaleReplicas, extensions);
return Objects.hash(epoch, schema, directory, tokenMap, placements, accordFastPath, lockedRanges, inProgressSequences, consensusMigrationState, accordStaleReplicas, extensions, cmsMembership);
}
public static ClusterMetadata current()
@ -1132,6 +1171,8 @@ public class ClusterMetadata
assert key.valueType.isInstance(value);
value.serialize(out, version);
}
if (version.isAtLeast(Version.V9))
CMSMembership.serializer.serialize(metadata.cmsMembership, out, version);
}
@Override
@ -1188,6 +1229,11 @@ public class ClusterMetadata
value.deserialize(in, version);
extensions.put(key, value);
}
CMSMembership cmsMembership = CMSMembership.EMPTY;
if (version.isAtLeast(Version.V9))
cmsMembership = CMSMembership.serializer.deserialize(in, version);
return new ClusterMetadata(clusterIdentifier,
epoch,
partitioner,
@ -1200,7 +1246,8 @@ public class ClusterMetadata
ips,
consensusMigrationState,
extensions,
staleReplicas);
staleReplicas,
cmsMembership);
}
private DistributedSchema deduplicateReplicationParams(DistributedSchema schema, DataPlacements placements)
@ -1248,6 +1295,9 @@ public class ClusterMetadata
size += LockedRanges.serializer.serializedSize(metadata.lockedRanges, version) +
InProgressSequences.serializer.serializedSize(metadata.inProgressSequences, version);
if (version.isAtLeast(Version.V9))
size += CMSMembership.serializer.serializedSize(metadata.cmsMembership, version);
return size;
}

View File

@ -327,14 +327,15 @@ public class ClusterMetadataService
DatabaseDescriptor.getPartitioner(),
new DistributedSchema(keyspaces),
Directory.EMPTY,
new TokenMap(DatabaseDescriptor.getPartitioner()),
DataPlacements.empty(),
AccordFastPath.EMPTY,
LockedRanges.EMPTY,
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
Collections.emptyMap(),
AccordStaleReplicas.EMPTY);
new TokenMap(DatabaseDescriptor.getPartitioner()),
DataPlacements.empty(),
AccordFastPath.EMPTY,
LockedRanges.EMPTY,
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
Collections.emptyMap(),
AccordStaleReplicas.EMPTY,
CMSMembership.EMPTY);
LocalLog.LogSpec logSpec = LocalLog.logSpec()
@ -360,6 +361,24 @@ public class ClusterMetadataService
ClusterMetadataService.setInstance(cms);
}
@SuppressWarnings("resource")
public static void initializeForClients()
{
if (instance != null)
return;
ClusterMetadataService.setInstance(StubClusterMetadataService.forClientTools());
}
public static void initializeForClients(DistributedSchema initialSchema)
{
if (instance != null)
return;
ClusterMetadataService.setInstance(StubClusterMetadataService.forClientTools(initialSchema));
}
/*
* Hook to be executed when the LocalLog is bootstrapped with the PreInitialize transformation. This is done on
* the first CMS member to set up the initial replication and data placements for the metadata keyspace.
@ -391,25 +410,8 @@ public class ClusterMetadataService
};
}
// otherwise, this is a noop.
return preInit -> {};
}
@SuppressWarnings("resource")
public static void initializeForClients()
{
if (instance != null)
return;
ClusterMetadataService.setInstance(StubClusterMetadataService.forClientTools());
}
public static void initializeForClients(DistributedSchema initialSchema)
{
if (instance != null)
return;
ClusterMetadataService.setInstance(StubClusterMetadataService.forClientTools(initialSchema));
return preInit -> {
};
}
public boolean isCurrentMember(InetAddressAndPort peer)

View File

@ -184,7 +184,8 @@ public class StubClusterMetadataService extends ClusterMetadataService
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
ImmutableMap.of(),
AccordStaleReplicas.EMPTY);
AccordStaleReplicas.EMPTY,
CMSMembership.EMPTY);
}
return new StubClusterMetadataService(new UniformRangePlacement(),
snapshots != null ? snapshots : MetadataSnapshots.NO_OP,

View File

@ -58,6 +58,7 @@ import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.service.accord.topology.AccordFastPath;
import org.apache.cassandra.service.accord.topology.AccordStaleReplicas;
import org.apache.cassandra.service.consensus.migration.ConsensusMigrationState;
import org.apache.cassandra.tcm.CMSMembership;
import org.apache.cassandra.tcm.ClusterMetadata;
import org.apache.cassandra.tcm.Epoch;
import org.apache.cassandra.tcm.MultiStepOperation;
@ -306,7 +307,8 @@ public class GossipHelper
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
Collections.emptyMap(),
AccordStaleReplicas.EMPTY);
AccordStaleReplicas.EMPTY,
CMSMembership.EMPTY);
}
public static ClusterMetadata fromEndpointStates(DistributedSchema schema, Map<InetAddressAndPort, EndpointState> epStates)
@ -396,7 +398,8 @@ public class GossipHelper
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
extensions,
AccordStaleReplicas.EMPTY);
AccordStaleReplicas.EMPTY,
CMSMembership.EMPTY);
DataPlacements placements = new UniformRangePlacement().calculatePlacements(Epoch.UPGRADE_GOSSIP,
forPlacementCalculation,
schema.getKeyspaces());
@ -411,7 +414,8 @@ public class GossipHelper
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
extensions,
AccordStaleReplicas.EMPTY);
AccordStaleReplicas.EMPTY,
CMSMembership.EMPTY);
}
public static boolean isValidForClusterMetadata(Map<InetAddressAndPort, EndpointState> epstates)

View File

@ -36,7 +36,7 @@ import static org.apache.cassandra.db.TypeSizes.sizeofUnsignedVInt;
public class NodeVersion implements Comparable<NodeVersion>
{
public static final Serializer serializer = new Serializer();
public static final Version CURRENT_METADATA_VERSION = Version.V8;
public static final Version CURRENT_METADATA_VERSION = Version.V9;
public static final NodeVersion CURRENT = new NodeVersion(new CassandraVersion(FBUtilities.getReleaseVersionString()), CURRENT_METADATA_VERSION);
private static final CassandraVersion SINCE_VERSION = CassandraVersion.CASSANDRA_5_1;

View File

@ -38,13 +38,13 @@ public enum Version
*/
V0(0),
/**
* - Moved Partitioner in ClusterMetadata serializer to be the first field
* - Added a counter to Directory serializer to keep track of NodeIds
* - Moved Partitioner in ClusterMetadata serializer to be the first field
* - Added a counter to Directory serializer to keep track of NodeIds
*/
V1(1),
/**
* - Added version to PlacementForRange serializer
* - Serialize MemtableParams when serializing TableParams
* - Added version to PlacementForRange serializer
* - Serialize MemtableParams when serializing TableParams
*/
V2(2),
/**
@ -78,6 +78,10 @@ public enum Version
* - Comments and security labels for schema elements (keyspaces, tables, columns, UDTs, and UDT fields)
*/
V8(8),
/**
* - DataPlacements don't include MetaStrategy, replaced by ClusterMetadata.CMSMembership
*/
V9(9),
UNKNOWN(Integer.MAX_VALUE);
@ -95,6 +99,7 @@ public enum Version
}
private final int version;
Version(int version)
{
this.version = version;

View File

@ -64,6 +64,7 @@ import org.apache.cassandra.service.accord.topology.AccordFastPath;
import org.apache.cassandra.service.accord.topology.AccordStaleReplicas;
import org.apache.cassandra.service.consensus.migration.ConsensusMigrationState;
import org.apache.cassandra.tcm.AtomicLongBackedProcessor;
import org.apache.cassandra.tcm.CMSMembership;
import org.apache.cassandra.tcm.ClusterMetadata;
import org.apache.cassandra.tcm.ClusterMetadataService;
import org.apache.cassandra.tcm.Commit;
@ -169,7 +170,8 @@ public class ClusterMetadataTestHelper
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
ImmutableMap.of(),
AccordStaleReplicas.EMPTY);
AccordStaleReplicas.EMPTY,
CMSMembership.EMPTY);
}
public static ClusterMetadata minimalForTesting(IPartitioner partitioner)

View File

@ -36,6 +36,7 @@ import org.apache.cassandra.schema.DistributedSchema;
import org.apache.cassandra.service.accord.topology.AccordFastPath;
import org.apache.cassandra.service.accord.topology.AccordStaleReplicas;
import org.apache.cassandra.service.consensus.migration.ConsensusMigrationState;
import org.apache.cassandra.tcm.CMSMembership;
import org.apache.cassandra.tcm.ClusterMetadata;
import org.apache.cassandra.tcm.Epoch;
import org.apache.cassandra.tcm.membership.Directory;
@ -96,7 +97,8 @@ public class MetaStrategyTest
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
ImmutableMap.of(),
AccordStaleReplicas.EMPTY);
AccordStaleReplicas.EMPTY,
CMSMembership.EMPTY);
}
@Test

View File

@ -55,6 +55,7 @@ import org.apache.cassandra.schema.SchemaConstants;
import org.apache.cassandra.service.accord.topology.AccordFastPath;
import org.apache.cassandra.service.accord.topology.AccordStaleReplicas;
import org.apache.cassandra.service.consensus.migration.ConsensusMigrationState;
import org.apache.cassandra.tcm.CMSMembership;
import org.apache.cassandra.tcm.ClusterMetadata;
import org.apache.cassandra.tcm.ClusterMetadataService;
import org.apache.cassandra.tcm.Epoch;
@ -110,7 +111,8 @@ public class CMSOfflineToolTest extends OfflineToolUtils
InProgressSequences.EMPTY,
ConsensusMigrationState.EMPTY,
ImmutableMap.of(),
AccordStaleReplicas.EMPTY);
AccordStaleReplicas.EMPTY,
CMSMembership.EMPTY);
}
@Before

View File

@ -140,6 +140,7 @@ import org.apache.cassandra.service.accord.topology.SimpleFastPathStrategy;
import org.apache.cassandra.service.accord.topology.UpFastPathStrategy;
import org.apache.cassandra.service.consensus.TransactionalMode;
import org.apache.cassandra.service.consensus.migration.ConsensusMigrationState;
import org.apache.cassandra.tcm.CMSMembership;
import org.apache.cassandra.tcm.ClusterMetadata;
import org.apache.cassandra.tcm.Epoch;
import org.apache.cassandra.tcm.extensions.ExtensionKey;
@ -1955,7 +1956,8 @@ public final class CassandraGenerators
ConsensusMigrationState consensusMigrationState = ConsensusMigrationState.EMPTY;
Map<ExtensionKey<?, ?>, ExtensionValue<?>> extensions = ImmutableMap.of();
AccordStaleReplicas accordStaleReplicas = accordStaleReplicasGen.generate(rnd);
return new ClusterMetadata(epoch, partitioner, schema, directory, tokenMap, placements, accordFastPath, lockedRanges, inProgressSequences, consensusMigrationState, extensions, accordStaleReplicas);
CMSMembership cms = CMSMembership.EMPTY;
return new ClusterMetadata(epoch, partitioner, schema, directory, tokenMap, placements, accordFastPath, lockedRanges, inProgressSequences, consensusMigrationState, extensions, accordStaleReplicas, cms);
};
}
}