Class SharedConfigurationState

java.lang.Object
ru.vyarus.dropwizard.guice.module.context.SharedConfigurationState

public class SharedConfigurationState extends Object
Application-wide shared state assumed to be used in the configuration phase. For example, in complex cases when bundles must share some global state (otherwise it would require to maintain some ThreadLocal field in a bundle). But other cases could arise too. Intended to be used for very rare cases: use it only if you can't avoid shared state in configuration time (for example, like the guicey gsp bundle, which requires global configuration, accessible by multiple bundles).

Internally, guicey use it to store created Injector and make it available statically (see InjectorLookup).

Universal sharing place should simplify testing in the future: if a new global state appeared, there would be no need to reset anything in tests (to clear state, for example, on testing errors). One "dirty" place to replace all separate hacks.

Shared state could be accessed statically with get(Application), or within GuiceyBundle. Guicey hooks could use GuiceBundle.Builder.withSharedState(java.util.function.Consumer) to access application state. Alternatively, dropwizard Environment may be used for resolution: get(Environment).

During startup shared state instance could be obtained directly as getStartupInstance(), but only from application main thread. This might be required for places where neither application nor environment object available. After guice bundle's run method finishes, startup instance is unlinked.

Classes are used as state keys to simplify usage (shared object class is the key). Shared value could be set only once (to prevent complex situations with state substitutions). It is advised to initialize shared value only in initialization phase (to avoid potential static access errors).

If stored state object implements AutoCloseable it will be automatically closed on application shutdown (which is closed in most cases under tests). This is mostly useful to guarantee resource cleanup after the test (when it can't be managed directly).

Objects available in shared state by default: Bootstrap, Configuration, Environment, ConfigurationTree, Injector, Options (see shortcut instance methods).

To debug shared state access use getAccessReport() (or GuiceBundle.Builder.printSharedStateUsage()).

Since:
26.09.2019
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    Attribute name used to store application instance in application context attributes.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Create state.
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    assignTo(io.dropwizard.core.Application application)
    Called on initialization phase to assign registry instance to application (to be able to statically reference registry).
    static void
    Clears stored injectors references.
    protected void
    Called after application startup to cleanup thread local instance.
    get(io.dropwizard.core.Application application)
    Static lookup for entire application registry.
    get(io.dropwizard.core.setup.Environment environment)
    Static lookup for entire application registry by environment instance.
    <V> V
    get(Class<V> key)
    Note: although class is used for key, actual value is stored with full class name string.
    <V> V
    get(Class<V> key, Supplier<V> defaultValue)
    Get value or declare default if value not set yet.
    <V> V
    get(String key)
    Special string-based state access for revising state with getKeys().
    Shows all objects in state with a link to assignment source and all state access attempts (success or misses).
    <C extends io.dropwizard.core.Configuration>
    jakarta.inject.Provider<io.dropwizard.core.Application<C>>
    Application object is available since guice bundle initialization start.
    <C extends io.dropwizard.core.Configuration>
    jakarta.inject.Provider<io.dropwizard.core.setup.Bootstrap<C>>
    Bootstrap object is available since guice bundle initialization start.
    <C extends io.dropwizard.core.Configuration>
    jakarta.inject.Provider<C>
    Configuration instance is available since guice bundle run.
    jakarta.inject.Provider<ConfigurationTree>
    Configuration instance is available since guice bundle run.
    jakarta.inject.Provider<io.dropwizard.core.setup.Environment>
    Environment instance is available since guice bundle run.
    jakarta.inject.Provider<com.google.inject.Injector>
    Injector instance is created under guice bundle run.
    Note: each key is a full name of registration class.
    Options access object is always available.
    getOrFail(io.dropwizard.core.Application application, String message, Object... args)
    Shortcut for get(Application) to immediately fail if registry is not available.
    getOrFail(io.dropwizard.core.setup.Environment environment, String message, Object... args)
    Shortcut for get(Environment) to immediately fail if registry is not available.
    <V> V
    getOrFail(Class<V> key, String message, Object... args)
    Shortcut for get(Class) to immediately fail if value not set.
    During application startup it is not always possible to lookup configuration state with Application or Environment objects.
    protected void
    listen(io.dropwizard.core.setup.Environment environment)
    Called on run phase to assign to application lifecycle and listen for shutdown.
    static <V> Optional<V>
    lookup(io.dropwizard.core.Application application, Class<V> key)
    Static lookup for registry value.
    static <V> Optional<V>
    lookup(io.dropwizard.core.setup.Environment environment, Class<V> key)
    Static lookup for registry value by environment instance.
    static <V> V
    lookupOrCreate(io.dropwizard.core.Application application, Class<V> key, Supplier<V> defSupplier)
    Shortcut for lookup(Application, Class) to get ot initialize shared state value.
    static <V> V
    lookupOrCreate(io.dropwizard.core.setup.Environment environment, Class<V> key, Supplier<V> defSupplier)
    Shortcut for lookup(Environment, Class) to get ot initialize shared state value.
    static <V> V
    lookupOrFail(io.dropwizard.core.Application application, Class<V> key, String message, Object... args)
    Shortcut for lookup(Application, Class) to immediately fail if value is not available.
    static <V> V
    lookupOrFail(io.dropwizard.core.setup.Environment environment, Class<V> key, String message, Object... args)
    Shortcut for lookup(Environment, Class) to immediately fail if value is not available.
    <V> void
    put(Class<V> key, V value)
    Assumed to be used to store some configuration during startup.
    void
    Clear state for exact application.
    static int
    Could be useful only in tests in order to validate possibly stale applications.
     
    <V> void
    whenReady(Class<V> key, Consumer<V> action)
    Reactive shared value access: if value already available action called immediately, otherwise action would be called when value set (note that value could be set only once).

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • CONTEXT_APPLICATION_PROPERTY

      public static final String CONTEXT_APPLICATION_PROPERTY
      Attribute name used to store application instance in application context attributes.
      See Also:
  • Constructor Details

    • SharedConfigurationState

      public SharedConfigurationState()
      Create state.
  • Method Details

    • get

      public <V> V get(Class<V> key)
      Note: although class is used for key, actual value is stored with full class name string. So classes, loaded from different class loaders will lead to the same value.
      Type Parameters:
      V - shared object type
      Parameters:
      key - shared object key
      Returns:
      value or null
    • get

      public <V> V get(String key)
      Special string-based state access for revising state with getKeys().
      Type Parameters:
      V - value type
      Parameters:
      key - state key
      Returns:
      state value or null
    • get

      public <V> V get(Class<V> key, Supplier<V> defaultValue)
      Get value or declare default if value not set yet.
      Type Parameters:
      V - shared object type
      Parameters:
      key - shared object key
      defaultValue - default shared object provider
      Returns:
      stored or default (just stored) value
    • getOrFail

      public <V> V getOrFail(Class<V> key, String message, Object... args)
      Shortcut for get(Class) to immediately fail if value not set. Supposed to be used by shared state consumers (to validate situations when value must exist for sure).
      Type Parameters:
      V - shared object type
      Parameters:
      key - shared object key
      message - exception message (could use String.format(String, Object...) placeholders)
      args - placeholder arguments for error message
      Returns:
      stored object (never null)
      Throws:
      IllegalStateException - if value isn't set
    • whenReady

      public <V> void whenReady(Class<V> key, Consumer<V> action)
      Reactive shared value access: if value already available action called immediately, otherwise action would be called when value set (note that value could be set only once).

      Note: listener would not be called if the state is never set. This assumed to be used for optional state cases.

      Type Parameters:
      V - value type
      Parameters:
      key - shared object key
      action - action to execute when value would be set
    • getOptions

      public Options getOptions()
      Options access object is always available.
      Returns:
      options access object
    • getBootstrap

      public <C extends io.dropwizard.core.Configuration> jakarta.inject.Provider<io.dropwizard.core.setup.Bootstrap<C>> getBootstrap()
      Bootstrap object is available since guice bundle initialization start. It will not be available for hooks (because hooks processed before guice bundle initialization call - no way to get boostrap reference).
      Type Parameters:
      C - configuration type
      Returns:
      bootstrap instance provider (would fail if called too early)
    • getApplication

      public <C extends io.dropwizard.core.Configuration> jakarta.inject.Provider<io.dropwizard.core.Application<C>> getApplication()
      Application object is available since guice bundle initialization start.
      Type Parameters:
      C - configuration type
      Returns:
      application instance provider (would fail if called too early)
    • getEnvironment

      public jakarta.inject.Provider<io.dropwizard.core.setup.Environment> getEnvironment()
      Environment instance is available since guice bundle run.
      Returns:
      environment instance provider (would fail if called too early)
    • getConfiguration

      public <C extends io.dropwizard.core.Configuration> jakarta.inject.Provider<C> getConfiguration()
      Configuration instance is available since guice bundle run.
      Type Parameters:
      C - configuration type
      Returns:
      configuration instance provider (would fail if called too early)
    • getConfigurationTree

      public jakarta.inject.Provider<ConfigurationTree> getConfigurationTree()
      Configuration instance is available since guice bundle run.
      Returns:
      configuration tree instance provider (would fail if called too early)
    • getInjector

      public jakarta.inject.Provider<com.google.inject.Injector> getInjector()
      Injector instance is created under guice bundle run.
      Returns:
      configuration instance provider (would fail if called too early)
      See Also:
    • put

      public <V> void put(Class<V> key, V value)
      Assumed to be used to store some configuration during startup. For example, if multiple bundle instances should know of each other - they could use shared state to communicate.

      Class is used for key to avoid dummy mistakes with strings (in most cases bundle class would be key). But internally string class name is used in order to unify classes from different class loaders.

      Note: warning will be printed if existing state value is overridden because it is assumed that some global configuration object would be shared once and later all participants will work with the same object.

      Type Parameters:
      V - value type
      Parameters:
      key - shared object key
      value - shared value (usually configuration object)
    • getKeys

      public Set<String> getKeys()
      Note: each key is a full name of registration class.
      Returns:
      all available keys
    • shutdown

      public void shutdown()
      Clear state for exact application. Normally, state should shut down automatically (as it is a managed object). But in tests with disabled lifecycle this will not happen and so cleanup must be manual.
      See Also:
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • assignTo

      protected void assignTo(io.dropwizard.core.Application application)
      Called on initialization phase to assign registry instance to application (to be able to statically reference registry).
      Parameters:
      application - application instance
    • listen

      protected void listen(io.dropwizard.core.setup.Environment environment)
      Called on run phase to assign to application lifecycle and listen for shutdown.
      Parameters:
      environment - environment object
    • forgetStartupInstance

      protected void forgetStartupInstance()
      Called after application startup to cleanup thread local instance. After this moment call to getStartupInstance() would lead to exception (since that moment it is not a problem to obtain application or environment instances and resolve state with them).
    • getStartupInstance

      public static SharedConfigurationState getStartupInstance()
      During application startup it is not always possible to lookup configuration state with Application or Environment objects. For such cases simplified static call can be used. For example, in binding installer call, bundles lookup implementation, hook.

      IMPORTANT: It will work only during application startup and only from main application thread! Would not be available in application run method (becuase at this point guice bundle is already processed).

      Returns:
      shared configuration state instance
      Throws:
      NullPointerException - if called after startup, from non-main thread or before guice bundle registration (too early).
    • lookup

      public static <V> Optional<V> lookup(io.dropwizard.core.Application application, Class<V> key)
      Static lookup for registry value.
      Type Parameters:
      V - shared object key
      Parameters:
      application - application instance
      key - shared object key
      Returns:
      value optional
    • lookup

      public static <V> Optional<V> lookup(io.dropwizard.core.setup.Environment environment, Class<V> key)
      Static lookup for registry value by environment instance.
      Type Parameters:
      V - shared object key
      Parameters:
      environment - dropwizard environment object
      key - shared object key
      Returns:
      value optional
    • lookupOrFail

      public static <V> V lookupOrFail(io.dropwizard.core.Application application, Class<V> key, String message, Object... args)
      Shortcut for lookup(Application, Class) to immediately fail if value is not available.
      Type Parameters:
      V - shared object type
      Parameters:
      application - application instance
      key - shared object key
      message - exception message (could use String.format(String, Object...) placeholders)
      args - placeholder arguments for error message
      Returns:
      value (never null)
      Throws:
      IllegalStateException - if value not available
    • lookupOrFail

      public static <V> V lookupOrFail(io.dropwizard.core.setup.Environment environment, Class<V> key, String message, Object... args)
      Shortcut for lookup(Environment, Class) to immediately fail if value is not available.
      Type Parameters:
      V - shared object type
      Parameters:
      environment - environment instance
      key - shared object key
      message - exception message (could use String.format(String, Object...) placeholders)
      args - placeholder arguments for error message
      Returns:
      value (never null)
      Throws:
      IllegalStateException - if value not available
    • lookupOrCreate

      public static <V> V lookupOrCreate(io.dropwizard.core.Application application, Class<V> key, Supplier<V> defSupplier)
      Shortcut for lookup(Application, Class) to get ot initialize shared state value.
      Type Parameters:
      V - shared object type
      Parameters:
      application - application instance
      key - shared object key
      defSupplier - default value supplier (used when state is not exists to initialize it)
      Returns:
      value (never null)
      Throws:
      IllegalStateException - if value not available
    • lookupOrCreate

      public static <V> V lookupOrCreate(io.dropwizard.core.setup.Environment environment, Class<V> key, Supplier<V> defSupplier)
      Shortcut for lookup(Environment, Class) to get ot initialize shared state value.
      Type Parameters:
      V - shared object type
      Parameters:
      environment - environment instance
      key - shared object key
      defSupplier - default value supplier (used when state is not exists to initialize it)
      Returns:
      value (never null)
      Throws:
      IllegalStateException - if value not available
    • get

      public static Optional<SharedConfigurationState> get(io.dropwizard.core.Application application)
      Static lookup for entire application registry.
      Parameters:
      application - application instance
      Returns:
      optional of application registry (may be empty if called too early or too late)
    • get

      public static Optional<SharedConfigurationState> get(io.dropwizard.core.setup.Environment environment)
      Static lookup for entire application registry by environment instance.
      Parameters:
      environment - environment instance
      Returns:
      optional of application registry (may be empty if called too early or too late)
    • getOrFail

      public static SharedConfigurationState getOrFail(io.dropwizard.core.Application application, String message, Object... args)
      Shortcut for get(Application) to immediately fail if registry is not available.
      Parameters:
      application - application instance
      message - exception message (could use String.format(String, Object...) placeholders)
      args - placeholder arguments for error message
      Returns:
      registry (never null)
      Throws:
      IllegalStateException - if no state is associated with application yet
    • getOrFail

      public static SharedConfigurationState getOrFail(io.dropwizard.core.setup.Environment environment, String message, Object... args)
      Shortcut for get(Environment) to immediately fail if registry is not available.
      Parameters:
      environment - environment instance
      message - exception message (could use String.format(String, Object...) placeholders)
      args - placeholder arguments for error message
      Returns:
      registry (never null)
      Throws:
      IllegalStateException - if no state is associated with application yet
    • clear

      public static void clear()
      Clears stored injectors references. Normally shouldn't be used at all, because managed object will detect application shutdown and remove assigned state (for example, when used DropwizardAppRule or GuiceyAppRule).

      May be useful in tests, when application was not shut down properly (but just to clear memory).

      WARNING: calling this method while application is working may cause incorrect behaviour.

    • statesCount

      public static int statesCount()
      Could be useful only in tests in order to validate possibly stale applications.
      Returns:
      number of registered contexts
    • getAccessReport

      public String getAccessReport()
      Shows all objects in state with a link to assignment source and all state access attempts (success or misses).
      Returns:
      shared state usage report