Created
December 5, 2020 00:23
-
-
Save afsalthaj/6ab21159a968d489f13c291381b810ec to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package zio.config.examples | |
import java.lang.{ Boolean => JBoolean } | |
import scala.util.{ Failure, Success, Try } | |
import com.typesafe.config._ | |
import zio.config.typesafe._ | |
import zio.{ IO } | |
import zio.config._, ConfigDescriptor._ | |
/** | |
* Load a configuration from different sources based on the given | |
* configuration schema. | |
* | |
* Configuration is obtained in this order: | |
* 1. from command line arguments (the most visible one) | |
* 2. from environment variable | |
* 3. from service `application.conf` (with all the default values) | |
* | |
* Examples: | |
* - args:`--myConfig=111` & env:`MYCONFIG=222` => myConfig=111 | |
* - env:`MYCONFIG=111` & hocon:`myConfig:222` => myConfig=111 | |
* - args:`--myConfig=111` & hocon:`myConfig:222` => myConfig=111 | |
* | |
* It is possible for environment variables to come with a predefined | |
* prefix. This feature allows to get a specific namespace for your | |
* environment variables by using this prefix. See | |
* [[loadConfiguration]] for more details. | |
* | |
* Note: to ensure ensure source/data reconciliation (ie. matching) | |
* whatever case schema is used, every keys are converted | |
* lowercase. Eg. `--myConfig` is the same as `--myconfig` or | |
* `--MYCONFIG`. | |
* | |
* @param schema configuration schema | |
* @tparam A type of the configuration | |
*/ | |
case class ServiceConfigurationLoader[A <: ServiceParameters]( | |
schema: zio.config.ConfigDescriptor[A] | |
) { | |
/** | |
* Retrieve configuration values. | |
* | |
* For environment variables, you may provide you own prefix. Eg. if | |
* your config key is named `myConfig` and you provide `MY_SERVICE_` | |
* as prefix, then the descriptor will match with the environment | |
* variable `MY_SERVICE_MYCONFIG`. | |
* | |
* @param prefix prefix used to namespaced you environment variables | |
* @param args command line arguments | |
* @return configuration values or an error message | |
*/ | |
def loadConfiguration( | |
prefix: String, | |
args: List[String] | |
): IO[ReadError[String], A] = | |
for { | |
config <- getConfigProgram(prefix, args, schema) | |
serviceConfig <- IO.fromEither(read(config)) | |
} yield serviceConfig | |
private def getConfigProgram[A]( | |
prefix: String, | |
args: List[String], | |
configSchema: ConfigDescriptor[A] | |
): IO[ReadError[String], ConfigDescriptor[A]] = | |
for { | |
cmdConf <- IO.succeed( | |
ConfigSource.fromCommandLineArgs(args, Some(ServiceConfigurationLoader.CommandLineKeyDelimiter)) | |
) | |
sysConf <- ConfigSource.fromSystemEnvLive( | |
Some(ServiceConfigurationLoader.EnvVarKeyDelimiter), | |
Some(ServiceConfigurationLoader.EnvVarValueDelimiter) | |
) | |
ressConf <- configFromResources | |
updatedSchema = (configSchema from cmdConf) <> | |
(configSchema.mapKey(key => addPrefixToKey(prefix)(key).toUpperCase()) from sysConf) <> | |
(configSchema from ressConf) | |
} yield updatedSchema | |
private def configFromResources: IO[ReadError[String], ConfigSource] = | |
IO.fromEither(TypesafeConfigSource.fromTypesafeConfig(ConfigFactory.defaultApplication())) | |
} | |
object ServiceConfigurationLoader { | |
val CommandLineKeyDelimiter = '.' | |
val EnvVarKeyDelimiter = '_' | |
val EnvVarValueDelimiter = ',' | |
} | |
/** | |
* Base parameter trait to extends by every services. | |
*/ | |
trait ServiceParameters { | |
val serviceName: String | |
val kafka: KafkaConfig | |
} | |
case class KafkaConfig( | |
bootstrapServers: String, | |
schemaRegistryUrl: String, | |
performCleanup: Boolean = false | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment