Class SecretsStores

java.lang.Object
com.iizix.prop.SecretsStores

public final class SecretsStores extends Object
The one way from the property framework to the secrets store of this process (SECRETS-STORE-DESIGN.md section 4.2, decision P-7 (a)): the installed ISecretsStore, the no-op store NONE until one is installed, and the two traversals of a root that a loader and a saver call - resolve(PropCnr) when the tree of a file is complete and commit(PropCnr) when its file has been saved.

The traversals use only the four methods of ISecretsStore (and its default ISecretsStore.putProp(String,GProp)), so they work over the server's file store and over any other implementation alike. A secret-marked property finds its key through the nearest ancestor implementing ISecretsContext; a property with no such ancestor, or whose root has no context name yet, is skipped (design section 3.2): its value stays in memory and is written nowhere.

Nothing leaks. A value is never put in a log line or an exception text, and neither is the message of an exception thrown while converting one, since a conversion error quotes the text it could not convert.

Only a server or the Designer installs a store; a client never does.

Author:
Christopher Mindus
  • Field Details

  • Method Details

    • get

      public static ISecretsStore get()
      Gets the secrets store of this process.
      Returns:
      The installed store, or NONE when none is installed; never null.
    • isInstalled

      public static boolean isInstalled()
      Checks whether a store is installed.
      Returns:
      true when a store other than NONE is installed.
    • install

      public static ISecretsStore install(ISecretsStore store)
      Installs the secrets store of this process, replacing the one installed before.
      Parameters:
      store - The store.
      Returns:
      The store installed before, or null when there was none.
      Throws:
      NullPointerException - If the store is null: use uninstall(ISecretsStore).
    • uninstall

      public static boolean uninstall(ISecretsStore store)
      Uninstalls a store, only when it is the one installed: disposing a store that another has replaced leaves the replacement installed.
      Parameters:
      store - The store.
      Returns:
      true when it was installed and is not any longer.
    • resolve

      public static int resolve(PropCnr root)
      Gives every secret-marked property below a root its value from the installed store. See resolve(PropCnr,ISecretsStore).
      Parameters:
      root - The root of the tree, typically the root of a file just loaded.
      Returns:
      The number of properties that took a value.
    • resolve

      public static int resolve(PropCnr root, ISecretsStore store)
      Gives every secret-marked property below a root its value from a store, without firing a change and without touching the changed state of the property: the value is set as a value read from the file would have been.

      A key the store has no entry for leaves the property as it is, normally null, and is reported once per key per call: SEVERE on a production server, WARNING anywhere else (decision P-15). The server keeps running; the consumer of the value is unconfigured, as it is today when a file carries no value. A key of a secret its context calls optional (ISecretsContext.isSecretOptional(GProp)) is not reported here: its root says what the absence means, as PushProps does for an application's Push Notification secrets (CC-FIX-PUSH-SECRET-MISSING, ruling T5-D-1). A value that the property class cannot convert is reported SEVERE, naming the key and the class, and the property is left as it is.

      Parameters:
      root - The root of the tree.
      store - The store, null for NONE.
      Returns:
      The number of properties that took a value.
      Throws:
      NullPointerException - If the root is null.
    • commit

      public static int commit(PropCnr root)
      Hands the value of every secret-marked property below a root to the installed store. See commit(PropCnr,ISecretsStore).
      Parameters:
      root - The root of the tree, typically the root of a file just saved.
      Returns:
      The number of values handed to the store.
    • commit

      public static int commit(PropCnr root, ISecretsStore store)
      Hands the value of every secret-marked property below a root to a store, called after the file of the root has been saved (decision P-2 (b)): each value becomes a put under its key, through ISecretsStore.putProp(String,GProp) so that a store keeping the class of an entry learns it. When and how the store writes it is the store's business.

      A property with a null value is skipped, not removed: a null in memory normally means that the value is missing on this machine, or could not be converted, and saving the file must not destroy an entry. A key is removed only by an explicit ISecretsStore.remove(String). A read-only store is told nothing, and that is logged once at INFO with the number of values not written.

      Parameters:
      root - The root of the tree.
      store - The store, null for NONE.
      Returns:
      The number of values handed to the store.
      Throws:
      NullPointerException - If the root is null.
    • keyOf

      public static String keyOf(GProp<?> prop)
      Gets the key of a secret property: the nearest ancestor implementing ISecretsContext gives it.
      Parameters:
      prop - The property.
      Returns:
      The key, or null when no ancestor gives a context.
    • contextOf

      public static ISecretsContext contextOf(GProp<?> prop)
      Gets the secrets context of a secret property: the nearest ancestor implementing ISecretsContext, the one keyOf(GProp) asks for the key.
      Parameters:
      prop - The property.
      Returns:
      The context, or null when no ancestor gives one.