org.apache.cassandra.service

## Class ClientState

- java.lang.Object
- - org.apache.cassandra.service.ClientState

- Direct Known Subclasses:
    ThriftClientState

      public class ClientState
      extends java.lang.Object

  State related to a client connection.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static CassandraVersion` | `DEFAULT_CQL_VERSION`
    `boolean` | `isInternal`

  - ### Constructor Summary

    Constructors
    Modifier | Constructor and Description
    --- | ---
    `protected` | `ClientState(java.net.InetSocketAddress remoteAddress)`

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `ensureHasPermission(Permission permission, Function function)`
    `void` | `ensureHasPermission(Permission perm, IResource resource)`
    `void` | `ensureIsSuper(java.lang.String message)`
    `void` | `ensureNotAnonymous()`
    `static ClientState` | `forExternalCalls(java.net.SocketAddress remoteAddress)`
    `static ClientState` | `forInternalCalls()`
    `static QueryHandler` | `getCQLQueryHandler()`
    `static CassandraVersion[]` | `getCQLSupportedVersion()`
    `java.lang.String` | `getKeyspace()`
    `java.lang.String` | `getRawKeyspace()`
    `java.net.InetSocketAddress` | `getRemoteAddress()`
    `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.
    `long` | `getTimestampForPaxos(long minTimestampToUse)` Returns a timestamp suitable for paxos given the timestamp of the last known commit (or in progress update).
    `AuthenticatedUser` | `getUser()`
    `void` | `hasAllKeyspacesAccess(Permission perm)`
    `void` | `hasColumnFamilyAccess(java.lang.String keyspace, java.lang.String columnFamily, Permission perm)`
    `void` | `hasKeyspaceAccess(java.lang.String keyspace, Permission perm)`
    `void` | `login(AuthenticatedUser user)` Attempts to login the given user.
    `void` | `setKeyspace(java.lang.String ks)`
    `void` | `validateLogin()`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### DEFAULT_CQL_VERSION

          public static final CassandraVersion DEFAULT_CQL_VERSION

    - #### isInternal

          public final boolean isInternal

  - ### Constructor Detail

    - #### ClientState

          protected ClientState(java.net.InetSocketAddress remoteAddress)

  - ### Method Detail

    - #### forInternalCalls

          public static ClientState forInternalCalls()

      Returns:
        a ClientState object for internal C* calls (not limited by any kind of auth).

    - #### forExternalCalls

          public static ClientState forExternalCalls(java.net.SocketAddress remoteAddress)

      Returns:
        a ClientState object for external clients (thrift/native protocol users).

    - #### getTimestamp

          public 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 long getTimestampForPaxos(long minTimestampToUse)

      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:
        `minTimestampToUse` - 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.

    - #### 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)
                           throws InvalidRequestException

      Throws:
        `InvalidRequestException`

    - #### login

          public void login(AuthenticatedUser user)
                     throws AuthenticationException

      Attempts to login the given user.
      Throws:
        `AuthenticationException`

    - #### hasAllKeyspacesAccess

          public void hasAllKeyspacesAccess(Permission perm)
                                     throws UnauthorizedException

      Throws:
        `UnauthorizedException`

    - #### hasKeyspaceAccess

          public void hasKeyspaceAccess(java.lang.String keyspace,
                                        Permission perm)
                                 throws UnauthorizedException,
                                        InvalidRequestException

      Throws:
        `UnauthorizedException`
        `InvalidRequestException`

    - #### hasColumnFamilyAccess

          public void hasColumnFamilyAccess(java.lang.String keyspace,
                                            java.lang.String columnFamily,
                                            Permission perm)
                                     throws UnauthorizedException,
                                            InvalidRequestException

      Throws:
        `UnauthorizedException`
        `InvalidRequestException`

    - #### ensureHasPermission

          public void ensureHasPermission(Permission perm,
                                          IResource resource)
                                   throws UnauthorizedException

      Throws:
        `UnauthorizedException`

    - #### ensureHasPermission

          public void ensureHasPermission(Permission permission,
                                          Function function)

    - #### validateLogin

          public void validateLogin()
                             throws UnauthorizedException

      Throws:
        `UnauthorizedException`

    - #### ensureNotAnonymous

          public void ensureNotAnonymous()
                                  throws UnauthorizedException

      Throws:
        `UnauthorizedException`

    - #### ensureIsSuper

          public void ensureIsSuper(java.lang.String message)
                             throws UnauthorizedException

      Throws:
        `UnauthorizedException`

    - #### getUser

          public AuthenticatedUser getUser()

    - #### getCQLSupportedVersion

          public static CassandraVersion[] getCQLSupportedVersion()

Copyright © 2018 The Apache Software Foundation