Class HubDefinition

java.lang.Object
com.iizix.server.hub.HubDefinition
All Implemented Interfaces:
AutoCloseable

public final class HubDefinition extends Object implements AutoCloseable
The hub definition in force on this server, HUB-DESIGN.md section 4.2: the file located by the system property "iizi.hub.definition" or, when it is absent, the environment variable "IIZI_HUB_DEFINITION" (the property wins), this server's member ID from "iizi.hub.member" or "IIZI_HUB_MEMBER" the same way, parsed by HubDefinitionFile, hashed for the REGISTER event (getDefinitionHash(), section 2.4) and watched for changes through PushFileWatcher (ruling H-9: the watcher is used where it is; ruling S-5: a WatchService, never polling). In com.iizix.server because every member needs it (ruling D-7 of B-7a): today the hub module loads it in LoadBalancer.initialize, and B-7b's member client will load it from ServerShell.

Standalone. With no file configured, no member ID configured, a path that is set but does not exist or cannot be read (SEVERE), a file without a usable [hub] name (SEVERE) or a file that does not name this server in [members] (SEVERE; ruling H-6 applied locally), nothing is in force and isStandalone() answers true.

Reload, section 4.2: [origins], lease, margin, grace and hold apply at once; a change to [members] or policy is held for the next election (hasPendingElectionChange(), applyElectionChanges(), called by the election of B-7c); a change to name is refused with SEVERE until restart, the name of the first load staying in force while the rest of the reload applies. A reload whose file is missing, unreadable, unusable or does not name this server is refused with SEVERE and the previous definition stays in force. Every refused line of a partly valid reload is logged and the valid lines apply.

Never logged: the content of any line. The file holds no secret - the interim cluster key lives in the file key names, which B-7b reads and protects - so the path, the hub name, the member IDs and the counts are logged at INFO on every load.

Author:
Christopher Mindus
  • Field Details

    • PROPERTY

      public static final String PROPERTY
      The system property naming the definition file: "iizi.hub.definition".
      See Also:
    • ENVIRONMENT

      public static final String ENVIRONMENT
      The environment variable naming the definition file when the property is absent: "IIZI_HUB_DEFINITION".
      See Also:
    • MEMBER_PROPERTY

      public static final String MEMBER_PROPERTY
      The system property naming this server's member ID: "iizi.hub.member".
      See Also:
    • MEMBER_ENVIRONMENT

      public static final String MEMBER_ENVIRONMENT
      The environment variable naming this server's member ID when the property is absent: "IIZI_HUB_MEMBER".
      See Also:
    • THREAD_NAME

      public static final String THREAD_NAME
      The name of the watcher thread when this instance owns one.
      See Also:
  • Constructor Details

    • HubDefinition

      public HubDefinition(Path file, String memberID)
      Constructor: nothing is read until start() or load().
      Parameters:
      file - The definition file, null when none is configured.
      memberID - This server's member ID, null when not configured.
  • Method Details

    • fromConfiguration

      public static HubDefinition fromConfiguration()
      Creates the definition from the configuration: the system properties, else the environment variables.
      Returns:
      The definition, not yet loaded.
    • configuredPath

      public static Path configuredPath(UnaryOperator<String> property, UnaryOperator<String> environment)
      Resolves the configured file from the two settings supplied: the property wins because it is set on the one server JVM's command line; the environment variable is read only when the property is absent or blank.
      Parameters:
      property - Answers a system property by name.
      environment - Answers an environment variable by name.
      Returns:
      The absolute path, or null when neither names a file; an unusable path is logged SEVERE and answered as null.
    • configuredMember

      public static String configuredMember(UnaryOperator<String> property, UnaryOperator<String> environment)
      Resolves this server's member ID from the two settings supplied, the property winning as for the file.
      Parameters:
      property - Answers a system property by name.
      environment - Answers an environment variable by name.
      Returns:
      The member ID, stripped, or null when neither sets one.
    • getFile

      public Path getFile()
      Gets the configured file.
      Returns:
      The file, or null when none is configured.
    • getMemberID

      public String getMemberID()
      Gets this server's configured member ID.
      Returns:
      The member ID, or null when not configured.
    • isStandalone

      public boolean isStandalone()
      Tells whether no definition is in force: nothing of the hub runs on this server.
      Returns:
      true while standalone.
    • getHubName

      public String getHubName()
      Gets the hub's name, the key of its rows in HUB.*, fixed at the first load.
      Returns:
      The name, or null while standalone.
    • getLeaseSeconds

      public int getLeaseSeconds()
      Gets the lease in seconds, applied at once by a reload.
      Returns:
      The lease, the default while standalone.
    • getMarginSeconds

      public int getMarginSeconds()
      Gets the margin in seconds, applied at once by a reload.
      Returns:
      The margin, the default while standalone.
    • getGraceSeconds

      public int getGraceSeconds()
      Gets the fail-open grace in seconds, applied at once by a reload.
      Returns:
      The grace, the default while standalone.
    • getHoldSeconds

      public int getHoldSeconds()
      Gets the hold in seconds, applied at once by a reload.
      Returns:
      The hold, the default while standalone.
    • getKeyPath

      public String getKeyPath()
      Gets the path of the interim cluster key file as written in the file.
      Returns:
      The path, or null when not set or while standalone.
    • getOrigins

      public List<String> getOrigins()
      Gets the further allowed origins, applied at once by a reload.
      Returns:
      The normalised origins, empty while standalone; never null.
    • getPolicy

      public HubDefinitionFile.Policy getPolicy()
      Gets the election policy in force: a change waits for the next election.
      Returns:
      The policy, the default while standalone.
    • getMembers

      public List<HubDefinitionFile.Member> getMembers()
      Gets the members in force, in priority order: a change waits for the next election.
      Returns:
      The members, empty while standalone; never null.
    • getMember

      public HubDefinitionFile.Member getMember()
      Gets this server's own member line, from the members in force.
      Returns:
      The member, or null while standalone.
    • isEligible

      public boolean isEligible()
      Tells whether this server is an eligible member: flagged principal in the members in force.
      Returns:
      true when eligible.
    • hasPendingElectionChange

      public boolean hasPendingElectionChange()
      Tells whether a reload changed [members] or policy since the election in force.
      Returns:
      true when a change waits for the next election.
    • applyElectionChanges

      public boolean applyElectionChanges()
      Applies a pending change to [members] and policy: called by an election.
      Returns:
      true when the members or the policy changed, false when nothing was pending.
    • getDefinitionHash

      public String getDefinitionHash()
      Gets the SHA-256 of the definition file as last read, for the def member of the REGISTER event (section 2.4).
      Returns:
      The hash in lower-case hexadecimal, or null while standalone.
    • getLoadCount

      public int getLoadCount()
      Gets the number of completed loads, successful or not.
      Returns:
      The count.
    • setLoadHook

      public void setLoadHook(Runnable hook)
      Sets what runs after every completed load, for a test that waits for the condition.
      Parameters:
      hook - The hook, null for none.
    • getWatcher

      public PushFileWatcher getWatcher()
      Gets the watcher.
      Returns:
      The watcher, null before start() or without a file.
    • start

      public void start()
      Loads the file and watches it with a watcher of this instance's own, closed by close(). Without a configured file nothing runs and nothing is watched.
    • start

      public void start(PushFileWatcher shared)
      Loads the file and watches it.
      Parameters:
      shared - The server's watcher to register the file with, or null for a watcher of this instance's own, closed by close().
    • load

      public void load()
      Loads the file once, as start() does first; for a caller that watches nothing.
    • reload

      public void reload()
      Reloads the file after a change.
    • close

      public void close()
      Stops watching; the own watcher is closed. What is in force stays in force.
      Specified by:
      close in interface AutoCloseable