Class CaldavPendingSubscriptionStorage

java.lang.Object
org.exoplatform.caldav.storage.CaldavPendingSubscriptionStorage

@Component public class CaldavPendingSubscriptionStorage extends Object
Maps the subscription changes eXo owes colleagues' BlueMind accounts between their JPA entity and the service-layer DTO (EXO-90277).

No business logic: which changes are owed, how hard to try and when to stop belong to the service. What lives here is the mechanical part — that an obligation is one per colleague, server and container, so recording the same one twice replaces it rather than queueing it, and that renewing it resets the attempt count because a new instruction deserves its own patience. The shape is CaldavPendingPushStorage's, keyed by the sharee rather than by a mapping row.

  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    abandoned(long id, org.exoplatform.caldav.model.PendingSubscriptionKind kind, int maxAttempts)
    Records that an obligation is given up on, without counting toward the bound first, unless the row has been renewed with the other change since it was read.
    List<org.exoplatform.caldav.model.PendingSubscription>
    attemptable(int maxAttempts, int limit)
    What is owed to anybody and still worth attempting, oldest first.
    List<org.exoplatform.caldav.model.PendingSubscription>
    attemptable(long userIdentityId, int maxAttempts, int limit)
    What one colleague is owed and is still worth attempting, oldest first.
    org.exoplatform.caldav.model.PendingSubscription
    owe(long userIdentityId, long serverId, String containerUid, org.exoplatform.caldav.model.PendingSubscriptionKind kind)
    Records that a colleague's account owes a change, replacing whatever was owed about the same container before.
    void
    refused(long id, org.exoplatform.caldav.model.PendingSubscriptionKind kind)
    Records that one more attempt was refused, unless the row has been renewed with the other change since it was read.
    void
    settledIfStillAsking(long userIdentityId, long serverId, String containerUid, org.exoplatform.caldav.model.PendingSubscriptionKind kind)
    Forgets what was owed about one container, because that change landed — and only if the row is still asking for it.
    void
    settledWhateverWasOwed(long userIdentityId, long serverId, String containerUid)
    Forgets whatever was owed about one container, because the caller has just decided and applied the newest instruction about it.
    boolean
    stillAsking(long id, org.exoplatform.caldav.model.PendingSubscriptionKind kind)
    Whether an obligation still stands as it was read: the row is there and still asks for the same change.

    Methods inherited from class java.lang.Object

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

    • CaldavPendingSubscriptionStorage

      public CaldavPendingSubscriptionStorage()
  • Method Details

    • owe

      @Transactional public org.exoplatform.caldav.model.PendingSubscription owe(long userIdentityId, long serverId, String containerUid, org.exoplatform.caldav.model.PendingSubscriptionKind kind)
      Records that a colleague's account owes a change, replacing whatever was owed about the same container before.

      Replacing, not queueing: the latest instruction describes the account. A revoke recorded while a subscribe is still pending turns the row into a removal — harmless when nothing was ever subscribed, and the only right answer when it was. The lookup before the write is a check-then-act and the unique index is what settles two writers: the loser's insert is refused and its caller says so.

      Parameters:
      userIdentityId - the sharee
      serverId - the server key
      containerUid - the container uid
      kind - whether to subscribe or unsubscribe
      Returns:
      the obligation as it now stands
    • settledWhateverWasOwed

      @Transactional public void settledWhateverWasOwed(long userIdentityId, long serverId, String containerUid)
      Forgets whatever was owed about one container, because the caller has just decided and applied the newest instruction about it.

      For the caller who cannot be stale — the grant and the revoke. They decide the instruction in the same call, inside the share service's stripe lock and after the access list was read back, and owe(long, long, java.lang.String, org.exoplatform.caldav.model.PendingSubscriptionKind) — the only method here that records an instruction, as opposed to settling or counting one — has a single call site, theirs. So whatever row stands for the container is older than what they just did, whichever kind it asks for, and leaving it would have the drain later re-apply an instruction the owner has already replaced. A pending SUBSCRIBE surviving a landed revoke is the worst of those: the drain re-subscribes the colleague to a calendar whose access entry is gone — the dangling subscription this feature exists to prevent — and BlueMind's subscribe makes no access check, so it lands.

      By the colleague, server and container rather than by the row's own identifier, because owe(long, long, java.lang.String, org.exoplatform.caldav.model.PendingSubscriptionKind) reuses the row and an id says nothing about which instruction it now carries.

      Parameters:
      userIdentityId - the sharee
      serverId - the server key
      containerUid - the container uid
    • settledIfStillAsking

      @Transactional public void settledIfStillAsking(long userIdentityId, long serverId, String containerUid, org.exoplatform.caldav.model.PendingSubscriptionKind kind)
      Forgets what was owed about one container, because that change landed — and only if the row is still asking for it.

      For the caller who can be stale — the drain, and only the drain. It reads its rows once and then spends a round trip on each, inside a session that costs a login and a logout. On one node the obligation's lock keeps a revoke out of that window; on another node it does not, and a revoke there records an UNSUBSCRIBE over the pending SUBSCRIBE — the same row, by the one-row-per-container rule — while the drain lands its now-stale SUBSCRIBE. Deleting by container alone would strike off the removal nobody has made yet. With the kind matched in the delete itself, one statement, the removal survives its predecessor's success and the next drain makes it.

      The guard belongs here and only here: at the grant and the revoke it could only ever refuse a delete that was right, which is why settledWhateverWasOwed(long, long, String) exists beside it.

      Parameters:
      userIdentityId - the sharee
      serverId - the server key
      containerUid - the container uid
      kind - the change that landed; a row now asking for the other one is left alone
    • stillAsking

      public boolean stillAsking(long id, org.exoplatform.caldav.model.PendingSubscriptionKind kind)
      Whether an obligation still stands as it was read: the row is there and still asks for the same change.
      Parameters:
      id - the obligation
      kind - the change it was read with
      Returns:
      true when it still asks for it
    • refused

      @Transactional public void refused(long id, org.exoplatform.caldav.model.PendingSubscriptionKind kind)
      Records that one more attempt was refused, unless the row has been renewed with the other change since it was read.
      Parameters:
      id - the obligation
      kind - the change that was refused
    • abandoned

      @Transactional public void abandoned(long id, org.exoplatform.caldav.model.PendingSubscriptionKind kind, int maxAttempts)
      Records that an obligation is given up on, without counting toward the bound first, unless the row has been renewed with the other change since it was read.
      Parameters:
      id - the obligation
      kind - the change given up on
      maxAttempts - the configured bound, written whole
    • attemptable

      public List<org.exoplatform.caldav.model.PendingSubscription> attemptable(int maxAttempts, int limit)
      What is owed to anybody and still worth attempting, oldest first.
      Parameters:
      maxAttempts - how many refusals are argued with before stopping
      limit - how many to take in one pass
      Returns:
      the obligations to attempt now, possibly none
    • attemptable

      public List<org.exoplatform.caldav.model.PendingSubscription> attemptable(long userIdentityId, int maxAttempts, int limit)
      What one colleague is owed and is still worth attempting, oldest first.
      Parameters:
      userIdentityId - the sharee
      maxAttempts - how many refusals are argued with before stopping
      limit - how many to take in one pass
      Returns:
      the obligations to attempt now, possibly none