Package org.confng

Class ConfNG


  • public class ConfNG
    extends Object
    Main configuration management class for ConfNG.

    ConfNG provides a unified way to access configuration values from multiple sources with a defined precedence order. By default, it checks environment variables first, then system properties, followed by any loaded properties, JSON, YAML, or TOML files.

    This class supports integration with secret managers like AWS Secrets Manager and HashiCorp Vault, providing secure access to sensitive configuration data.

    Global vs Environment-Specific Configuration

    ConfNG supports a powerful pattern for managing configurations across multiple environments by separating global/common settings from environment-specific overrides:

    Global/Common Configuration

    Define baseline configuration that applies to all environments in global configuration files:

    • global.properties, global.json, global.yaml, global.toml
    • common.properties, common.json, common.yaml, common.toml
     // Load global configuration (applies to all environments)
     ConfNG.loadGlobalConfig();
     

    Environment-Specific Configuration

    Override global settings with environment-specific values (env1, env2, env3, etc.):

     // Load environment-specific files (overrides global config)
     ConfNG.loadConfigForEnvironment("env1");  // Loads env1.properties, env1.json, env1.yaml, env1.toml
    
     // Or automatically detect environment from APP_ENV, ENVIRONMENT, or ENV variables
     String env = ConfNG.autoLoadConfig();  // Automatically loads config for detected environment
     

    Recommended Loading Order

    For best practices, load global configuration first, then environment-specific:

     // 1. Load global/common configuration
     ConfNG.loadGlobalConfig();
    
     // 2. Load environment-specific configuration (overrides global)
     ConfNG.loadConfigForEnvironment("prod");
     

    Example Configuration Structure

    global.json (shared across all environments):

     {
       "api.timeout": "30",
       "retry.count": "3",
       "log.level": "INFO"
     }
     

    uat.json (UAT-specific overrides):

     {
       "api.url": "https://uat-api.example.com",
       "api.timeout": "60",
       "database.host": "uat-db.example.com"
     }
     

    Result for UAT: api.timeout=60 (overridden), retry.count=3 (inherited from global), log.level=INFO (inherited from global), plus UAT-specific api.url and database.host

    Additional Configuration Patterns

    Environment Sections Within Files

    Store multiple environments in a single file with sections:

     // Load specific environment section from a file
     ConfNG.loadJson("config.json", "uat");    // Loads only the "uat" section
     ConfNG.loadYaml("config.yaml", "prod");   // Loads only the "prod" section
     ConfNG.loadToml("config.toml", "qa");     // Loads only the "qa" section
     

    TestNG Integration

    When using TestNG, the TestNGParameterListener automatically loads global configuration followed by environment-specific configuration at suite startup. Simply add an "environment" or "env" parameter to your testng.xml:

     <suite name="My Test Suite">
       <parameter name="environment" value="uat"/>
       ...
     </suite>
     
    Since:
    1.0
    Author:
    Bharat Kumar Malviya, GitHub: github.com/imBharatMalviya
    See Also:
    ConfNGKey, ConfigSource, TestNGParameterListener
    • Constructor Detail

      • ConfNG

        public ConfNG()
    • Method Detail

      • registerSource

        public static void registerSource​(ConfigSource source)
      • registerSourceAt

        public static void registerSourceAt​(int precedenceIndex,
                                            ConfigSource source)
      • addSource

        public static void addSource​(ConfigSource source)
        Adds a configuration source with automatic priority-based ordering. Sources with higher priority values are placed earlier in the resolution chain.
        Parameters:
        source - the configuration source to add
      • clearSourcesAndUseDefaults

        public static void clearSourcesAndUseDefaults()
      • load

        public static void load​(String filePath)
        Loads a configuration file by auto-detecting its type based on the file extension. Supports .properties, .json, .yaml, .yml, and .toml files. Supports loading from both filesystem and classpath (including JAR resources). If the file doesn't exist, it will be silently skipped.
        Parameters:
        filePath - path to the configuration file (filesystem or classpath)
      • load

        public static void load​(String filePath,
                                String environment)
        Loads a configuration file with environment-specific section by auto-detecting its type. Supports .json, .yaml, .yml, and .toml files with environment sections. Supports loading from both filesystem and classpath (including JAR resources). Properties files don't support environment sections. If the file doesn't exist, it will be silently skipped.
        Parameters:
        filePath - path to the configuration file (filesystem or classpath)
        environment - the environment section to load (e.g., "uat", "beta", "qa", "prod")
      • loadProperties

        public static void loadProperties​(String filePath)
        Loads a properties file as a configuration source. Supports loading from both filesystem and classpath (including JAR resources). If the file doesn't exist, it's silently skipped. If the file exists but is invalid, throws a runtime exception.
        Parameters:
        filePath - path to the properties file (filesystem or classpath)
      • loadJson

        public static void loadJson​(String filePath)
        Loads a JSON file as a configuration source. Supports loading from both filesystem and classpath (including JAR resources). If the file doesn't exist, it's silently skipped. If the file exists but is invalid, throws a runtime exception.
        Parameters:
        filePath - path to the JSON file (filesystem or classpath)
      • loadYaml

        public static void loadYaml​(String filePath)
        Loads a YAML file as a configuration source. Supports loading from both filesystem and classpath (including JAR resources). If the file doesn't exist, it's silently skipped. If the file exists but is invalid, throws a runtime exception.
        Parameters:
        filePath - path to the YAML file (filesystem or classpath)
      • loadToml

        public static void loadToml​(String filePath)
        Loads a TOML file as a configuration source. Loads all top-level keys (not nested in environment sections). Supports loading from both filesystem and classpath (including JAR resources). If the file doesn't exist, it's silently skipped. If the file exists but is invalid, throws a runtime exception.
        Parameters:
        filePath - path to the TOML file (filesystem or classpath)
      • loadToml

        public static void loadToml​(String filePath,
                                    String environment)
        Loads a TOML file as a configuration source for a specific environment. Only configuration from the specified environment section is loaded. Supports loading from both filesystem and classpath (including JAR resources). If the file doesn't exist, it's silently skipped. If the file exists but is invalid or the environment section doesn't exist, throws a runtime exception.
        Parameters:
        filePath - path to the TOML file (filesystem or classpath)
        environment - the environment section to load (e.g., "uat", "beta", "qa", "prod")
      • loadJson

        public static void loadJson​(String filePath,
                                    String environment)
        Loads a JSON file as a configuration source for a specific environment. Only configuration from the specified environment section is loaded. Supports loading from both filesystem and classpath (including JAR resources). If the file doesn't exist, it's silently skipped. If the file exists but is invalid or the environment section doesn't exist, throws a runtime exception.
        Parameters:
        filePath - path to the JSON file (filesystem or classpath)
        environment - the environment section to load (e.g., "uat", "beta", "qa", "prod")
      • loadYaml

        public static void loadYaml​(String filePath,
                                    String environment)
        Loads a YAML file as a configuration source for a specific environment. Only configuration from the specified environment section is loaded. Supports loading from both filesystem and classpath (including JAR resources). If the file doesn't exist, it's silently skipped. If the file exists but is invalid or the environment section doesn't exist, throws a runtime exception.
        Parameters:
        filePath - path to the YAML file (filesystem or classpath)
        environment - the environment section to load (e.g., "uat", "beta", "qa", "prod")
      • loadGlobalConfig

        public static void loadGlobalConfig()
        Loads global/common configuration files that apply to all environments. Automatically looks for and loads the following files if they exist:
        • global.properties
        • global.json
        • global.yaml
        • global.toml
        • common.properties
        • common.json
        • common.yaml
        • common.toml

        Files that don't exist are silently skipped. This method should be called before loading environment-specific configuration to establish a baseline configuration that can be overridden by environment-specific values.

        Example usage:

         // Load global configuration first
         ConfNG.loadGlobalConfig();
        
         // Then load environment-specific configuration (which can override global values)
         ConfNG.loadConfigForEnvironment("uat");
         
      • loadConfigForEnvironment

        public static void loadConfigForEnvironment​(String environment)
        Loads all environment-specific configuration files for the given environment. Automatically looks for and loads the following files if they exist:
        • {environment}.properties
        • {environment}.json
        • {environment}.yaml
        • {environment}.toml

        Files that don't exist are silently skipped. This method provides a convenient way to load all configuration for a specific environment with a single call.

        Note: For best practices, call loadGlobalConfig() before this method to load global/common configuration that applies to all environments. Environment-specific values will override global values due to the loading order.

        Parameters:
        environment - the environment name (e.g., "env1", "env2", "env3")
      • autoLoadConfig

        public static String autoLoadConfig()
        Automatically detects the current environment and loads appropriate configuration files.

        The environment is detected by checking the following configuration keys in order (respecting ConfNG's source precedence):

        1. APP_ENV (case-insensitive: app_env, App_Env, etc.)
        2. ENVIRONMENT (case-insensitive: environment, Environment, etc.)
        3. ENV (case-insensitive: env, Env, etc.)

        If no value is found in any configuration source, defaults to "local".

        This method uses ConfNG's own configuration resolution system, which means the environment can be set via any configuration source (environment variables, system properties, TestNG parameters, configuration files, etc.) according to the standard precedence order.

        Case Insensitivity: The key lookup is case-insensitive. For example, setting export app_env=production or export APP_ENV=production will both work.

        Once the environment is detected, this method calls loadConfigForEnvironment(String) to load all environment-specific configuration files.

        Returns:
        the detected environment name
      • getEnvironmentName

        public static String getEnvironmentName()
        Detects the current environment name by checking multiple configuration keys in order.

        This method checks the following keys in order (case-insensitive), returning the first non-null, non-empty value:

        1. APP_ENV (or app_env, App_Env, etc.)
        2. ENVIRONMENT (or environment, Environment, etc.)
        3. ENV (or env, Env, etc.)

        If none of these keys have a value, returns "local" as the default.

        This method uses ConfNG's configuration resolution system, respecting source precedence. For example, if APP_ENV is set as a TestNG parameter, it will take precedence over APP_ENV set as an environment variable.

        Case Insensitivity: The key lookup is case-insensitive, so APP_ENV, app_env, App_Env, etc. are all treated as the same key.

        Returns:
        the detected environment name, never null
      • loadSecretSource

        public static void loadSecretSource​(ConfigSource source)
        Loads a custom secret source.
        Parameters:
        source - the custom configuration source to add
      • resolveAllValues

        public static void resolveAllValues()
        Resolves all configuration values from all sources according to precedence. This method is called automatically when needed but can be called manually to force immediate resolution of all values.
      • resolveAllValues

        public static void resolveAllValues​(Set<String> keys)
        Resolves configuration values for the specified keys from all sources. If keys is null, attempts to discover all keys from known ConfNGKey implementations.
        Parameters:
        keys - specific keys to resolve, or null to discover all keys
      • get

        public static String get​(ConfNGKey key)
        Gets a configuration value for the given key.
        Parameters:
        key - the configuration key
        Returns:
        the configuration value, or the default value if not found
      • getOptional

        public static Optional<String> getOptional​(ConfNGKey key)
        Gets a configuration value as an Optional. Returns Optional.empty() if the value is not found and has no default.

        This method is useful when you want to handle missing configuration gracefully without null checks:

        
         Optional<String> dbUrl = ConfNG.getOptional(MyConfig.DATABASE_URL);
         dbUrl.ifPresent(url -> connectToDatabase(url));
         
        Parameters:
        key - the configuration key
        Returns:
        an Optional containing the value if present, empty otherwise
        Since:
        1.1.0
      • getRequired

        public static String getRequired​(ConfNGKey key)
        Gets a required configuration value. Throws ConfigurationException if the value is not found and has no default.

        Use this method when a configuration value is mandatory and the application cannot proceed without it:

        
         try {
             String dbUrl = ConfNG.getRequired(MyConfig.DATABASE_URL);
             connectToDatabase(dbUrl);
         } catch (ConfigurationException e) {
             System.err.println("Missing required config: " + e.getKey());
             System.exit(1);
         }
         
        Parameters:
        key - the configuration key
        Returns:
        the configuration value (never null)
        Throws:
        ConfigurationException - if the value is not found and has no default
        Since:
        1.1.0
      • getOrDefault

        public static String getOrDefault​(ConfNGKey key,
                                          String defaultValue)
        Gets a configuration value with a fallback default. Returns the provided default if the value is not found and the key has no default.

        This method is useful when you want to provide a runtime default that differs from the key's compile-time default:

        
         String timeout = ConfNG.getOrDefault(MyConfig.TIMEOUT, "60");
         
        Parameters:
        key - the configuration key
        defaultValue - the fallback default value
        Returns:
        the configuration value, or the provided default if not found
        Since:
        1.1.0
      • getInt

        public static Integer getInt​(ConfNGKey key)
        Gets a configuration value as an integer.
        Parameters:
        key - the configuration key
        Returns:
        the configuration value as integer, or null if not found and no default
        Throws:
        IllegalArgumentException - if the value cannot be converted to integer
      • getBoolean

        public static Boolean getBoolean​(ConfNGKey key)
        Gets a configuration value as a boolean.
        Parameters:
        key - the configuration key
        Returns:
        the configuration value as boolean, or null if not found and no default
        Throws:
        IllegalArgumentException - if the value cannot be converted to boolean
      • getLong

        public static Long getLong​(ConfNGKey key)
        Gets a configuration value as a long.
        Parameters:
        key - the configuration key
        Returns:
        the configuration value as long, or null if not found and no default
        Throws:
        IllegalArgumentException - if the value cannot be converted to long
        Since:
        1.1.0
      • getDouble

        public static Double getDouble​(ConfNGKey key)
        Gets a configuration value as a double.
        Parameters:
        key - the configuration key
        Returns:
        the configuration value as double, or null if not found and no default
        Throws:
        IllegalArgumentException - if the value cannot be converted to double
        Since:
        1.1.0
      • getList

        public static List<String> getList​(ConfNGKey key)
        Gets a configuration value as a list of strings. Values are split by comma and trimmed.

        Example: "a, b, c" becomes ["a", "b", "c"]

        Parameters:
        key - the configuration key
        Returns:
        the configuration value as a list, or null if not found and no default
        Since:
        1.1.0
      • getList

        public static List<String> getList​(ConfNGKey key,
                                           String delimiter)
        Gets a configuration value as a list of strings with a custom delimiter.
        Parameters:
        key - the configuration key
        delimiter - the delimiter to split values
        Returns:
        the configuration value as a list, or null if not found and no default
        Since:
        1.1.0
      • getDuration

        public static Duration getDuration​(ConfNGKey key)
        Gets a configuration value as a Duration. Supports formats: "30s" (seconds), "5m" (minutes), "2h" (hours), "1d" (days), "500ms" (milliseconds), or ISO-8601 duration format (e.g., "PT30S").

        Examples:

        • "30s" - 30 seconds
        • "5m" - 5 minutes
        • "2h" - 2 hours
        • "1d" - 1 day
        • "500ms" - 500 milliseconds
        • "PT30S" - ISO-8601 format for 30 seconds
        Parameters:
        key - the configuration key
        Returns:
        the configuration value as Duration, or null if not found and no default
        Throws:
        IllegalArgumentException - if the value cannot be parsed as a duration
        Since:
        1.1.0
      • getForDisplay

        public static String getForDisplay​(ConfNGKey key)
        Gets a configuration value with masking for sensitive data.
        Parameters:
        key - the configuration key
        Returns:
        the configuration value, masked if sensitive
      • getAllForDisplay

        public static String getAllForDisplay​(ConfNGKey... keys)
        Gets all configuration values for display purposes. Sensitive values are masked.
        Parameters:
        keys - the configuration keys to display
        Returns:
        a formatted string showing all configuration values
      • discoverAllConfigKeys

        public static List<ConfNGKey> discoverAllConfigKeys​(String... basePackages)
        Discovers all ConfNGKey implementations in the classpath.
        Parameters:
        basePackages - packages to scan, if empty scans entire classpath
        Returns:
        list of discovered configuration keys
      • refresh

        public static void refresh()
        Forces re-resolution of all configuration values. Useful when configuration sources might have changed.
      • getResolvedValueCount

        public static int getResolvedValueCount()
        Gets the number of resolved configuration values.
        Returns:
        number of resolved values
      • isResolved

        public static boolean isResolved()
        Checks if configuration values have been resolved.
        Returns:
        true if values are resolved, false otherwise
      • getResolvedKeys

        public static Set<String> getResolvedKeys()
        Gets all resolved configuration keys.
        Returns:
        set of all resolved keys
      • validate

        public static ValidationResult validate()
        Validates all discovered configuration keys against their defined constraints.

        This method scans all ConfNGKey implementations for validation annotations (Required, NotEmpty, Pattern, Range) and checks that the resolved values satisfy all constraints.

        Example usage:

        
         ValidationResult result = ConfNG.validate();
         if (!result.isValid()) {
             System.err.println(result.getSummary());
             throw new RuntimeException("Configuration validation failed");
         }
         
        Returns:
        the validation result containing any errors found
        Since:
        1.1.0
        See Also:
        ValidationResult, Required, NotEmpty, Pattern, Range
      • validate

        public static ValidationResult validate​(List<ConfNGKey> keys)
        Validates the specified configuration keys against their defined constraints.
        Parameters:
        keys - the configuration keys to validate
        Returns:
        the validation result containing any errors found
        Since:
        1.1.0
        See Also:
        validate()
      • validate

        public static ValidationResult validate​(ConfNGKey... keys)
        Validates the specified configuration keys against their defined constraints.
        Parameters:
        keys - the configuration keys to validate
        Returns:
        the validation result containing any errors found
        Since:
        1.1.0
        See Also:
        validate()
      • getSourceInfo

        public static ConfigSourceInfo getSourceInfo​(ConfNGKey key)
        Gets information about which source provided the value for a configuration key.

        This method is useful for debugging configuration issues and understanding the precedence of configuration sources:

        
         ConfigSourceInfo info = ConfNG.getSourceInfo(MyConfig.DATABASE_URL);
         System.out.println("Value: " + info.getValue());
         System.out.println("Source: " + info.getSourceName());
         System.out.println("Priority: " + info.getPriority());
         System.out.println("From default: " + info.isFromDefault());
         
        Parameters:
        key - the configuration key
        Returns:
        source information including source name, priority, and value
        Since:
        1.1.0
        See Also:
        ConfigSourceInfo
      • getAllSourceInfo

        public static Map<String,​ConfigSourceInfo> getAllSourceInfo​(ConfNGKey... keys)
        Gets source information for multiple configuration keys.
        Parameters:
        keys - the configuration keys to get info for
        Returns:
        map of key name to source information
        Since:
        1.1.0
        See Also:
        getSourceInfo(ConfNGKey)
      • getAllSourceInfo

        public static Map<String,​ConfigSourceInfo> getAllSourceInfo​(List<ConfNGKey> keys)
        Gets source information for a list of configuration keys.
        Parameters:
        keys - the configuration keys to get info for
        Returns:
        map of key name to source information
        Since:
        1.1.0
        See Also:
        getSourceInfo(ConfNGKey)
      • getByPrefix

        public static Map<String,​String> getByPrefix​(String prefix)
        Gets all configuration values that match a given prefix.

        This method is useful for retrieving groups of related configuration values:

        
         // Get all database-related configuration
         Map<String, String> dbConfig = ConfNG.getByPrefix("database.");
         // Returns: {"database.host": "localhost", "database.port": "5432", ...}
        
         // Get all API configuration
         Map<String, String> apiConfig = ConfNG.getByPrefix("api.");
         
        Parameters:
        prefix - the prefix to match (e.g., "database." or "app.")
        Returns:
        map of matching keys to their values
        Since:
        1.1.0
      • getKeysWithPrefix

        public static Set<String> getKeysWithPrefix​(String prefix)
        Gets all configuration keys that match a given prefix.

        This method returns only the key names, not the values:

        
         Set<String> dbKeys = ConfNG.getKeysWithPrefix("database.");
         // Returns: {"database.host", "database.port", "database.user", ...}
         
        Parameters:
        prefix - the prefix to match (e.g., "database." or "app.")
        Returns:
        set of matching keys
        Since:
        1.1.0
      • getFromSources

        public static String getFromSources​(String key)
        Gets a configuration value by string key directly from registered sources.

        This method bypasses the ConfNGKey enum and looks up values directly from all registered configuration sources. Useful for dynamic key lookups or integration with frameworks that use string-based property names.

        Example:

        
         // Direct lookup by string key
         String value = ConfNG.getFromSources("app.name");
        
         // Useful for Spring/Micronaut integration
         String dbUrl = ConfNG.getFromSources("spring.datasource.url");
         
        Parameters:
        key - the configuration key as a string
        Returns:
        the configuration value, or null if not found
        Since:
        1.1.0
      • getByPrefixWithInfo

        public static Map<String,​ConfigSourceInfo> getByPrefixWithInfo​(String prefix,
                                                                             List<ConfNGKey> keys)
        Gets all configuration values that match a given prefix, with source information.

        This method combines prefix matching with source diagnostics:

        
         List<ConfNGKey> allKeys = ConfNG.discoverAllConfigKeys();
         Map<String, ConfigSourceInfo> dbInfo = ConfNG.getByPrefixWithInfo("database.", allKeys);
         for (ConfigSourceInfo info : dbInfo.values()) {
             System.out.println(info.getKey() + " from " + info.getSourceName());
         }
         
        Parameters:
        prefix - the prefix to match
        keys - the ConfNGKey implementations to check for prefix matching
        Returns:
        map of matching keys to their source information
        Since:
        1.1.0
        See Also:
        getByPrefix(String), getSourceInfo(ConfNGKey)
      • addChangeListener

        public static void addChangeListener​(ConfigChangeListener listener)
        Adds a listener to be notified when configuration values change.

        Listeners are notified when configuration files are reloaded (either manually via refresh() or automatically when auto-reload is enabled).

        Example:

        
         ConfNG.addChangeListener(event -> {
             if (event.hasChanged("database.pool.size")) {
                 reconfigurePool(event.getNewValue("database.pool.size"));
             }
         });
         
        Parameters:
        listener - the listener to add
        Since:
        1.1.0
        See Also:
        ConfigChangeListener
      • removeChangeListener

        public static void removeChangeListener​(ConfigChangeListener listener)
        Removes a configuration change listener.
        Parameters:
        listener - the listener to remove
        Since:
        1.1.0
      • enableAutoReload

        public static void enableAutoReload()
                                     throws IOException
        Enables automatic reloading of configuration when files change.

        When enabled, ConfNG watches all loaded configuration files for changes. When a file is modified, the configuration is automatically reloaded and registered listeners are notified of any changes.

        Example:

        
         // Load configuration
         ConfNG.load("config.properties");
         ConfNG.load("config.yaml");
        
         // Enable auto-reload
         ConfNG.enableAutoReload();
        
         // Now any changes to config.properties or config.yaml will be detected
         
        Throws:
        IOException - if the file watch service cannot be started
        Since:
        1.1.0
      • enableAutoReload

        public static void enableAutoReload​(long debounceMs)
                                     throws IOException
        Enables automatic reloading with a custom debounce time.
        Parameters:
        debounceMs - minimum time in milliseconds between reloads for the same file
        Throws:
        IOException - if the file watch service cannot be started
        Since:
        1.1.0
      • disableAutoReload

        public static void disableAutoReload()
        Disables automatic reloading of configuration files.
        Since:
        1.1.0
      • isAutoReloadEnabled

        public static boolean isAutoReloadEnabled()
        Checks if automatic reloading is enabled.
        Returns:
        true if auto-reload is enabled
        Since:
        1.1.0
      • setEncryptionProvider

        public static void setEncryptionProvider​(EncryptionProvider provider)
        Sets the default encryption provider for decrypting configuration values.

        Configuration values marked with Encrypted or wrapped with encryption markers (e.g., "ENC(...)") will be automatically decrypted using this provider.

        Example:

        
         // Set up AES encryption from environment variable
         ConfNG.setEncryptionProvider(AesEncryptionProvider.fromEnvironment());
        
         // Now encrypted values will be automatically decrypted
         String password = ConfNG.get(MyConfig.DATABASE_PASSWORD);
         
        Parameters:
        provider - the encryption provider to use
        Since:
        1.1.0
        See Also:
        EncryptionProvider, AesEncryptionProvider
      • registerEncryptionProvider

        public static void registerEncryptionProvider​(String name,
                                                      EncryptionProvider provider)
        Registers a named encryption provider.

        Named providers can be referenced in the Encrypted annotation to use different encryption for different keys.

        Parameters:
        name - the provider name
        provider - the encryption provider
        Since:
        1.1.0
      • encrypt

        public static String encrypt​(String plainValue)
        Encrypts a value using the default encryption provider.

        This is useful for generating encrypted values to put in configuration files.

        Parameters:
        plainValue - the plain text value to encrypt
        Returns:
        the encrypted value (e.g., "ENC(base64data)")
        Throws:
        EncryptionException - if no provider is configured or encryption fails
        Since:
        1.1.0
      • encrypt

        public static String encrypt​(String plainValue,
                                     String providerName)
        Encrypts a value using a named encryption provider.
        Parameters:
        plainValue - the plain text value to encrypt
        providerName - the name of the encryption provider to use
        Returns:
        the encrypted value
        Throws:
        EncryptionException - if the provider is not found or encryption fails
        Since:
        1.1.0