Class CaldavServerQuirkService

java.lang.Object
org.exoplatform.caldav.service.CaldavServerQuirkService

@Service public class CaldavServerQuirkService extends Object
What each CalDAV server has been seen doing, and what its administrator has excused it for.

The list is evidence, not configuration. Before EXO-89771 an operator had to read a log line naming a property, type it into exo.agenda.caldav.mirror.ignoredProperties or ...droppedProperties, and restart — and both settings were global, so naming CONFERENCE for BlueMind also blinded a well-behaved server to a genuinely deleted conference link. The sweep already knows exactly what diverges on each server every five minutes; this records it per server, so the drawer can offer what that server actually does and the administrator can choose from evidence instead of guessing.

Where it is recorded, and why there. One column on the server's own row, holding a bounded rolling summary — see ServerQuirkSummary for the format. It survives a restart, because an empty drawer after one is an empty drawer exactly when somebody is investigating; it stays cheap, because it is one bounded row per server rather than a row per copy per divergence; and it costs no extra query, because the drawer already fetches the registration.

Accumulated in memory, flushed at most once per sweep per server. The sweep runs per user, so a deployment with five hundred accounts on one server would otherwise write that row five hundred times every five minutes. The counts are therefore approximate by construction — a crash loses at most one interval — which is all they need to be: they answer "does this server always do this, or did it happen once", and no decision is made from an exact value.

  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    org.exoplatform.caldav.model.CaldavServer
    decorate(org.exoplatform.caldav.model.CaldavServer server)
    Fills in what the drawer needs to show a registration's behaviours: the lists actually in force for it, and which observed behaviour each of them excuses.
    void
    forget(long serverId)
    Forgets what has been seen on a server but not yet written, so a deleted registration leaves nothing behind to be written against an identifier a later row may reuse.
    int
    The bound the stored summary is kept within, named here so a caller can reason about it without reaching into the codec.
    void
    observe(Long serverId, List<org.exoplatform.caldav.model.IcsDivergence> divergences)
    Records what one comparison found a server doing to one copy.
    void
    settle(Long serverId)
    Gives one server's summary its chance to be written and pruned, whether or not anything diverged.

    Methods inherited from class java.lang.Object

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

    • CaldavServerQuirkService

      public CaldavServerQuirkService()
  • Method Details

    • observe

      public void observe(Long serverId, List<org.exoplatform.caldav.model.IcsDivergence> divergences)
      Records what one comparison found a server doing to one copy.

      Called for every judged copy, including the ones judged equivalent — a divergence the administrator has already excused is still reported by the comparison and still counted here, or the very behaviour somebody ticked would disappear from the list they ticked it in, and nobody could untick it or see what a deployment-wide property is already hiding.

      Parameters:
      serverId - the registration the account is connected through, may be null for an account predating the registry — nothing is recorded for one, since there is no row to record it against
      divergences - what the comparison saw, one entry per property
    • settle

      public void settle(Long serverId)
      Gives one server's summary its chance to be written and pruned, whether or not anything diverged.

      The cleanup must not depend on the problem still happening. Pruning used to ride on the write, the write on a pending count, and the count on a divergence — and a copy that agrees with what eXo writes moves no ETag, so a converged account never even reaches the comparison. An account that is healthy, which is exactly the account whose stale records need clearing, therefore never wrote its row at all. That is the same failure one level down from the one supersession-by-excusal fixed: the mechanism could only act while the fault it cleans up after was still occurring.

      So the pass calls this once per sweep for the server it swept, with nothing to report. The throttle below is what keeps that cheap — one read per server per interval, however many accounts are connected to it — and the write happens only when the summary actually changes, so a settled row stays untouched rather than being rewritten every five minutes for ever.

      Parameters:
      serverId - the registration the pass ran against, may be null for an account predating the registry — there is no row to settle
    • decorate

      public org.exoplatform.caldav.model.CaldavServer decorate(org.exoplatform.caldav.model.CaldavServer server)
      Fills in what the drawer needs to show a registration's behaviours: the lists actually in force for it, and which observed behaviour each of them excuses.

      The lists come back resolved, and that is deliberate. A registration that has never been asked carries null and the deployment-wide property decides for it; what the drawer shows — and therefore what it saves back — is what is in force. So the first save of a server writes today's deployment-wide list into its row and the row owns it from then on, which is the honest reading of "this server's settings": an administrator looking at a ticked box must be able to untick it, and a box ticked by a property file they cannot see from here is not a setting they can act on.

      Parameters:
      server - the registration to enrich, may be null
      Returns:
      the same registration, enriched; null when null was given
    • forget

      public void forget(long serverId)
      Forgets what has been seen on a server but not yet written, so a deleted registration leaves nothing behind to be written against an identifier a later row may reuse.
      Parameters:
      serverId - technical identifier of the registration
    • getMaxObservedQuirks

      public int getMaxObservedQuirks()
      The bound the stored summary is kept within, named here so a caller can reason about it without reaching into the codec.
      Returns:
      how many behaviours one server's summary keeps