Read configuration values from the cmd-line
authorGeorgios Gousios <gousiosg@gmail.com>
Tue, 7 Feb 2012 09:28:02 +0000 (11:28 +0200)
committerGeorgios Gousios <gousiosg@gmail.com>
Tue, 7 Feb 2012 09:30:59 +0000 (11:30 +0200)
src/main/scala/gr/grnet/aquarium/Configurator.scala

index 4267715..2d52385 100644 (file)
@@ -44,6 +44,9 @@ import com.ckkloverdos.convert.Converters.{DefaultConverters => TheDefaultConver
 import processor.actor.{UserEventProcessorService, ResourceEventProcessorService, EventProcessorService}
 import store._
 import util.{Lifecycle, Loggable}
+import java.net.URL
+import collection.mutable.Buffer
+import java.io.{ByteArrayInputStream, InputStream, Reader, BufferedReader}
 
 /**
  * The master configurator. Responsible to load all of application configuration and provide the relevant services.
@@ -86,6 +89,10 @@ class Configurator(val props: Props) extends Loggable {
     instance
   }
 
+  /**
+   * Initializes a store provider, according to the value configured
+   * in the configuration file. The
+   */
   private[this] lazy val _storeProvider: StoreProvider = {
     val instance = newInstance[StoreProvider](props.getEx(Keys.store_provider_class))
     logger.info("Loaded StoreProvider: %s".format(instance.getClass))
@@ -252,6 +259,11 @@ object Configurator {
   val ClasspathBaseResourceContext = new ClassLoaderStreamResourceContext(Thread.currentThread().getContextClassLoader)
 
   /**
+   * Last resort: read properties from the command line
+   */
+  val CmdLineResourceContext = new SysPropResourceContext
+
+  /**
    * Use this property to override the place where aquarium configuration resides.
    *
    * The value of this property is a folder that defines the highest-priority resource context.
@@ -262,7 +274,8 @@ object Configurator {
     NoVal,
     SlashEtcResourceContext,
     AppBaseResourceContext,
-    ClasspathBaseResourceContext)
+    ClasspathBaseResourceContext,
+    CmdLineResourceContext)
 
   /**
    * The resource context used in the application.
@@ -318,6 +331,17 @@ object Configurator {
    * Defines the names of all the known keys inside the master properties file.
    */
   final object Keys {
+
+    final val allKeys = List(version, actor_provider_class, rest_service_class,
+      store_provider_class, user_state_store_class, resource_event_store_class,
+      user_event_store_class, wallet_entry_store_class, policy_store_class,
+      user_actors_lru_lower_mark, user_actors_lru_upper_mark, amqp_servers,
+      amqp_port, amqp_username, amqp_password, amqp_vhost, amqp_exchanges,
+      rest_port, persistence_provider, persistence_host, persistence_username,
+      persistence_password, persistence_port, persistence_db,
+      mongo_connection_pool_size, aquarium_policy, user_state_timestamp_threshold,
+      time_unit_in_millis)
+
     /**
      * The Aquarium version. Will be reported in any due occasion.
      */
@@ -481,4 +505,39 @@ object Configurator {
      */
     final val time_unit_in_millis = "time.unit.in.seconds"
   }
+}
+
+/**
+ * Reads configuration keys from system properties.
+ */
+class SysPropResource extends StreamResourceSkeleton {
+
+  def exists = true
+  def url = new URL("cmd-line://")
+  def name = "cmdline"
+  def path = "cmdline"
+  def canonicalPath = "cmdline"
+
+  override def _inputStream: InputStream = {
+    val props = Configurator.Keys.allKeys.foldLeft(new StringBuffer()){
+      (b, k) =>
+        SysProp(k).value match {
+          case Just(x) =>
+            b.append(k).append("=").append(x).append("\n")
+          case _ => b
+        }
+    }
+
+    new ByteArrayInputStream(props.toString.getBytes("UTF-8"))
+  }
+}
+
+class SysPropResourceContext extends StreamResourceContextSkeleton(NoVal) {
+  def /(child: String) = null
+
+  override def getResource(path: String, normalized: Boolean) = Just(new SysPropResource)
+
+  def getLocalResource(path: String, normalized: Boolean) = Just(new SysPropResource)
+
+  override def toString = "SysPropResourceContext"
 }
\ No newline at end of file