Scala: создание универсального утилиты с PureConfig - PullRequest
3 голосов
/ 24 апреля 2019

Я ищу некоторые утилиты в scala, которые хорошо подходят под akka и могут сопоставлять HOCON с классом / объектом Scala. (Что-то вроде @Configuration в Spring, сопоставляющее файл .yml или .properties с компонентом конфигурации / классом Java.)

Что я пробовал с PureConfig :

spark.conf файл конфигурации в ресурсах

spark{
    master {
        host = 1.2.3.4
        port = 7077
    }
}

Отображение на следующие классы scala:

trait Configuration {
    val nameSpace: String
}

case class SparkConfig(master: SparkMasterConfig) extends Configuration {
    override val nameSpace: String = "spark"
}

case class SparkMasterConfig(host: String,
                                    port: Int)

PureConfig отлично работает без универсального:

import pureconfig.generic.auto._
import com.typesafe.config.ConfigFactory

val conf = ConfigFactory.parseResources("spark.conf")
val sparkConfig = pureconfig.loadConfig[SparkConfig]("spark")

val config = sparkConfig match {
    case Left(f) => fail(f.toString)
    case Right(c) => c
}

Однако следующий универсальный утилит даже не компилируется с not enough arguments for method error

object PureConfigLoader{
    def load[T <: Configuration](clazz: Class[T]): T = {
        val nameSpace = clazz.getField("nameSpace").get().asInstanceOf[String]

        import pureconfig.generic.auto._
        val configResult = pureconfig.loadConfig[T](nameSpace)  // this doesn't compile

        configResult match {
            case Right(x) => x.asInstanceOf[T]
            case Left(x) => throw new IllegalArgumentException(s"Fail to parse ${clazz.getSimpleName} from namespace $nameSpace")
        }
    }
}

val config = PureConfigLoader.load(classOf[SparkConfig])

Мои вопросы:

  1. Что я могу сделать с этим универсальным утилитой PureConfig?
  2. import pureconfig.generic.auto._ всегда помечается IntelliJ как неиспользуемый импорт, и он будет удален при форматировании моего кода, как это исправить?
  3. Существуют ли другие утилиты config / библиотека, работающие аналогичным образом? Я также попробовал circe-config , но все еще получил подобные проблемы. Simple Scala Config использует Scala Dynamic, который не подходит для рефакторинга, например, переименования поля свойства конфигурации.

Спасибо

1 Ответ

2 голосов
/ 24 апреля 2019

Я использую небольшую оболочку Typesafe config :

https://github.com/kxbmap/configs

Я попробовал ваш пример - это компилируется:

  object PureConfigLoader{
    def load[T <: MyConfig[T]](clazz: Class[T])(implicit A: Configs[T]): T = {
      val nameSpace = clazz.getField("nameSpace").get().asInstanceOf[String]

      val config = ConfigFactory.load("spark.conf")
        Configs[T].get(config, nameSpace) 
          .valueOrThrow(e=>
             new IllegalArgumentException(s"Fail to parse ${clazz.getSimpleName} from namespace $nameSpace: ${e.messages}" 
          )
      )
    }
  }

  val sparkConfig = PureConfigLoader.load(classOf[SparkConfig])

  abstract class MyConfig[T] (implicit A: Configs[T])

  case class SparkConfig() extends MyConfig[SparkConfig]

Обновление

Я только что увидел в нашем коде, что не может вообще нуждаться в этом классе Util! Мы используем:

val config = ConfigFactory.load("spark.conf")
val sparkConfig = Configs[SparkConfig].get(config, nameSpace) 
...