za.co.absa.enceladus.utils.config.ConfigReader.scala Maven / Gradle / Ivy
/*
* Copyright 2018 ABSA Group Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package za.co.absa.enceladus.utils.config
import com.typesafe.config._
import org.slf4j.LoggerFactory
import scala.collection.JavaConverters._
import za.co.absa.enceladus.utils.config.ConfigUtils.ConfigImplicits
object ConfigReader {
val redactedReplacement: String = "*****"
}
class ConfigReader(config: Config = ConfigFactory.load()) {
import ConfigReader._
private val log = LoggerFactory.getLogger(this.getClass)
def readStringConfigIfExist(path: String): Option[String] = {
config.getOptionString(path)
}
def readStringConfig(path: String, default: String): String = {
readStringConfigIfExist(path).getOrElse(default)
}
/**
* Given a configuration returns a new configuration which has all sensitive keys redacted.
*
* @param keysToRedact A set of keys to be redacted.
*/
def getRedactedConfig(keysToRedact: Set[String]): Config = {
def withAddedKey(accumulatedConfig: Config, key: String): Config = {
if (config.hasPath(key)) {
accumulatedConfig.withValue(key, ConfigValueFactory.fromAnyRef(redactedReplacement))
} else {
accumulatedConfig
}
}
val redactingConfig = keysToRedact.foldLeft(ConfigFactory.empty)(withAddedKey)
redactingConfig.withFallback(config)
}
/**
* Flattens TypeSafe config tree and returns the effective configuration
* while redacting sensitive keys.
*
* @param keysToRedact A set of keys for which should be redacted.
* @return the effective configuration as a map
*/
def getFlatConfig(keysToRedact: Set[String] = Set()): Map[String, AnyRef] = {
getRedactedConfig(keysToRedact).entrySet().asScala.map({ entry =>
entry.getKey -> entry.getValue.unwrapped()
}).toMap
}
/**
* Logs the effective configuration while redacting sensitive keys
* in HOCON format.
*
* @param keysToRedact A set of keys for which values shouldn't be logged.
*/
def logEffectiveConfigHocon(keysToRedact: Set[String] = Set()): Unit = {
val redactedConfig = getRedactedConfig(keysToRedact)
val renderOptions = ConfigRenderOptions.defaults()
.setComments(false)
.setOriginComments(false)
.setJson(false)
val rendered = redactedConfig.root().render(renderOptions)
log.info(s"Effective configuration:\n$rendered")
}
/**
* Logs the effective configuration while redacting sensitive keys
* in Properties format.
*
* @param keysToRedact A set of keys for which values shouldn't be logged.
*/
def logEffectiveConfigProps(keysToRedact: Set[String] = Set()): Unit = {
val redactedConfig = getFlatConfig(keysToRedact)
val rendered = redactedConfig.map {
case (k, v) => s"$k = $v"
}.toArray
.sortBy(identity)
.mkString("\n")
log.info(s"Effective configuration:\n$rendered")
}
}