Class CconfigClientImpl

java.lang.Object
org.chenile.cconfig.sdk.CconfigClientImpl
All Implemented Interfaces:
CconfigClient

public class CconfigClientImpl extends Object implements CconfigClient
The default implementation of the CconfigClient interface. This uses a CconfigRetriever to get multiple Cconfigs that allow the default value to be mutated.
  • Field Details

    • logger

      private static final org.slf4j.Logger logger
    • objectMapper

      private final ObjectMapper objectMapper
    • parser

      private final ExpressionParser parser
    • configPath

      private final String configPath
    • cconfigRetriever

      private final CconfigRetriever cconfigRetriever
    • memoryCache

      @Autowired MemoryCache memoryCache
    • moduleCache

      private final Map<String,String> moduleCache
      Caches module keys in cache. Avoids repeated reads and processing of the Module files and DB. Avoids repeated expensive SPEL evaluation.
    • contextContainer

      @Autowired ContextContainer contextContainer
  • Constructor Details

  • Method Details

    • value

      public Map<String,Object> value(String module, String key)
      Specified by:
      value in interface CconfigClient
      Parameters:
      module - - the module under which the key is defined. Modules can be nested.
      key - - the key for which value is desired.
      Returns:
      the value for the key. If key is null and only module name is specified, then all keys for module will be returned. Key value can be string or a map.
      If a module is specified it will be a map with all the keys as keys of the map. The value can be strings or map depending on how the value was defined in the JSON file and all the DB records.
      Eg: The JSON file that defines the keys for a module can look like this:
      "key1": "value1" "key2": { "valid JSON": "here", "it": { "can": {"be": { "arbitrarily": "nested"}}} }
      Modules are defined in JSON files under a config path defined in "chenile.config.path". For example module1 is defined in module1.json directly under "chenile.config.path".
      These JSON values can be over-ridden in two ways in the database:
      1. They can be over-ridden for all "requests" whether they have a custom attribute or not (__GLOBAL__)
      2. They can be over-ridden for specific "requests" that have a custom attribute (eg. all requests that belong to a client "tenant0")
      The whole JSON can be over-ridden or specific portions of the JSON (given by path) can be over-ridden. Please see the test cases for more details.
      It is possible that no JSON file exists. All keys can be defined in the database directly without using the JSON. In that case, keys can only be defined using path as null. Subsequent records can override this record. It is assumed that DB records don't alter the same path. If they do so, the result is indeterminate.
    • allKeysForModule

      private Map<String,Object> allKeysForModule(String module, String customAttribute)
      Parameters:
      module - name of the module
      Returns:
      all the keys in the module. This includes all the keys in the JSON file (if found) and also the DB keys.
    • getJsonMapForModuleFromClassPath

      private Map<String,Object> getJsonMapForModuleFromClassPath(String module)
      Parameters:
      module - the module that needs to be read from the class path
      Returns:
      all the module keys as JSON.
    • customizationAttribute

      protected String customizationAttribute()
      Override this in a subclass to change the default behaviour.
      Returns:
      the value of custom attribute from request headers. Default implementation returns the value of the tenant ID header.
    • readModuleAsString

      private String readModuleAsString(String module)
      Parameters:
      module - the module to read from the class path
      Returns:
      the module as a string or null if such a file does not exist
    • override

      private Object override(String module, String key, Object value, List<Cconfig> dbList)
      Parameters:
      module - the module
      key - the key
      value - the original value either from JSON or from the first record found with path null in DB
      dbList - the list of all keys obtained for the module and the custom attribute.
      Returns:
      the modified value after all the operations in dblist are applied against the key
    • mapExpression

      private String mapExpression(String p)
      Parameters:
      p - the path defined in the database
      Returns:
      the expression in a form that is amenable to be used as a SPEL expression for maps
    • evaluate

      private Object evaluate(String key, String path, Object value, String dbValue)
      Parameters:
      key - the key
      path - the path in the value that has been modified to a new value
      value - the original value that will be modified
      dbValue - the db value that will be applied against the original record
      Returns:
      the modified value after SPEL constructs specified in the path are invoked on the original record
    • objectify

      private Object objectify(String dbValue)
      Parses the string as JSON if applicable and returns the parsed string as map
      Parameters:
      dbValue - the value to objectify
      Returns:
      the string or map