Using typesafe's config to manage my database connection
Asked Answered
T

1

6

This is normally a straight forward problem, but I'm not entirely sure how to solve this in Scala given that it is type sensitive. I have a class where I setup a simple connection to my MongoDB instance. Right now locally, I do the god awful notion of just commenting out the production config lines and uncommenting the local/dev ones. Here's what each one looks like:

// production
object MongoReplicaConnection {
    def mongoDb = {
      val addresses = List(new ServerAddress("10.1.1.2" , 27017),  new ServerAddress("10.1.1.3" , 27017),  new ServerAddress("10.1.1.4" , 27017))
      val mongoConn = MongoConnection(addresses) 
      val db = mongoConn("mydb")
      db
  }
}

// local development
object MongoReplicaConnection {
    def mongoDb = {
      val mongoConn = MongoConnection() 
      val db = mongoConn("mydb_local")
      db
    }
}

In as far as getting the database name passed in, that's trivial - it's just grabbing a string from the config file. Where I'm not able to think of a clean solution is how to handle the fact that I use a List of ServerAddress instances to initialize MongoConnection() vs not passing any List to MongoConnection in a local/dev setup.

How can you use a tool like typesafe's config here? I'm assuming I can just pass an empty List/array to MongoConnection() for a local db connection, but I'm not entirely sure how I can config the production database without modifying the mongoDb function. I've been looking at a tool such as this to help me with the process: https://github.com/typesafehub/config

Trifocals answered 7/9, 2013 at 1:53 Comment(0)
A
10

You can use the type safe config for this purpose.
You will have to define a file called application.conf which should be present in your classpath.
Typesafe config works by reading configurations defined in application.conf, reference.conf etc.
So first create a file called application.conf which should be in application classpath and define the configuration values like this

com.company.application {
  production {
    mongodb {
      servers=["10.1.1.2", "10.1.1.3"]
      password=pwd
    }
  }
  development {
    mongodb {
      servers=["10.1.1.2", "10.1.1.3"]
      password=pwd
    }
  }
  local {
    mongodb {
      servers=["127.0.0.1."]
      password=pwd
    } 
  }
}

Code to read the values will look something like this

 import com.typesafe.config.ConfigFactory
 import com.typesafe.config.Config

 object MongoReplicaConnection {

 def mongoDb = {

   val configNamespace = "com.company.application"
   val mergedCfg = ConfigFactory.load().getConfig(configNamespace)
   val env = getEnvironment // a util function, returns development or productoin or local
   // environment can be passed as jvm args and read from System properties
   val envCfg = mergedCfg.getConfig(env)
   val serverCfg = envCfg.getConfig("mongodb")
   val servers = serverCfg.getStringList("servers")
   // Servers will be a returned as List of Strings
   val pwd = serverCfg.getString("password")
   val addresses = servers map { new ServerAddress(_ , 27017) }
   val mongoConn = MongoConnection(addresses) 
   val db = mongoConn("mydb")
   db
 }
} 
Anaclinal answered 7/9, 2013 at 2:13 Comment(2)
This is on the right track, but it won't work because you can't just pass a list to MongoConnection. It is expecting a list of ServerAddress instances.Trifocals
I am not sure whether, i got your requirement correctly. I have slightly modified the solution. You cannot use any user defined classes/types within the configuration file.Anaclinal

© 2022 - 2024 — McMap. All rights reserved.