Class ClientState
- java.lang.Object
-
- org.apache.cassandra.service.ClientState
-
public class ClientState extends java.lang.Object
State related to a client connection.
-
-
Field Summary
Fields Modifier and Type Field Description boolean
isInternal
static com.google.common.collect.ImmutableSet<IResource>
PROTECTED_AUTH_RESOURCES
static com.google.common.collect.ImmutableSet<IResource>
READABLE_SYSTEM_RESOURCES
-
Constructor Summary
Constructors Modifier Constructor Description protected
ClientState(java.net.InetSocketAddress remoteAddress)
protected
ClientState(ClientState source)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description ClientState
cloneWithKeyspaceIfSet(java.lang.String keyspace)
Clone this ClientState object, but use the provided keyspace instead of the keyspace in this ClientState object.void
ensureAllKeyspacesPermission(Permission perm)
void
ensureAllTablesPermission(java.lang.String keyspace, Permission perm)
void
ensureIsSuperuser(java.lang.String message)
void
ensureKeyspacePermission(java.lang.String keyspace, Permission perm)
void
ensureNotAnonymous()
void
ensurePermission(Permission perm, IResource resource)
void
ensurePermission(Permission permission, Function function)
void
ensureTablePermission(java.lang.String keyspace, java.lang.String table, Permission perm)
void
ensureTablePermission(TableMetadataRef tableRef, Permission perm)
void
ensureTablePermission(TableMetadata table, Permission perm)
static ClientState
forExternalCalls(java.net.SocketAddress remoteAddress)
static ClientState
forInternalCalls()
static ClientState
forInternalCalls(java.lang.String keyspace)
java.util.Optional<java.util.Map<java.lang.String,java.lang.String>>
getClientOptions()
static QueryHandler
getCQLQueryHandler()
java.util.Optional<java.lang.String>
getDriverName()
java.util.Optional<java.lang.String>
getDriverVersion()
java.lang.String
getKeyspace()
static long
getLastTimestampMicros()
java.lang.String
getRawKeyspace()
java.net.InetSocketAddress
getRemoteAddress()
static long
getTimestamp()
This clock guarantees that updates for the same ClientState will be ordered in the sequence seen, even if multiple updates happen in the same millisecond.static long
getTimestampForPaxos(long minUnixMicros)
Returns a timestamp suitable for paxos given the timestamp of the last known commit (or in progress update).AuthenticatedUser
getUser()
boolean
hasTablePermission(TableMetadata table, Permission perm)
boolean
isOrdinaryUser()
Checks if this user is an ordinary user (not a super or system user).boolean
isSuper()
Checks if this user is a super user.boolean
isSystem()
Checks if the user is the system user.void
login(AuthenticatedUser user)
Attempts to login the given user.static void
resetLastTimestamp(long nowMillis)
void
setClientOptions(java.util.Map<java.lang.String,java.lang.String> clientOptions)
void
setDriverName(java.lang.String driverName)
void
setDriverVersion(java.lang.String driverVersion)
void
setKeyspace(java.lang.String ks)
void
validateLogin()
void
warnAboutUseWithPreparedStatements(MD5Digest statementId, java.lang.String preparedKeyspace)
-
-
-
Constructor Detail
-
ClientState
protected ClientState(java.net.InetSocketAddress remoteAddress)
-
ClientState
protected ClientState(ClientState source)
-
-
Method Detail
-
resetLastTimestamp
public static void resetLastTimestamp(long nowMillis)
-
forInternalCalls
public static ClientState forInternalCalls()
- Returns:
- a ClientState object for internal C* calls (not limited by any kind of auth).
-
forInternalCalls
public static ClientState forInternalCalls(java.lang.String keyspace)
-
forExternalCalls
public static ClientState forExternalCalls(java.net.SocketAddress remoteAddress)
- Returns:
- a ClientState object for external clients (native protocol users).
-
cloneWithKeyspaceIfSet
public ClientState cloneWithKeyspaceIfSet(java.lang.String keyspace)
Clone this ClientState object, but use the provided keyspace instead of the keyspace in this ClientState object.- Returns:
- a new ClientState object if the keyspace argument is non-null. Otherwise do not clone and return this ClientState object.
-
getTimestamp
public static long getTimestamp()
This clock guarantees that updates for the same ClientState will be ordered in the sequence seen, even if multiple updates happen in the same millisecond.
-
getTimestampForPaxos
public static long getTimestampForPaxos(long minUnixMicros)
Returns a timestamp suitable for paxos given the timestamp of the last known commit (or in progress update).Paxos ensures that the timestamp it uses for commits respects the serial order of those commits. It does so by having each replica reject any proposal whose timestamp is not strictly greater than the last proposal it accepted. So in practice, which timestamp we use for a given proposal doesn't affect correctness but it does affect the chance of making progress (if we pick a timestamp lower than what has been proposed before, our new proposal will just get rejected).
As during the prepared phase replica send us the last propose they accepted, a first option would be to take the maximum of those last accepted proposal timestamp plus 1 (and use a default value, say 0, if it's the first known proposal for the partition). This would most work (giving commits the timestamp 0, 1, 2, ... in the order they are commited) up to 2 important caveats: 1) it would give a very poor experience when Paxos and non-Paxos updates are mixed in the same partition, since paxos operations wouldn't be using microseconds timestamps. And while you shouldn't theoretically mix the 2 kind of operations, this would still be pretty unintuitive. And what if you started writing normal updates and realize later you should switch to Paxos to enforce a property you want? 2) this wouldn't actually be safe due to the expiration set on the Paxos state table.
So instead, we initially chose to use the current time in microseconds as for normal update. Which works in general but mean that clock skew creates unavailability periods for Paxos updates (either a node has his clock in the past and he may no be able to get commit accepted until its clock catch up, or a node has his clock in the future and then once one of its commit his accepted, other nodes ones won't be until they catch up). This is ok for small clock skew (few ms) but can be pretty bad for large one.
Hence our current solution: we mix both approaches. That is, we compare the timestamp of the last known accepted proposal and the local time. If the local time is greater, we use it, thus keeping paxos timestamps locked to the current time in general (making mixing Paxos and non-Paxos more friendly, and behaving correctly when the paxos state expire (as long as your maximum clock skew is lower than the Paxos state expiration time)). Otherwise (the local time is lower than the last proposal, meaning that this last proposal was done with a clock in the future compared to the local one), we use the last proposal timestamp plus 1, ensuring progress.
- Parameters:
minUnixMicros
- the max timestamp of the last proposal accepted by replica having responded to the prepare phase of the paxos round this is for. In practice, that's the minimum timestamp this method may return.- Returns:
- a timestamp suitable for a Paxos proposal (using the reasoning described above). Note that
contrarily to the
getTimestamp()
method, the return value is not guaranteed to be unique (nor monotonic) across calls since it can return it's argument (so if the same argument is passed multiple times, it may be returned multiple times). Note that we still ensure Paxos "ballot" are unique (for different proposal) by (securely) randomizing the non-timestamp part of the UUID.
-
getLastTimestampMicros
public static long getLastTimestampMicros()
-
getDriverName
public java.util.Optional<java.lang.String> getDriverName()
-
getDriverVersion
public java.util.Optional<java.lang.String> getDriverVersion()
-
getClientOptions
public java.util.Optional<java.util.Map<java.lang.String,java.lang.String>> getClientOptions()
-
setDriverName
public void setDriverName(java.lang.String driverName)
-
setDriverVersion
public void setDriverVersion(java.lang.String driverVersion)
-
setClientOptions
public void setClientOptions(java.util.Map<java.lang.String,java.lang.String> clientOptions)
-
getCQLQueryHandler
public static QueryHandler getCQLQueryHandler()
-
getRemoteAddress
public java.net.InetSocketAddress getRemoteAddress()
-
getRawKeyspace
public java.lang.String getRawKeyspace()
-
getKeyspace
public java.lang.String getKeyspace() throws InvalidRequestException
- Throws:
InvalidRequestException
-
setKeyspace
public void setKeyspace(java.lang.String ks)
-
login
public void login(AuthenticatedUser user)
Attempts to login the given user.
-
ensureAllKeyspacesPermission
public void ensureAllKeyspacesPermission(Permission perm)
-
ensureKeyspacePermission
public void ensureKeyspacePermission(java.lang.String keyspace, Permission perm)
-
ensureAllTablesPermission
public void ensureAllTablesPermission(java.lang.String keyspace, Permission perm)
-
ensureTablePermission
public void ensureTablePermission(java.lang.String keyspace, java.lang.String table, Permission perm)
-
ensureTablePermission
public void ensureTablePermission(TableMetadataRef tableRef, Permission perm)
-
ensureTablePermission
public void ensureTablePermission(TableMetadata table, Permission perm)
-
hasTablePermission
public boolean hasTablePermission(TableMetadata table, Permission perm)
-
ensurePermission
public void ensurePermission(Permission perm, IResource resource)
-
ensurePermission
public void ensurePermission(Permission permission, Function function)
-
validateLogin
public void validateLogin()
-
ensureNotAnonymous
public void ensureNotAnonymous()
-
isOrdinaryUser
public boolean isOrdinaryUser()
Checks if this user is an ordinary user (not a super or system user).- Returns:
true
if this user is an ordinary user,false
otherwise.
-
isSuper
public boolean isSuper()
Checks if this user is a super user.
-
isSystem
public boolean isSystem()
Checks if the user is the system user.- Returns:
true
if this user is the system user,false
otherwise.
-
ensureIsSuperuser
public void ensureIsSuperuser(java.lang.String message)
-
warnAboutUseWithPreparedStatements
public void warnAboutUseWithPreparedStatements(MD5Digest statementId, java.lang.String preparedKeyspace)
-
getUser
public AuthenticatedUser getUser()
-
-