Class Configurator

java.lang.Object
io.inversion.utils.Configurator

public class Configurator extends Object
Wires up an Api at runtime by reflectively setting bean properties based on key/value configuration properties.

Configurator works in two different modes:

  1. Dependency Injection Mode

    - If the Engine already has an Api set on it, then it is assumed that a developer has at least partially wired up their own Api via code. In this case, the Configurator looks for named beans in the Api object graph(s) and sets any corresponding "beanName.propertyName" values from configuration on the bean. This is a great way to inject runtime dependencies such as database credentials. If developers are hard core SpringBoot-ers, or are otherwise coding up their Inversion Api using some existing DI framework, they may find this capability to be redundant and prefer to use their own party DI which is totally fine.
  2. Full Wiring Mode

    - when an Engine starts up and no Api's have been added to the Engine via code, then the Configurator does all of the work to fully instantiate/configure/bootstrap the Api object model based on data found in the configuration. Here is an outline how Full Wiring Mode works.
    • All beans with key/value properties "${beanName}.class=className" are instantiated and all "${beanName}.${propertyName}" values are set.
    • startup() is called on all Db objects effectively bootstrapping the full Api model.
    • The now populated object graph is re-serialized to name/value property pairs in memory.
    • All instantiated objects to this point are thrown away.
    • All of the values from configuration are merged down on top of the in memory pairs. This allows the configuration author to overwrite any of the bean properties set during the Db.startup() default bootstrapping.
    • The merged properties model is decoded and the full Api(s) object model/graph that is set on the Engine.
    • When the Engine calls startup() on the Apis (right after configure(Engine) returns), the Apis will call startup() on their Dbs. In the first pass, above, the Dbs had empty configurations so calling Db.startup() caused the Dbs to reflectively inspect their underlying data source and create Collections to represent underlying tables etc. These Collections were serialized out and then instantiated and set on the new copies of the Db in the final wiring above. Now when Db.startup() is called, the Db has Collection(s) already set on them and the Db will skip the reflective bootstrapping phase.
    • NOTE: If you don't supply at least one "${myApiName}.class=io.inversion.Api" property in your configuration, a default api named "api" will be instantiated for you and the Configurator will assume all Db, Endpoints and Actions declared in the configuration belong to that single implicit Api.
    • NOTE: If you have a single Api and you don't supply at least one "${myEndpointName}.class=io.inversion.Endpoint" property in our configuration, a default Endpoint named "endpoint" that matches on all HTTP methods and URL paths will be inferred by the Configurator. If you declear multiple Apis, you must declare Endpoints if you want your Api to do anything.
    • NOTE: If you only have a single Api, all Dbs, Endpoints, and global Actions will be set on the Api. If you have more than one Api in your configuration, you must assign Dbs, Endpoints, and global Actions to the appropriate Api. A "global" Action is one that is not explicitly assigned to an Endpoint but is instead assigned directly to the Api and can then be selected to run across requests to multiple different Endpoints.

Here is an example minimal configuration for Full Wiring Mode that will produce a fully running REST API for the underlying data source. These name/value pairs can come from any combination of property sources loaded into configuration.

      myAction.class=io.inversion.db.DbAction
      myDb.class=io.inversion.jdbc.JdbcDb
      myDb.driver=${YOUR JDBC DRIVER CLASS NAME}
      myDb.url=${YOUR JDBC URL}
      myDb.user=${YOUR JDBC USERNAME}
      myDb.pass=${YOUR JDBC PASSWORD}
 

By default, the configuration is going to the global default CombinedConfiguration from Config.

See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
     
    static final Object[]
    If a bean property field name appears in this list, it will not be logged but replaced with "************" in the output.
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    configure(Engine engine, org.apache.commons.configuration2.Configuration configuration)
    Wires up an Api at runtime by reflectively setting bean properties based on key/value configuration properties.

    Methods inherited from class java.lang.Object

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

    • MASKED_FIELDS

      public static final Object[] MASKED_FIELDS
      If a bean property field name appears in this list, it will not be logged but replaced with "************" in the output.

      Put values here in lower case.

    • MASK

      public static final String MASK
      See Also:
  • Constructor Details

    • Configurator

      public Configurator()
  • Method Details

    • configure

      public void configure(Engine engine, org.apache.commons.configuration2.Configuration configuration)
      Wires up an Api at runtime by reflectively setting bean properties based on key/value configuration properties.
      Parameters:
      engine - the engine to be configured
      configuration - the name/value pairs used to wire up the Api's that will be added to engine.
      See Also: