Class PushNotificationsProps

java.lang.Object
com.iizix.prop.GProp<GProp<?>[]>
com.iizix.prop.PropCnr
com.iizix.prop.push.PushNotificationsProps
All Implemented Interfaces:
EventListener, IGProp<GProp<?>[]>, IPropCnr, IPushSettings, Cloneable

public class PushNotificationsProps extends PropCnr implements IPushSettings
The server-wide Push Notification settings container, i.e. the property container implementation of the IPushSettings configuration contract.

Scope. This container is server-wide: it holds the settings that govern this iiziServer installation's push subsystem as a whole. It is deliberately not an extension of com.iizix.prop.PushProps, which is the per-application push container holding the VAPID key pair and the APNs identities of one iiziApp. The two have different lifetimes, different owners and different editors, and merging them would tie a server restart to an application deployment.

Reading a setting never throws and never returns an out-of-range value. Every accessor of IPushSettings is implemented here by reading the stored value with the inherited typed accessor and then clamping it into the documented range, so a value edited out of range - by an administrator, by a transport error, or by a hand-edited file - can never take the subsystem outside its safe envelope. The bounds are part of the contract, not advice.

Two-tier logging on read. A missing value is the normal path and is silent: the default parameter of the inherited accessor supplies the documented default. A value that is present but unreadable - out of range, or an enum ordinal outside the constant set - returns the safe value and logs, because a bad stored value is evidence of a mis-edit, a bad migration or a transport corruption and must leave a trace. Note that this logs on every read of a corrupt value; callers on a hot path are expected to read a setting once and hold it (the engine builds its admission semaphore from getMaxParallelPush() at start-up and does not re-read it per send).

The setters do not clamp into the setting's range. That clamp is a read-side guarantee and lives in exactly one place, the getter. A setter stores what it is given, so that a value written by an administrator, a transport delta or a loaded XML file is preserved as written and is reported by the getter's log when it is out of range, rather than being silently rewritten on the way in and hidden from the operator who typed it.

But a setter does refuse a value the storage cannot hold, and says so. These are two different ranges and only one of them is policy. The setting's range - say [100, 100000] - is policy, and is enforced on read. The storable range is a property of IntProp, which holds only [IntProp.MIN_VALUE, IntProp.MAX_VALUE] = [-0x1FFFFFFF, 0x1FFFFFFF] because that is what its wire encoding carries. Handing IntProp more than that raises an InternalError from inside the property framework - an Error, which the inherited PropCnr.setInt cannot absorb although its own documentation promises to log a warning and return false. An administrator who types a large number into ServerAdmin must not be answered with that. So an int setter here checks the storable range first and, when the value will not fit, stores nothing, logs a WARNING naming the value that was passed, and returns false - which is exactly the behaviour setInt documents and fails to deliver. Nothing the administrator did not type is ever persisted, the previous value stands, and the evidence names the number they actually entered.

Author:
Christopher Mindus
  • Field Details

    • ATOM

      public static final Atom ATOM
      The atom for the server-wide Push Notification settings container: "$pushNotifications".
  • Constructor Details

    • PushNotificationsProps

      public PushNotificationsProps()
      Creates a Push Notification settings container without name and with a null value.
    • PushNotificationsProps

      public PushNotificationsProps(Atom propertyAtom)
      Creates a Push Notification settings container with the specified name with a null value.
      Parameters:
      propertyAtom - The property atom.
  • Method Details

    • clone

      public PushNotificationsProps clone()
      Creates a clone out of this property.
      Overrides:
      clone in class PropCnr
      Returns:
      The clone of the Push Notification settings container.
    • getMaxParallelPush

      public int getMaxParallelPush()
      Gets the hard ceiling on the number of push notifications that may be in flight at any single moment, clamped into [100, 100000] with the default 1000.
      Specified by:
      getMaxParallelPush in interface IPushSettings
      Returns:
      The maximum number of concurrent in-flight push sends.
    • setMaxParallelPush

      public boolean setMaxParallelPush(int value)
      Sets the hard ceiling on the number of push notifications in flight at any single moment.

      The value is stored as given: see the class documentation for why the setter does not clamp into the setting's own range. A value outside [100, 100000] is reported by getMaxParallelPush(). A value outside what an IntProp can hold is refused here, logged, and not stored.

      Parameters:
      value - The maximum number of concurrent in-flight push sends.
      Returns:
      true when this property container has been changed, false otherwise - including when the value was refused as unstorable.
    • getDefaultTTL

      public long getDefaultTTL()
      Gets the default time-to-live applied to a notification that does not carry its own TTL, in milliseconds, clamped into [60000L, 2419200000L] with the default 2073600000L.
      Specified by:
      getDefaultTTL in interface IPushSettings
      Returns:
      The default notification TTL in milliseconds.
    • setDefaultTTL

      public boolean setDefaultTTL(long value)
      Sets the default time-to-live applied to a notification that does not carry its own TTL, in milliseconds. The conversion to the seconds required by the RFC 8030 TTL header happens at the transport boundary, never here.

      The value is stored as given: see the class documentation for why the setter does not clamp.

      Parameters:
      value - The default notification TTL in milliseconds.
      Returns:
      true when this property container has been changed, false otherwise.
    • getPushRoof

      public int getPushRoof()
      Gets this server's outbound push throughput roof in sends per second, clamped into [10, 50000] with the default 500.
      Specified by:
      getPushRoof in interface IPushSettings
      Returns:
      The outbound push throughput roof in sends/second.
    • setPushRoof

      public boolean setPushRoof(int value)
      Sets this server's outbound push throughput roof in sends per second.

      The value is stored as given: see the class documentation for why the setter does not clamp into the setting's own range. A value outside what an IntProp can hold is refused here, logged, and not stored.

      Parameters:
      value - The outbound push throughput roof in sends/second.
      Returns:
      true when this property container has been changed, false otherwise - including when the value was refused as unstorable.
    • getDefaultResidencyPolicy

      public ResidencyPolicy getDefaultResidencyPolicy()
      Gets the server-default residency policy applied to a send that does not name its own.

      Stored as the constant's ordinal(). A stored index outside the constant set resolves to ResidencyPolicy.DEFAULT and is logged, because failing closed on unresolved residency is never a compliance violation whereas failing open can be.

      Specified by:
      getDefaultResidencyPolicy in interface IPushSettings
      Returns:
      The default ResidencyPolicy; never null.
    • setDefaultResidencyPolicy

      public boolean setDefaultResidencyPolicy(ResidencyPolicy value)
      Sets the server-default residency policy, stored as the constant's ordinal().

      Because the stored value is an ordinal, the order of the ResidencyPolicy constants is part of the persisted and wire contract: new constants are appended, never inserted or reordered.

      Parameters:
      value - The default residency policy.
      Returns:
      true when this property container has been changed, false otherwise.
      Throws:
      NullPointerException - If value is null.
    • getDefaultDeliveryMode

      public DeliveryMode getDefaultDeliveryMode()
      Gets the server-default delivery mode applied to a send that does not name its own.

      Stored as the constant's ordinal(). A stored index outside the constant set resolves to DeliveryMode.DEFAULT and is logged.

      Specified by:
      getDefaultDeliveryMode in interface IPushSettings
      Returns:
      The default DeliveryMode; never null.
    • setDefaultDeliveryMode

      public boolean setDefaultDeliveryMode(DeliveryMode value)
      Sets the server-default delivery mode, stored as the constant's ordinal().

      Because the stored value is an ordinal, the order of the DeliveryMode constants is part of the persisted and wire contract: new constants are appended, never inserted or reordered.

      Parameters:
      value - The default delivery mode.
      Returns:
      true when this property container has been changed, false otherwise.
      Throws:
      NullPointerException - If value is null.
    • getSpoolDirectory

      public String getSpoolDirectory()
      Gets the directory in which the write-ahead spool holds notifications that could not be delivered immediately. An empty string selects the server-determined default location.
      Specified by:
      getSpoolDirectory in interface IPushSettings
      Returns:
      The spool directory path, or an empty string for the server default; never null.
    • setSpoolDirectory

      public boolean setSpoolDirectory(String value)
      Sets the spool directory path. An empty value selects the server default location.
      Parameters:
      value - The spool directory path, or an empty string for the server default.
      Returns:
      true when this property container has been changed, false otherwise.