Class BlueMindSessionCache

java.lang.Object
org.exoplatform.caldav.client.bluemind.BlueMindSessionCache

@Component public class BlueMindSessionCache extends Object
The BlueMind REST session each account currently holds, kept in this node's own memory for a few minutes so that a burst of reads costs one login rather than one login per read (EXO-90397).

Why a session is kept at all. BlueMindRestSession.call(org.exoplatform.caldav.client.CalDavEndpoint, java.util.function.Function<org.exoplatform.caldav.client.bluemind.BlueMindRestSession.Session, T>) used to log in, make its one call and log out — three requests for one answer, measured at 0.2 to 0.4 s each against the demo rig. Every BlueMind REST read this add-on makes paid it: the Share drawer's access list, the subscription listing behind the calendar-owner witness, the ICS import channel. With the technical-account provider it is worse than three, because producing the account's credentials is itself up to two BlueMind calls — the technical login, then the sudo — on a miss of the provider's own store.

Why here, and not in a store. A session key is a live credential that acts as a user, with a lifetime in minutes.

  • Not the database. Persisting it would mean encrypting it under the instance codec key, migrating it and cleaning it up, for a value that expires long before any of that matters.
  • Not the platform's cache layer. Anything registered with the Kernel's CacheService is reachable by name from any other code in the container, and a cache is a thing a deployment may one day replicate. A credential that authenticates one person's mailbox must not travel between nodes, so it lives in a field of this bean and nowhere else.
  • Node-local. Each node mints its own session per account, which costs one login; losing them all on a restart costs one login each. That is the whole price of not replicating a credential.

The key is who the session acts as, field by field. Handed to another account, a session key is not a stale answer — it is somebody else's identity. So the key carries three explicit, equals-compared fields and never a folded hash (BlueMindSessionCache.Key): the declared server, the eXo user the credentials are produced for, and the account those credentials address on that server. The third is what the technical-account provider resolves before it sudoes (BluemindSudoCredentialsProvider#resolveTargetIdentity, the same derivation produce itself uses), so the key says who the session acts as and not merely who asked for it. Two users cannot land on one entry, and one user cannot land on an entry minted for another mailbox.

Bounded in both directions. An entry lives exo.agenda.caldav.bluemind.session.ttlSeconds seconds and there are at most exo.agenda.caldav.bluemind.session.maxAccounts of them; beyond that the session is used but not kept, so the map cannot grow with the user base of an instance nobody sized it for. A session this store declines to keep is closed by the call that opened it — holds(org.exoplatform.caldav.client.bluemind.BlueMindSessionCache.Key, org.exoplatform.caldav.model.BlueMindLogin) is how that call finds out — because nobody will ever present it again and a node above the bound would otherwise leave one live session on BlueMind per call.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final record 
    The account a session belongs to.
  • Constructor Summary

    Constructors
    Constructor
    Description
    BlueMindSessionCache(int ttlSeconds, int maxAccounts)
    The cache Spring builds.
  • Method Summary

    Modifier and Type
    Method
    Description
    A cache that keeps nothing: every call opens its own session and closes it, which is what this add-on did before EXO-90397 and what it still does for an endpoint that cannot be keyed.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • BlueMindSessionCache

      @Autowired public BlueMindSessionCache(@Value("${exo.agenda.caldav.bluemind.session.ttlSeconds:300}") int ttlSeconds, @Value("${exo.agenda.caldav.bluemind.session.maxAccounts:1000}") int maxAccounts)
      The cache Spring builds.
      Parameters:
      ttlSeconds - how long an entry is kept
      maxAccounts - how many accounts are kept at once
  • Method Details

    • unpooled

      public static BlueMindSessionCache unpooled()
      A cache that keeps nothing: every call opens its own session and closes it, which is what this add-on did before EXO-90397 and what it still does for an endpoint that cannot be keyed.
      Returns:
      a cache of no capacity