Implement a memory-based UserStore and hook it in the properties.
authorChristos KK Loverdos <loverdos@gmail.com>
Tue, 13 Dec 2011 14:02:15 +0000 (16:02 +0200)
committerChristos KK Loverdos <loverdos@gmail.com>
Tue, 13 Dec 2011 14:02:15 +0000 (16:02 +0200)
logic/src/main/resources/aquarium.properties
logic/src/main/scala/gr/grnet/aquarium/MasterConf.scala
logic/src/main/scala/gr/grnet/aquarium/store/memory/MemUserStore.scala [new file with mode: 0644]
logic/src/test/scala/gr/grnet/aquarium/MasterConfTest.scala

index f0fa571..22164e7 100644 (file)
@@ -46,6 +46,8 @@ persistence.password=aquarium
 actor.provider.class=gr.grnet.aquarium.actor.SimpleLocalActorProvider
 # Class that initializes the REST service
 rest.service.class=gr.grnet.aquarium.rest.actor.RESTActorService
+# Class that implements the User store
+user.store.class=gr.grnet.aquarium.store.memory.MemUserStore
 
 # Comma separated list of exchanges known to aquarium
 amqp.exchanges=aquarium
index 0406263..ac21065 100644 (file)
@@ -43,13 +43,15 @@ import com.ckkloverdos.maybe.{Maybe, Failed, Just, NoVal}
 import com.ckkloverdos.convert.Converters.{DefaultConverters => TheDefaultConverters}
 import processor.actor.ConfigureDispatcher
 import rest.RESTService
+import store.UserStore
+import util.Loggable
 
 /**
  * The master configurator. Responsible to load all of application configuration and provide the relevant services.
  *
  * @author Christos KK Loverdos <loverdos@gmail.com>.
  */
-class MasterConf(val props: Props) {
+class MasterConf(val props: Props) extends Loggable {
   import MasterConf.Keys
 
   private[this] def newInstance[C : Manifest](className: String): C = {
@@ -64,11 +66,21 @@ class MasterConf(val props: Props) {
   }
 
   private[this] val _actorProvider: ActorProvider = {
-    newInstance[ActorProvider](props.getEx(Keys.actor_provider_class))
+    val instance = newInstance[ActorProvider](props.getEx(Keys.actor_provider_class))
+    logger.info("Loaded ActorProvider: %s".format(instance.getClass))
+    instance
   }
   
   private[this] val _restService: RESTService = {
-    newInstance[RESTService](props.getEx(Keys.rest_service_class))
+    val instance = newInstance[RESTService](props.getEx(Keys.rest_service_class))
+    logger.info("Loaded RESTService: %s".format(instance.getClass))
+    instance
+  }
+
+  private[this] val _userStore: UserStore = {
+    val instance = newInstance[UserStore](props.getEx(Keys.user_store_class))
+    logger.info("Loaded UserStore: %s".format(instance.getClass))
+    instance
   }
 
   def get(prop: String): String =
@@ -99,6 +111,8 @@ class MasterConf(val props: Props) {
   }
   
   def actorProvider = _actorProvider
+
+  def userStore = _userStore
 }
 
 object MasterConf {
@@ -208,6 +222,11 @@ object MasterConf {
     final val rest_service_class = "rest.service.class"
 
     /**
+     * The class that implements the User store
+     */
+    final val user_store_class = "user.store.class"
+
+    /**
      * Comma separated list of amqp servers running in active-active
      * configuration.
      */
diff --git a/logic/src/main/scala/gr/grnet/aquarium/store/memory/MemUserStore.scala b/logic/src/main/scala/gr/grnet/aquarium/store/memory/MemUserStore.scala
new file mode 100644 (file)
index 0000000..aa50600
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2011 GRNET S.A. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials
+ *      provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either expressed
+ * or implied, of GRNET S.A.
+ */
+
+package gr.grnet.aquarium.store.memory
+
+import gr.grnet.aquarium.user.UserState
+import gr.grnet.aquarium.Configurable
+import com.ckkloverdos.props.Props
+import gr.grnet.aquarium.store.{RecordID, UserStore}
+import com.ckkloverdos.maybe.{Just, Maybe}
+
+/**
+ * A user store backed by main memory.
+ *
+ * The IDs returned are the original user IDs.
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>
+ */
+
+class MemUserStore extends UserStore with Configurable {
+  private[this] val map = new java.util.concurrent.ConcurrentHashMap[String, UserState]()
+  
+  def configure(props: Props) = {
+  }
+
+  def storeUserState(userState: UserState): Maybe[RecordID] = {
+    map.put(userState.userId, userState)
+    Just(RecordID(userState.userId))
+  }
+
+  def findUserStateById(id: String) = {
+    Maybe(map.get(id))
+  }
+
+  def findUserStateByUserId(userID: String, atMost: Int) = findUserStateById(userID).toList
+}
\ No newline at end of file
index 07ea132..685732c 100644 (file)
@@ -68,4 +68,10 @@ class MasterConfTest {
     val ap = mc.actorProvider
     val dispatcher = ap.actorForRole(DispatcherRole)
   }
+
+  @Test
+  def testGetUserStore: Unit = {
+    val mc = MasterConf.MasterConf
+    val userStore = mc.userStore
+  }
 }
\ No newline at end of file