Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use config-annotation for easier reading of config files #62

Open
hrj opened this issue Mar 17, 2015 · 6 comments
Open

use config-annotation for easier reading of config files #62

hrj opened this issue Mar 17, 2015 · 6 comments

Comments

@hrj
Copy link
Owner

hrj commented Mar 17, 2015

config-annotation provides macros for easier reading of config files.

@chidu8
Copy link
Contributor

chidu8 commented Aug 5, 2015

config-annotation should be used as follows:

Let's say i want to create a config file.

kafka {
  server {
    host = wacai.com
    port = 12306
  }
}

Instead of creating the kafka.config file, I have to create a trait like so :

@conf trait kafka {
  val server = new {
    val host = "wacai.com"
    val port = 12306
  }
}

and then whenever I want to use the config parameters, my class has to extend the trait like so

class myclass extends kafka {
val hostname = server.host
val port = server.port
}

There is a side effect. There will be a file called kafka.conf generated in src/main/resources

@chidu8
Copy link
Contributor

chidu8 commented Aug 5, 2015

I believe I have a good hang of it now. Could you tell me where this will be useful in abandon. Where are the config files? I did a grep for config, but it gave too many results.

@hrj
Copy link
Owner Author

hrj commented Aug 5, 2015

In abandon, the config files are specified at run time through the command line flags.

I thought the macro library would be useful while reading the config files. The current code has to explicitly read every field. It would be cool if we could just say:

val config = ConfigFactory.parseFile(file).resolve()
val settings = magic[Settings](config)

where magic is some macro that figures out how to read Settings from the config file automatically, at compile time.

This is what I believed config-annotation is intended for, but I might be wrong.

@chidu8
Copy link
Contributor

chidu8 commented Aug 5, 2015

I like the idea of magic macros.

But I understood it as creating a trait after running wacai's example. I immediately saw the redundancy of the macro annotation in my comment above, because even if we don't have @conf, the code class myclass extends kafka {} still works! My understanding may be wrong ...

Could you please take a quick look and run this https://github.com/wacai/config-annotation-example
You need to clone to run. There is a Main.scala under common

@chidu8
Copy link
Contributor

chidu8 commented Aug 24, 2015

Hi @hrj

I was held up with other stuff for two weeks- sorry. I am back now :-)
I have used ficus to come up with a small prototype, just to understand and test the functionality:

import net.ceedubs.ficus.Ficus._
import com.typesafe.config.{Config, ConfigFactory}

case class Account(name: String, alias: String)

class ConfigParser{

  val config = ConfigFactory.parseString(
    """
      services {
        account  {
           name = "Assets:Current:Cash"
           alias = "cash"
         }
        report {
          title = "All"
          type = balance
          showZeroAmountAccounts = true
         }
       }
    """.stripMargin)
    import net.ceedubs.ficus.readers.ArbitraryTypeReader._
    val someAccount:Account = config.as[Account]("services.account")

}

object ConfigParser {
  def main(args: Array[String]) {
  val cf = new ConfigParser()
  println(cf.someAccount.name + "\n" + cf.someAccount.alias)
}
}

This is doing exactly what you suggested above. The line we are interested in is:

 val someAccount:Account = config.as[Account]("services.account")

However, there is one major issue:
If there is an instance variable in a class (say Account.scala) which does not have a default value and is not present in the config file we are reading, the config parser gives a runtime exception.
Any ideas on how to handle this (apart from defining default values for all variables) ?

@hrj
Copy link
Owner Author

hrj commented Aug 24, 2015

@chidu8 Looks like good progress.

About the exception, can you try using an Option type or a default argument. For example, if Account.alias is optional in the config file, you can try declaring Account as:

case class Account(name: String, alias: Option[String])

or with a default value:

case class Account(name:String, alias: String = "")

or a combination of the two approaches (especially for the alias example):

case class Account(name:String, alias: Option[String] = None)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants