arnaud briche
arnaud briche

Reputation: 1509

Converting Typesafe Config type to java.util.Properties

The title talks by itself, I have a Config object (from https://github.com/typesafehub/config) and I want to pass it the a constructor which only supports java.util.Properties as argument. Is there an easy way to convert a Config to a Properties object ?

Upvotes: 17

Views: 9402

Answers (4)

Louis B
Louis B

Reputation: 342

It is not possible directly through typesafe config. Even rending the entire hocon file into json does provide a true valid json: ex:

"play" : {
    "filters" : {
            "disabled" : ${?play.filters.disabled}[
            "play.filters.hosts.AllowedHostsFilter"
        ],
            "disabled" : ${?play.filters.disabled}[
            "play.filters.csrf.CSRFFilter"
        ]

    }
}

That format is directly from Config.render

as you can see, disabled is represented twice with hocon style syntax.

I have also had problems with rendering hocon -> json -> hocon

Example hocon:

  http {
   port = "9000"
   port = ${?HTTP_PORT}
 }

typesafe config would parse this to

{
  "http": {
    "port": "9000,${?HTTP_PORT}"
  }
}

However if you try to parse that in hocon - it throws a syntax error. the , cannot be there. The hocon correct parsing would be 9000${?HTTP_PORT} - with no comma between the values. I believe this is true for all array concatenation and substitution

Upvotes: 0

andr83
andr83

Reputation: 69

You can try my scala wrapper https://github.com/andr83/scalaconfig. Using it convert config object to java Properties is simple:

val properties = config.as[Properties]

Upvotes: 4

Christian Zen
Christian Zen

Reputation: 131

Here is a way to convert a typesafe Config object into a Properties java object. I have only tested it in a simple case for creating Kafka properties.

Given this configuration in application.conf

kafka-topics {
  my-topic {
    zookeeper.connect = "localhost:2181",
    group.id = "testgroup",
    zookeeper.session.timeout.ms = "500",
    zookeeper.sync.time.ms = "250",
    auto.commit.interval.ms = "1000"
  }
}

You can create the corresponding Properties object like that:

import com.typesafe.config.{Config, ConfigFactory}
import java.util.Properties
import kafka.consumer.ConsumerConfig

object Application extends App {

  def propsFromConfig(config: Config): Properties = {
    import scala.collection.JavaConversions._

    val props = new Properties()

    val map: Map[String, Object] = config.entrySet().map({ entry =>
      entry.getKey -> entry.getValue.unwrapped()
    })(collection.breakOut)

    props.putAll(map)
    props
  }

  val config = ConfigFactory.load()

  val consumerConfig = {
    val topicConfig = config.getConfig("kafka-topics.my-topic")
    val props = propsFromConfig(topicConfig)
    new ConsumerConfig(props)
  }

  // ...    
}

The function propsFromConfig is what you are mainly interested in, and the key points are the use of entrySet to get a flatten list of properties, and the unwrapped of the entry value, that gives an Object which type depends on the configuration value.

Upvotes: 13

Andreas Neumann
Andreas Neumann

Reputation: 10894

As typesafe config/hocon supports a much richer structure than java.util.propeties it will be hard to get a safe conversion.

Or spoken otherwise as properties can only express a subset of hocon the conversion is not clear, as it will have a possible information loss.

So if you configuration is rather flat and does not contain utf-8 then you could transform hocon to json and then extract the values.

A better solution would be to implement a ConfigClass and populate the values with values from hocon and passing this to the class you want to configure.

Upvotes: 1

Related Questions