com.typesafe.config.ConfigValueType Scala Examples

The following examples show how to use com.typesafe.config.ConfigValueType. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: RefTypeConfigConvertSpec.scala    From refined   with MIT License 5 votes vote down vote up
package eu.timepit.refined.pureconfig

import com.typesafe.config.ConfigValueType
import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.numeric.Positive
import org.scalacheck.Prop._
import org.scalacheck.Properties
import pureconfig._
import pureconfig.error.{CannotConvert, ConfigReaderFailures, ConvertFailure, WrongType}
import pureconfig.generic.auto._

class RefTypeConfigConvertSpec extends Properties("RefTypeConfigConvert") {

  type PosInt = Int Refined Positive
  case class Config(value: PosInt)

  property("load success") = secure {
    loadConfigWithValue("1") ?=
      Right(Config(1))
  }

  property("load failure (predicate)") = secure {
    val expected1 = Left(
      ConfigReaderFailures(
        ConvertFailure(
          reason = CannotConvert(
            value = "0",
            toType =
              "eu.timepit.refined.api.Refined[Int,eu.timepit.refined.numeric.Greater[shapeless.nat._0]]",
            because = "Predicate failed: (0 > 0)."
          ),
          location = None,
          path = "value"
        )
      )
    )

    // Allow "scala.Int" instead of just "Int" in the toType parameter.
    // For some reason Scala 2.12 with sbt 1.1.2 uses the former.
    val expected2 = Left(
      ConfigReaderFailures(
        ConvertFailure(
          reason = CannotConvert(
            value = "0",
            toType =
              "eu.timepit.refined.api.Refined[scala.Int,eu.timepit.refined.numeric.Greater[shapeless.nat._0]]",
            because = "Predicate failed: (0 > 0)."
          ),
          location = None,
          path = "value"
        )
      )
    )

    val actual = loadConfigWithValue("0")
    (actual ?= expected1) ||
    (actual ?= expected2)
  }

  property("load failure (wrong type)") = secure {
    loadConfigWithValue("abc") =?
      Left(
        ConfigReaderFailures(
          ConvertFailure(
            reason = WrongType(
              foundType = ConfigValueType.STRING,
              expectedTypes = Set(ConfigValueType.NUMBER)
            ),
            location = None,
            path = "value"
          )
        )
      )
  }

  property("roundtrip success") = secure {
    val config = Config(1)
    val configValue = ConfigConvert[Config].to(config)
    ConfigConvert[Config].from(configValue) ?=
      Right(config)
  }

  def loadConfigWithValue(value: String): Either[ConfigReaderFailures, Config] =
    ConfigSource.string(s"value = $value").load[Config]
} 
Example 2
Source File: ServiceNameMapper.scala    From lagom-akka-discovery-service-locator   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.client

import akka.discovery.Lookup
import com.typesafe.config.Config
import com.typesafe.config.ConfigObject
import com.typesafe.config.ConfigValueType
import org.slf4j.LoggerFactory

import scala.collection.JavaConverters._

private[lagom] class ServiceNameMapper(config: Config) {
  private val logger = LoggerFactory.getLogger(this.getClass)

  private val defaultPortName = readConfigValue(config, "defaults.port-name").toOption
  private val defaultPortProtocol = readConfigValue(config, "defaults.port-protocol").toOption
  private val defaultScheme = readConfigValue(config, "defaults.scheme").toOption

  sealed private trait ConfigValue {
    def toOption =
      this match {
        case NonEmpty(v) => Some(v)
        case _           => None
      }
  }
  private object ConfigValue {
    def apply(value: String) =
      if (value.trim.isEmpty) Empty
      else NonEmpty(value.trim)
  }
  private case object Undefined extends ConfigValue
  private case object Empty extends ConfigValue
  private case class NonEmpty(value: String) extends ConfigValue

  private def readConfigValue(config: Config, name: String) =
    if (config.hasPathOrNull(name)) {
      if (config.getIsNull(name)) Empty
      else ConfigValue(config.getString(name))
    } else Undefined

  private val serviceLookupMapping: Map[String, ServiceLookup] =
    config
      .getObject("service-name-mappings")
      .entrySet()
      .asScala
      .map { entry =>
        if (entry.getValue.valueType != ConfigValueType.OBJECT) {
          throw new IllegalArgumentException(
            s"Illegal value type in service-name-mappings: ${entry.getKey} - ${entry.getValue.valueType}")
        }
        val configEntry = entry.getValue.asInstanceOf[ConfigObject].toConfig

        val lookup: Lookup =
          readConfigValue(configEntry, "lookup").toOption
            .map(parseSrv)
            .getOrElse(Lookup(entry.getKey, defaultPortName, defaultPortProtocol))

        // if the user didn't explicitly set a value, use the default scheme,
        // otherwise honour user settings.
        val scheme =
          readConfigValue(configEntry, "scheme") match {
            case Undefined => defaultScheme
            // this is the case the user explicitly set the scheme to empty string
            case Empty           => None
            case NonEmpty(value) => Option(value)
          }

        entry.getKey -> ServiceLookup(lookup, scheme)
      }
      .toMap

  private def parseSrv(name: String) =
    if (Lookup.isValidSrv(name)) Lookup.parseSrv(name)
    else Lookup(name, defaultPortName, defaultPortProtocol)

  private[lagom] def mapLookupQuery(name: String): ServiceLookup = {
    val serviceLookup = serviceLookupMapping.getOrElse(name, ServiceLookup(parseSrv(name), defaultScheme))
    logger.debug("Lookup service '{}', mapped to {}", name: Any, serviceLookup: Any)
    serviceLookup
  }
}

private[lagom] case class ServiceLookup(lookup: Lookup, scheme: Option[String]) 
Example 3
Source File: ServiceNameMapper.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.client

import akka.discovery.Lookup
import com.typesafe.config.Config
import com.typesafe.config.ConfigObject
import com.typesafe.config.ConfigValueType
import org.slf4j.LoggerFactory

import scala.collection.JavaConverters._

private[lagom] class ServiceNameMapper(config: Config) {
  private val logger = LoggerFactory.getLogger(this.getClass)

  private val defaultPortName     = readConfigValue(config, "defaults.port-name").toOption
  private val defaultPortProtocol = readConfigValue(config, "defaults.port-protocol").toOption
  private val defaultScheme       = readConfigValue(config, "defaults.scheme").toOption

  private sealed trait ConfigValue {
    def toOption =
      this match {
        case NonEmpty(v) => Some(v)
        case _           => None
      }
  }
  private object ConfigValue {
    def apply(value: String) =
      if (value.trim.isEmpty) Empty
      else NonEmpty(value.trim)
  }
  private case object Undefined              extends ConfigValue
  private case object Empty                  extends ConfigValue
  private case class NonEmpty(value: String) extends ConfigValue

  private def readConfigValue(config: Config, name: String): ConfigValue =
    if (config.hasPathOrNull(name)) {
      if (config.getIsNull(name)) Empty
      else ConfigValue(config.getString(name))
    } else Undefined

  
  private def readOptionalConfigValue(config: Config, name: String, defaultValue: Option[String]): Option[String] =
    readConfigValue(config, name) match {
      case Undefined => defaultValue
      // this is the case the user explicitly set the scheme to empty string
      case Empty           => None
      case NonEmpty(value) => Option(value)
    }

  private val serviceLookupMapping: Map[String, ServiceLookup] =
    config
      .getObject("service-name-mappings")
      .entrySet()
      .asScala
      .map { entry =>
        if (entry.getValue.valueType != ConfigValueType.OBJECT) {
          throw new IllegalArgumentException(
            s"Illegal value type in service-name-mappings: ${entry.getKey} - ${entry.getValue.valueType}"
          )
        }
        val configEntry = entry.getValue.asInstanceOf[ConfigObject].toConfig

        // read config values for portName, portProtocol and scheme
        // when not explicitly overwritten by used, uses default values
        val portName     = readOptionalConfigValue(configEntry, "port-name", defaultPortName)
        val portProtocol = readOptionalConfigValue(configEntry, "port-protocol", defaultPortProtocol)
        val scheme       = readOptionalConfigValue(configEntry, "scheme", defaultScheme)

        val lookup: Lookup =
          readConfigValue(configEntry, "lookup").toOption
            .map(name => parseSrv(name, portName, portProtocol))
            .getOrElse(Lookup(entry.getKey, portName, portProtocol))

        entry.getKey -> ServiceLookup(lookup, scheme)
      }
      .toMap

  private def parseSrv(name: String, portName: Option[String], portProtocol: Option[String]) =
    if (Lookup.isValidSrv(name)) Lookup.parseSrv(name)
    else Lookup(name, portName, portProtocol)

  private[lagom] def mapLookupQuery(name: String): ServiceLookup = {
    val serviceLookup = serviceLookupMapping.getOrElse(
      name,
      ServiceLookup(parseSrv(name, defaultPortName, defaultPortProtocol), defaultScheme)
    )
    logger.debug("Lookup service '{}', mapped to {}", name: Any, serviceLookup: Any)
    serviceLookup
  }
}

private[lagom] case class ServiceLookup(lookup: Lookup, scheme: Option[String]) 
Example 4
Source File: ParameterValue.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.models

import com.typesafe.config.{Config, ConfigValue, ConfigValueType}
import com.typesafe.config.impl.ConfigInt
import de.frosner.broccoli.services.{ParameterNotFoundException, ParameterValueParsingException}
import org.apache.commons.lang3.StringEscapeUtils
import play.api.libs.json._

import scala.util.{Failure, Success, Try}

object ParameterValue {

  implicit val parameterValueWrites: Writes[ParameterValue] = new Writes[ParameterValue] {
    override def writes(paramValue: ParameterValue) = paramValue.asJsValue
  }

  def fromConfigValue(paramName: String, parameterType: ParameterType, configValue: ConfigValue): Try[ParameterValue] =
    Try {
      parameterType match {
        case ParameterType.Raw =>
          RawParameterValue(configValue.unwrapped().toString)
        case ParameterType.String =>
          StringParameterValue(configValue.unwrapped.asInstanceOf[String])
        case ParameterType.Integer =>
          val number = configValue.unwrapped().asInstanceOf[Number]
          //noinspection ComparingUnrelatedTypes
          if (number == number.intValue())
            IntParameterValue(number.intValue())
          else
            throw ParameterValueParsingException(paramName, s"${number.toString} is not a valid integer")
        case ParameterType.Decimal =>
          DecimalParameterValue(BigDecimal(configValue.unwrapped().asInstanceOf[Number].toString))
      }
    }

  def fromJsValue(parameterName: String,
                  parameterInfos: Map[String, ParameterInfo],
                  jsValue: JsValue): Try[ParameterValue] =
    Try {
      val parameterInfo =
        parameterInfos.getOrElse(parameterName, throw ParameterNotFoundException(parameterName, parameterInfos.keySet))
      fromJsValue(parameterInfo.`type`, jsValue) match {
        case Success(param) => param
        case Failure(ex) =>
          throw ParameterValueParsingException(parameterName, ex.getMessage)
      }
    }

  def fromJsValue(parameterType: ParameterType, jsValue: JsValue): Try[ParameterValue] =
    Try {
      parameterType match {
        case ParameterType.Raw =>
          RawParameterValue(jsValue.as[String])
        case ParameterType.String =>
          StringParameterValue(jsValue.as[String])
        case ParameterType.Integer =>
          IntParameterValue(jsValue.as[Int])
        case ParameterType.Decimal =>
          DecimalParameterValue(jsValue.as[BigDecimal])
      }
    }
}
sealed trait ParameterValue {

  
  def asJsonString: String
  def asJsValue: JsValue
}

case class IntParameterValue(value: Int) extends ParameterValue {
  override def asJsonString: String = value.toString
  override def asJsValue: JsValue = JsNumber(value)
}
case class DecimalParameterValue(value: BigDecimal) extends ParameterValue {
  override def asJsonString: String = value.toString
  override def asJsValue: JsValue = JsNumber(value)
}
case class StringParameterValue(value: String) extends ParameterValue {
  override def asJsonString: String = StringEscapeUtils.escapeJson(value)
  override def asJsValue: JsValue = JsString(value)
}
case class RawParameterValue(value: String) extends ParameterValue {
  override def asJsonString: String = value
  override def asJsValue: JsValue = JsString(value)
} 
Example 5
Source File: HoconInputTest.scala    From scala-commons   with MIT License 5 votes vote down vote up
package com.avsystem.commons
package hocon

import java.time.{Duration, Period}

import com.avsystem.commons.serialization.json.JsonStringOutput
import com.avsystem.commons.serialization.{GenCodecRoundtripTest, Input, Output}
import com.typesafe.config.{ConfigFactory, ConfigMemorySize, ConfigValue, ConfigValueFactory, ConfigValueType}

class HoconInputTest extends GenCodecRoundtripTest {
  type Raw = ConfigValue

  def writeToOutput(write: Output => Unit): ConfigValue = {
    val sb = new JStringBuilder
    write(new JsonStringOutput(sb))
    val config = ConfigFactory.parseString(s"""{"f":${sb.toString}}""")
    if (config.getIsNull("f")) ConfigValueFactory.fromAnyRef(null) else config.getValue("f")
  }

  def createInput(raw: ConfigValue): Input =
    new HoconInput(raw)

  def rawInput(any: Any): HoconInput =
    new HoconInput(ConfigValueFactory.fromAnyRef(any))

  test("value type reading") {
    assert(rawInput(null).valueType == ConfigValueType.NULL)
    assert(rawInput("kek").valueType == ConfigValueType.STRING)
    assert(rawInput(42).valueType == ConfigValueType.NUMBER)
    assert(rawInput(true).valueType == ConfigValueType.BOOLEAN)
    assert(rawInput(JMap()).valueType == ConfigValueType.OBJECT)
    assert(rawInput(JList()).valueType == ConfigValueType.LIST)
  }

  test("duration reading") {
    assert(rawInput("34s").readDuration() == Duration.ofSeconds(34))
  }

  test("period reading") {
    assert(rawInput("5m").readPeriod() == Period.ofMonths(5))
  }

  test("temporal amount reading") {
    assert(rawInput("5 minutes").readTemporal() == Duration.ofMinutes(5))
    assert(rawInput("5 months").readTemporal() == Period.ofMonths(5))
  }

  test("size in bytes reading") {
    assert(rawInput("100M").readSizeInBytes() == 100 * 1024 * 1024L)
  }

  test("memory size reading") {
    assert(rawInput("100M").readMemorySize() == ConfigMemorySize.ofBytes(100 * 1024 * 1024L))
  }

  test("number reading") {
    assert(rawInput(42.0).readNumber().doubleValue == 42.0)
  }
} 
Example 6
Source File: TupleConvertersSuite.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.module.magnolia

import scala.collection.JavaConverters._
import scala.language.higherKinds

import com.typesafe.config.{ ConfigValueFactory, ConfigValueType }
import org.scalacheck.ScalacheckShapeless._
import pureconfig._
import pureconfig.error._
import pureconfig.module.magnolia.auto.reader._
import pureconfig.module.magnolia.auto.writer._

class TupleConvertersSuite extends BaseSuite {

  behavior of "ConfigConvert"

  // Check arbitrary Tuples
  checkArbitrary[Tuple1[Int]]
  checkArbitrary[(String, Int)]
  checkArbitrary[(Int, (Long, String), Boolean)]

  // Check arbitrary Tuples with custom types
  case class Foo(a: Int, b: String)
  checkArbitrary[(Long, Foo, Boolean, Foo)]

  // Check readers from objects and lists
  checkRead[(String, Int)](ConfigValueFactory.fromMap(Map("_1" -> "one", "_2" -> 2).asJava) -> (("one", 2)))
  checkRead[(String, Int)](ConfigValueFactory.fromMap(Map("0" -> "one", "1" -> 2).asJava) -> (("one", 2)))
  checkRead[(String, Int)](ConfigValueFactory.fromIterable(List("one", 2).asJava) -> (("one", 2)))

  // Check writers
  checkWrite[Tuple1[Int]](Tuple1(1) -> ConfigValueFactory.fromIterable(List(1).asJava))
  checkWrite[(String, Int)](("one", 2) -> ConfigValueFactory.fromIterable(List("one", 2).asJava))
  checkWrite[(Int, (Long, String), Boolean)]((1, (2l, "three"), false) -> ConfigValueFactory.fromIterable(List(1, List(2l, "three").asJava, false).asJava))

  // Check errors
  checkFailures[(String, Int)](
    ConfigValueFactory.fromAnyRef(Map("_1" -> "one", "_2" -> "two").asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.STRING, Set(ConfigValueType.NUMBER)), emptyConfigOrigin, "_2")))
  checkFailures[(String, Int)](
    ConfigValueFactory.fromIterable(List("one", "two").asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.STRING, Set(ConfigValueType.NUMBER)), emptyConfigOrigin, "1")))

  checkFailures[(Int, Int, Int)](
    ConfigValueFactory.fromIterable(List(1, "one").asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongSizeList(3, 2), emptyConfigOrigin, "")))

  checkFailures[(Int, Int, Int)](
    ConfigValueFactory.fromAnyRef(Map("_1" -> "one", "_2" -> 2).asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.STRING, Set(ConfigValueType.NUMBER)), emptyConfigOrigin, "_1"),
      ConvertFailure(KeyNotFound("_3", Set()), emptyConfigOrigin, "")))

  checkFailures[(String, Int)](
    ConfigValueFactory.fromAnyRef("str") -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.STRING, Set(ConfigValueType.LIST)), emptyConfigOrigin, "")))
} 
Example 7
Source File: EnumCoproductHint.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.generic

import com.typesafe.config.{ ConfigObject, ConfigValue, ConfigValueType }
import pureconfig._
import pureconfig.error._
import pureconfig.generic.CoproductHint.Use
import pureconfig.generic.error.{ CoproductHintException, NoValidCoproductOptionFound }
import pureconfig.syntax._


  protected def fieldValue(name: String): String = name.toLowerCase

  def from(cursor: ConfigCursor, options: Seq[String]): ConfigReader.Result[CoproductHint.Action] =
    cursor.asString.right.flatMap { str =>
      options.find(str == fieldValue(_)) match {
        case Some(opt) => Right(Use(cursor, opt))
        case None => cursor.failed[CoproductHint.Action](NoValidCoproductOptionFound(cursor.value, Seq.empty))
      }
    }

  def to(value: ConfigValue, name: String): ConfigValue =
    value match {
      case co: ConfigObject if co.isEmpty => fieldValue(name).toConfig
      case _: ConfigObject =>
        throw CoproductHintException(NonEmptyObjectFound(name))
      case cv =>
        throw CoproductHintException(WrongType(cv.valueType, Set(ConfigValueType.OBJECT)))
    }
} 
Example 8
Source File: CollectionConvertersSuite.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig

import scala.collection.JavaConverters._
import scala.collection.immutable.{ HashSet, ListSet, Queue, TreeSet }

import com.typesafe.config.{ ConfigFactory, ConfigValueFactory, ConfigValueType }
import pureconfig.error.{ ConfigReaderFailures, ConvertFailure, WrongType }

class CollectionConvertersSuite extends BaseSuite {
  implicit override val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 100)

  behavior of "ConfigConvert"

  checkArbitrary[HashSet[String]]

  checkArbitrary[List[Float]]
  checkRead[List[Int]](
    // order of keys maintained
    ConfigValueFactory.fromMap(Map("2" -> 1, "0" -> 2, "1" -> 3).asJava) -> List(2, 3, 1),
    ConfigValueFactory.fromMap(Map("3" -> 2, "1" -> 4).asJava) -> List(4, 2),
    ConfigValueFactory.fromMap(Map("1" -> 1, "a" -> 2).asJava) -> List(1))

  checkFailures[List[Int]](
    ConfigValueFactory.fromMap(Map("b" -> 1, "a" -> 2).asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.OBJECT, Set(ConfigValueType.LIST)), emptyConfigOrigin, "")),
    ConfigValueFactory.fromMap(Map().asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.OBJECT, Set(ConfigValueType.LIST)), emptyConfigOrigin, "")))

  checkArbitrary[ListSet[Int]]

  checkArbitrary[Map[String, Int]]
  checkFailures[Map[String, Int]](
    // nested map should fail
    ConfigFactory.parseString("conf.a=1").root() -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.OBJECT, Set(ConfigValueType.NUMBER)), stringConfigOrigin(1), "conf")),
    // wrong value type should fail
    ConfigFactory.parseString("{ a=b }").root() -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.STRING, Set(ConfigValueType.NUMBER)), stringConfigOrigin(1), "a")))

  checkArbitrary[Queue[Boolean]]

  checkArbitrary[Set[Double]]
  checkRead[Set[Int]](
    ConfigValueFactory.fromMap(Map("1" -> 4, "2" -> 5, "3" -> 6).asJava) -> Set(4, 5, 6))

  checkArbitrary[Stream[String]]

  checkArbitrary[TreeSet[Int]]

  checkArbitrary[Vector[Short]]

  checkArbitrary[Option[Int]]

  checkArbitrary[Array[Int]]
} 
Example 9
Source File: EnumerationsSuite.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig

import com.typesafe.config.{ ConfigFactory, ConfigValueFactory, ConfigValueType }
import pureconfig.error.WrongType
import pureconfig.generic.error.NoValidCoproductOptionFound
import pureconfig.generic.semiauto._
import shapeless.test.illTyped

class EnumerationsSuite extends BaseSuite {

  sealed trait Color
  case object RainyBlue extends Color
  case object SunnyYellow extends Color

  val conf = ConfigFactory.parseString("{ type: person, name: John, surname: Doe }")

  behavior of "deriveEnumeration"

  it should "provide methods to derive readers for enumerations encoded as sealed traits" in {
    implicit val colorReader = deriveEnumerationReader[Color]

    ConfigReader[Color].from(ConfigValueFactory.fromAnyRef("rainy-blue")) shouldBe Right(RainyBlue)
    ConfigReader[Color].from(ConfigValueFactory.fromAnyRef("sunny-yellow")) shouldBe Right(SunnyYellow)

    val unknownValue = ConfigValueFactory.fromAnyRef("blue")
    ConfigReader[Color].from(unknownValue) should failWith(NoValidCoproductOptionFound(unknownValue, Seq.empty), "", emptyConfigOrigin)
    ConfigReader[Color].from(conf.root()) should failWith(WrongType(ConfigValueType.OBJECT, Set(ConfigValueType.STRING)), "", stringConfigOrigin(1))
  }

  it should "provide methods to derive writers for enumerations encoded as sealed traits" in {
    implicit val colorWriter = deriveEnumerationWriter[Color]

    ConfigWriter[Color].to(RainyBlue) shouldEqual ConfigValueFactory.fromAnyRef("rainy-blue")
    ConfigWriter[Color].to(SunnyYellow) shouldEqual ConfigValueFactory.fromAnyRef("sunny-yellow")
  }

  it should "provide methods to derive full converters for enumerations encoded as sealed traits" in {
    implicit val colorConvert = deriveEnumerationConvert[Color]

    ConfigConvert[Color].from(ConfigValueFactory.fromAnyRef("rainy-blue")) shouldBe Right(RainyBlue)
    ConfigConvert[Color].from(ConfigValueFactory.fromAnyRef("sunny-yellow")) shouldBe Right(SunnyYellow)
    ConfigConvert[Color].to(RainyBlue) shouldEqual ConfigValueFactory.fromAnyRef("rainy-blue")
    ConfigConvert[Color].to(SunnyYellow) shouldEqual ConfigValueFactory.fromAnyRef("sunny-yellow")
  }

  it should "provide customizable methods to derive readers for enumerations encoded as sealed traits" in {
    implicit val colorReader = deriveEnumerationReader[Color](ConfigFieldMapping(PascalCase, SnakeCase))

    ConfigReader[Color].from(ConfigValueFactory.fromAnyRef("rainy_blue")) shouldBe Right(RainyBlue)
    ConfigReader[Color].from(ConfigValueFactory.fromAnyRef("sunny_yellow")) shouldBe Right(SunnyYellow)
  }

  it should "provide customizable methods to derive writers for enumerations encoded as sealed traits" in {
    implicit val colorWriter = deriveEnumerationWriter[Color](ConfigFieldMapping(PascalCase, SnakeCase))

    ConfigWriter[Color].to(RainyBlue) shouldEqual ConfigValueFactory.fromAnyRef("rainy_blue")
    ConfigWriter[Color].to(SunnyYellow) shouldEqual ConfigValueFactory.fromAnyRef("sunny_yellow")
  }

  it should "provide customizable methods to derive full converters for enumerations encoded as sealed traits" in {
    implicit val colorConvert = deriveEnumerationConvert[Color](ConfigFieldMapping(PascalCase, SnakeCase))

    ConfigConvert[Color].from(ConfigValueFactory.fromAnyRef("rainy_blue")) shouldBe Right(RainyBlue)
    ConfigConvert[Color].from(ConfigValueFactory.fromAnyRef("sunny_yellow")) shouldBe Right(SunnyYellow)
    ConfigConvert[Color].to(RainyBlue) shouldEqual ConfigValueFactory.fromAnyRef("rainy_blue")
    ConfigConvert[Color].to(SunnyYellow) shouldEqual ConfigValueFactory.fromAnyRef("sunny_yellow")
  }

  it should "not allow deriving readers, writers and full converters for enumerations encoded as sealed traits whose subclasses are not all case objects" in {

    illTyped("deriveEnumerationReader[Entity]")
    illTyped("deriveEnumerationWriter[Entity]")
    illTyped("deriveEnumerationConvert[Entity]")
  }
} 
Example 10
Source File: TupleConvertersSuite.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig

import scala.collection.JavaConverters._

import com.typesafe.config.{ ConfigValueFactory, ConfigValueType }
import org.scalacheck.ScalacheckShapeless._
import pureconfig.error._
import pureconfig.generic.auto._

class TupleConvertersSuite extends BaseSuite {

  behavior of "ConfigConvert"

  // Check arbitrary Tuples
  checkArbitrary[Tuple1[Int]]
  checkArbitrary[(String, Int)]
  checkArbitrary[(Int, (Long, String), Boolean)]

  // Check arbitrary Tuples with custom types
  case class Foo(a: Int, b: String)
  checkArbitrary[(Long, Foo, Boolean, Foo)]

  // Check readers from objects and lists
  checkRead[(String, Int)](ConfigValueFactory.fromMap(Map("_1" -> "one", "_2" -> 2).asJava) -> (("one", 2)))
  checkRead[(String, Int)](ConfigValueFactory.fromMap(Map("0" -> "one", "1" -> 2).asJava) -> (("one", 2)))
  checkRead[(String, Int)](ConfigValueFactory.fromIterable(List("one", 2).asJava) -> (("one", 2)))

  // Check writers
  checkWrite[Tuple1[Int]](Tuple1(1) -> ConfigValueFactory.fromIterable(List(1).asJava))
  checkWrite[(String, Int)](("one", 2) -> ConfigValueFactory.fromIterable(List("one", 2).asJava))
  checkWrite[(Int, (Long, String), Boolean)]((1, (2l, "three"), false) -> ConfigValueFactory.fromIterable(List(1, List(2l, "three").asJava, false).asJava))

  // Check errors
  checkFailures[(String, Int)](
    ConfigValueFactory.fromAnyRef(Map("_1" -> "one", "_2" -> "two").asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.STRING, Set(ConfigValueType.NUMBER)), emptyConfigOrigin, "_2")))
  checkFailures[(String, Int)](
    ConfigValueFactory.fromIterable(List("one", "two").asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.STRING, Set(ConfigValueType.NUMBER)), emptyConfigOrigin, "1")))

  checkFailures[(Int, Int, Int)](
    ConfigValueFactory.fromIterable(List(1, "one").asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongSizeList(3, 2), emptyConfigOrigin, "")))

  checkFailures[(Int, Int, Int)](
    ConfigValueFactory.fromAnyRef(Map("_1" -> "one", "_2" -> 2).asJava) -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.STRING, Set(ConfigValueType.NUMBER)), emptyConfigOrigin, "_1"),
      ConvertFailure(KeyNotFound("_3", Set()), emptyConfigOrigin, "")))

  checkFailures[(String, Int)](
    ConfigValueFactory.fromAnyRef("str") -> ConfigReaderFailures(
      ConvertFailure(WrongType(ConfigValueType.STRING, Set(ConfigValueType.LIST)), emptyConfigOrigin, "")))
} 
Example 11
Source File: ConfigConvertSuite.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig

import com.typesafe.config.{ ConfigValue, ConfigValueFactory, ConfigValueType }
import org.scalacheck.{ Arbitrary, Gen }
import pureconfig.error.{ ExceptionThrown, WrongType, CannotConvert }
import ConfigConvertSuite._

class ConfigConvertSuite extends BaseSuite {
  implicit override val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 100)

  val intConvert = ConfigConvert[Int]

  // generate configs that always read correctly as strings, but not always as integers
  val genConfig: Gen[ConfigValue] =
    Gen.frequency(80 -> Gen.chooseNum(Int.MinValue, Int.MaxValue), 20 -> Gen.alphaStr)
      .map(ConfigValueFactory.fromAnyRef)

  implicit val arbConfig = Arbitrary(genConfig)

  behavior of "ConfigConvert"

  it should "have a correct xmap method" in forAll { (f: Int => String, g: String => Int) =>
    forAll { str: String => intConvert.xmap(f, g).to(str) shouldEqual intConvert.to(g(str)) }
    forAll { conf: ConfigValue => intConvert.xmap(f, g).from(conf) shouldEqual intConvert.from(conf).right.map(f) }
  }

  it should "have a xmap method that wraps exceptions in a ConfigReaderFailure" in {
    val throwable = new Exception("Exception message.")
    val cc = ConfigConvert[Int].xmap[String]({ _ => throw throwable }, { _: String => 42 })
    cc.from(ConfigValueFactory.fromAnyRef(1)) should failWith(
      ExceptionThrown(throwable))
    cc.from(ConfigValueFactory.fromAnyRef("test")) should failWith(
      WrongType(ConfigValueType.STRING, Set(ConfigValueType.NUMBER)))
  }

  it should "have a xemap method that allows specifying custom failure messages" in {
    ConfigConvert[EvenInt].from(ConfigValueFactory.fromAnyRef(1)) should
      failWith(CannotConvert("1", "EvenInt", EvenInt.err(1)))
  }

  it should "correctly read using xemap" in {
    ConfigConvert[EvenInt].from(ConfigValueFactory.fromAnyRef(2)) shouldEqual Right(EvenInt(2))
  }
}

object ConfigConvertSuite {
  case class EvenInt(i: Int) extends AnyVal
  object EvenInt {
    def err(i: Int): String = s"Cannot construct an EvenInt from $i because it's not even"

    def safely(i: Int): Either[String, EvenInt] =
      if (i % 2 == 0) Right(EvenInt(i)) else Left(err(i))

    implicit val configConvert: ConfigConvert[EvenInt] =
      ConfigConvert[Int].xemap(
        i => safely(i).left.map(s => CannotConvert(i.toString, "EvenInt", s)),
        _.i)
  }
} 
Example 12
Source File: ConfigReaderFailureOriginSuite.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig

import java.net.URL

import com.typesafe.config.{ ConfigFactory, ConfigValueType }
import org.scalatest.{ EitherValues, Inside }
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import pureconfig.error._
import pureconfig.generic.auto._


class ConfigReaderFailureOriginSuite extends BaseSuite with EitherValues with Inside {
  "Loading configuration from files" should "show proper error locations when loading a single file" in {
    import pureconfig.syntax._
    case class Conf(a: Int, b: String, c: Int)

    val workingDir = getClass.getResource("/").getFile
    val file = "conf/configFailureOrigin/single/a.conf"
    val conf = ConfigFactory.load(file).root()

    inside(conf.get("conf").to[Conf].left.value.toList) {
      case List(
        ConvertFailure(
          KeyNotFound("a", _),
          Some(origin1),
          ""),
        ConvertFailure(
          WrongType(ConfigValueType.STRING, valueTypes),
          Some(origin2),
          "c")
        ) =>
        origin1.filename() should endWith(file)
        origin1.url() shouldBe new URL("file", "", workingDir + file)
        origin1.lineNumber() shouldBe 1

        origin2.filename() should endWith(file)
        origin2.url() shouldBe new URL("file", "", workingDir + file)
        origin2.lineNumber() shouldBe 3
        valueTypes should contain only ConfigValueType.NUMBER

    }

    inside(conf.get("other-conf").to[Conf].left.value.toList) {
      case List(
        ConvertFailure(
          KeyNotFound("a", _),
          Some(origin1),
          ""),
        ConvertFailure(
          KeyNotFound("b", _),
          Some(origin2),
          ""),
        ConvertFailure(
          WrongType(ConfigValueType.STRING, valueTypes2),
          Some(origin3),
          "c")
        ) =>
        origin1.filename() should endWith(file)
        origin1.url shouldBe new URL("file", "", workingDir + file)
        origin1.lineNumber shouldBe 7

        origin2.filename() should endWith(file)
        origin2.url shouldBe new URL("file", "", workingDir + file)
        origin2.lineNumber shouldBe 7

        origin3.filename() should endWith(file)
        origin3.url shouldBe new URL("file", "", workingDir + file)
        origin3.lineNumber shouldBe 9
        valueTypes2 should contain only ConfigValueType.NUMBER
    }
  }

  it should "show proper error location when loading from multiple files" in {
    import pureconfig.syntax._
    case class Conf(a: Int, b: String, c: Int)

    val workingDir = getClass.getResource("/").getFile
    val file1 = "conf/configFailureOrigin/multiple/a.conf"
    val file2 = "conf/configFailureOrigin/multiple/b.conf"
    val conf = ConfigFactory.load(file1).withFallback(ConfigFactory.load(file2)).root()

    inside(conf.get("conf").to[Conf].left.value.toList) {
      case List(ConvertFailure(
        WrongType(ConfigValueType.STRING, valueTypes),
        Some(origin),
        "a")) =>
        valueTypes should contain only ConfigValueType.NUMBER
        origin.url() shouldBe new URL("file", "", workingDir + file2)
        origin.lineNumber() shouldBe 2

    }
  }
} 
Example 13
Source File: ClusterBuilder.scala    From quill   with Apache License 2.0 5 votes vote down vote up
package io.getquill.context.cassandra.cluster

import io.getquill.util.Messages._
import scala.util.Try
import com.typesafe.config.Config
import com.typesafe.config.ConfigValueType
import java.lang.reflect.Method
import scala.jdk.CollectionConverters._
import com.datastax.driver.core.Cluster

object ClusterBuilder {

  def apply(cfg: Config) =
    set(Cluster.builder, cfg)

  private def set[T](instance: T, cfg: Config): T = {
    for (key <- cfg.entrySet.asScala.map(_.getKey.split('.').head)) {

      def tryMethod(m: Method) =
        m.getParameterTypes.toList match {
          case Nil =>
            Try(cfg.getBoolean(key)).map {
              case true  => m.invoke(instance)
              case false =>
            }
          case tpe :: Nil =>
            param(key, tpe, cfg)
              .map(p => m.invoke(instance, p.asInstanceOf[AnyRef]))
          case tpe :: tail =>
            val c = cfg.getConfig(key)
            tail.foldLeft(param("0", tpe, c).map(List(_))) {
              case (list, tpe) =>
                list.flatMap { l =>
                  val key = s"${l.size}"
                  param(key, tpe, c).map(l :+ _)
                }
            }.map { params =>
              m.invoke(instance, params.asInstanceOf[List[Object]]: _*)
            }
        }

      def tryMethods(m: List[Method]): Any =
        m match {
          case Nil       => fail(s"Invalid config key '$key'")
          case m :: tail => tryMethod(m).getOrElse(tryMethods(tail))
        }

      tryMethods {
        instance.getClass.getMethods.toList.filter { m =>
          m.getName == key ||
            m.getName == s"with${key.capitalize}" ||
            m.getName == s"add${key.capitalize}" ||
            m.getName == s"set${key.capitalize}"
        }
      }
    }

    instance
  }

  val stringArrayClass = java.lang.reflect.Array.newInstance(classOf[String], 0).getClass()

  private def param(key: String, tpe: Class[_], cfg: Config) =
    Try {
      if (tpe == classOf[String])
        cfg.getString(key)
      else if (tpe == stringArrayClass)
        cfg.getStringList(key).asScala.toArray
      else if (tpe == classOf[Int] || tpe == classOf[Integer])
        cfg.getInt(key)
      else if (tpe.isEnum)
        tpe.getMethod("valueOf", classOf[String]).invoke(tpe, cfg.getString(key))
      else if (cfg.getValue(key).valueType == ConfigValueType.STRING)
        getClass.getClassLoader.loadClass(cfg.getString(key)).getConstructor().newInstance()
      else
        set(tpe.getConstructor().newInstance(), cfg.getConfig(key))
    }
} 
Example 14
Source File: EmailNotifierConfig.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package vinyldns.api.notifier.email

import scala.collection.JavaConverters._
import javax.mail.Address
import javax.mail.internet.InternetAddress
import pureconfig.ConfigReader
import scala.util.Try
import pureconfig.error.CannotConvert
import java.util.Properties
import com.typesafe.config.{ConfigObject, ConfigValue}
import com.typesafe.config.ConfigValueType

object EmailNotifierConfig {

  implicit val smtpPropertiesReader: ConfigReader[Properties] = {
    ConfigReader[ConfigObject].map { config =>
      val props = new Properties()

      def convertToProperties(baseKey: String, config: ConfigObject): Unit =
        config.keySet().asScala.foreach {
          case key =>
            config.get(key) match {
              case value: ConfigObject =>
                convertToProperties(s"${baseKey}.${key}", value)
              case value: ConfigValue if value.valueType != ConfigValueType.NULL =>
                props.put(s"${baseKey}.${key}", value.unwrapped())
              case _ =>
            }
        }

      convertToProperties("mail.smtp", config)
      props
    }
  }

  implicit val addressReader: ConfigReader[Address] = ConfigReader[String].emap { s =>
    Try(new InternetAddress(s)).toEither.left.map { exc =>
      CannotConvert(s, "InternetAddress", exc.getMessage)
    }
  }

}

case class EmailNotifierConfig(from: Address, smtp: Properties = new Properties()) 
Example 15
Source File: FunctionConfigStorage.scala    From mist   with Apache License 2.0 5 votes vote down vote up
package io.hydrosphere.mist.master.data

import java.io.File
import java.nio.file.Paths
import java.util.concurrent.Executors

import com.typesafe.config.{ConfigValueFactory, ConfigFactory, ConfigValueType, Config}
import io.hydrosphere.mist.master.models.FunctionConfig
import io.hydrosphere.mist.utils.Logger

import scala.collection.JavaConverters._
import scala.concurrent.{Future, ExecutionContext}
import scala.util._

class FunctionConfigStorage(
  fsStorage: FsStorage[FunctionConfig],
  val defaults: Seq[FunctionConfig]
)(implicit ex: ExecutionContext) {

  private val defaultMap = defaults.map(e => e.name -> e).toMap

  def all: Future[Seq[FunctionConfig]] =
    Future { fsStorage.entries } map (seq => {
      val merged = defaultMap ++ seq.map(a => a.name -> a).toMap
      merged.values.toSeq
    })

  def get(name: String): Future[Option[FunctionConfig]] = {
    Future { fsStorage.entry(name) } flatMap {
      case s @ Some(_) => Future.successful(s)
      case None => Future.successful(defaultMap.get(name))
    }
  }

  def delete(name: String): Future[Option[FunctionConfig]] = {
    Future { fsStorage.delete(name) }
  }

  def update(ec: FunctionConfig): Future[FunctionConfig] =
    Future { fsStorage.write(ec.name, ec) }

}

object FunctionConfigStorage extends Logger {

  def create(
    storagePath: String,
    defaultConfigPath: String): FunctionConfigStorage = {

    val defaults = fromDefaultsConfig(defaultConfigPath)
    val fsStorage = new FsStorage(checkDirectory(storagePath), ConfigRepr.EndpointsRepr)
    val ec = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(3))
    new FunctionConfigStorage(fsStorage, defaults)(ec)
  }

  def fromDefaultsConfig(path: String): Seq[FunctionConfig] = {
    val file = new File(path)
    if (!file.exists()) {
      Seq.empty
    } else {
      logger.warn("Starting using router conf (that feature will be removed - please use http api for uploading functions)")
      val directory = Paths.get(path).getParent
      val config = ConfigFactory.parseFile(file)
        .withValue("location", ConfigValueFactory.fromAnyRef(directory.toString))
        .resolve()
      parseConfig(config)
    }
  }

  def parseConfig(config: Config): Seq[FunctionConfig] = {
    def parse(name: String): Try[FunctionConfig] = Try {
      val part = config.getConfig(name)
      ConfigRepr.EndpointsRepr.fromConfig(name, part)
    }

    config.root().keySet().asScala
      .filter(k => config.getValue(k).valueType() == ConfigValueType.OBJECT)
      .map(name => parse(name))
      .foldLeft(List.empty[FunctionConfig])({
        case (lst, Failure(e)) =>
          logger.warn("Invalid configuration for function", e)
          lst
        case (lst, Success(c)) => lst :+ c
      })
  }
}