Revision 6adaafb6

b/logic/src/main/resources/aquarium.properties
23 23
# DO NOT TOUCH the following, unless you know what you are doing
24 24
# Actor subsystem
25 25
actor.provider.class=gr.grnet.aquarium.actor.SimpleLocalActorProvider
26
# Class that initializes the REST service
27
rest.service.class=gr.grnet.aquarium.rest.actor.RESTActorService
26 28

  
27 29
# Comma separated list of exchanges known to aquarium
28 30
amqp.exchanges=aquarium
b/logic/src/main/scala/gr/grnet/aquarium/MasterConf.scala
41 41
import com.ckkloverdos.props.Props
42 42
import com.ckkloverdos.maybe.{Maybe, Failed, Just, NoVal}
43 43
import com.ckkloverdos.convert.Converters.{DefaultConverters => TheDefaultConverters}
44
import rest.RESTService
44 45

  
45 46
/**
46 47
 * The master configurator. Responsible to load all of application configuration and provide the relevant services.
......
50 51
class MasterConf(val props: Props) {
51 52
  import MasterConf.Keys
52 53

  
53
  private[this] val _actorProvider: ActorProvider = {
54
    val className = props.getEx(Keys.actor_provider_class)
55
    val actorProvider = defaultClassLoader.loadClass(className).newInstance().asInstanceOf[ActorProvider]
56
    
57
    actorProvider match {
54
  private[this] def newInstance[C : Manifest](className: String): C = {
55
    val c = defaultClassLoader.loadClass(className).newInstance().asInstanceOf[C]
56
    c match {
58 57
      case configurable: Configurable ⇒
59 58
        configurable configure props
59
        c
60
      case _ ⇒
61
        c
60 62
    }
63
  }
61 64

  
62
    actorProvider
65
  private[this] val _actorProvider: ActorProvider = {
66
    newInstance[ActorProvider](props.getEx(Keys.actor_provider_class))
67
  }
68
  
69
  private[this] val _restService: RESTService = {
70
    newInstance[RESTService](props.getEx(Keys.rest_service_class))
63 71
  }
64 72

  
65 73
  def get(prop: String): String =
......
69 77
    }
70 78

  
71 79
  def defaultClassLoader = Thread.currentThread().getContextClassLoader
80

  
81
  def startServices(): Unit = {
82
    _actorProvider.start()
83
    _restService.start()
84
  }
85

  
86
  def stopServices(): Unit = {
87
    _restService.stop()
88
    _actorProvider.stop()
89
    
90
//    akka.actor.Actor.registry.shutdownAll()
91
  }
92

  
93
  def stopServicesWithDelay(millis: Long) {
94
    Thread sleep millis
95
    stopServices()
96
  }
72 97
  
73 98
  def actorProvider = _actorProvider
74 99
}
......
175 200
    final val actor_provider_class = "actor.provider.class"
176 201

  
177 202
    /**
203
     * The class that initializes the REST service
204
     */
205
    final val rest_service_class = "rest.service.class"
206

  
207
    /**
178 208
     * Comma separated list of amqp servers running in active-active
179 209
     * configuration.
180 210
     */
b/logic/src/main/scala/gr/grnet/aquarium/actor/ActorProvider.scala
51 51
   */
52 52
  @throws(classOf[Exception])
53 53
  def actorForRole(role: ActorRole, hints: Props = Props.empty): ActorRef
54

  
55
  def start(): Unit
56

  
57
  def stop(): Unit
54 58
}
b/logic/src/main/scala/gr/grnet/aquarium/actor/SimpleLocalActorProvider.scala
47 47
 */
48 48
class SimpleLocalActorProvider extends ActorProvider with Configurable {
49 49
  def configure(props: Props): Unit = {
50
  }
51

  
52
  def start(): Unit = {
53
    for(role <- SimpleLocalActorProvider.KnownRoles) {
54
      actorForRole(role)
55
    }
56
  }
50 57

  
58
  def stop(): Unit = {
51 59
  }
52 60

  
53 61
  @throws(classOf[Exception])
b/logic/src/main/scala/gr/grnet/aquarium/rest/RESTService.scala
1
/*
2
 * Copyright 2011 GRNET S.A. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *
12
 *   2. Redistributions in binary form must reproduce the above
13
 *      copyright notice, this list of conditions and the following
14
 *      disclaimer in the documentation and/or other materials
15
 *      provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * The views and conclusions contained in the software and
31
 * documentation are those of the authors and should not be
32
 * interpreted as representing official policies, either expressed
33
 * or implied, of GRNET S.A.
34
 */
35

  
36
package gr.grnet.aquarium.rest
37

  
38
import gr.grnet.aquarium.Configurable
39

  
40
/**
41
 * 
42
 * @author Christos KK Loverdos <loverdos@gmail.com>.
43
 */
44
trait RESTService {
45
  def start(): Unit
46
  def stop(): Unit
47
}
b/logic/src/main/scala/gr/grnet/aquarium/rest/actor/RESTActorService.scala
1
/*
2
 * Copyright 2011 GRNET S.A. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *
12
 *   2. Redistributions in binary form must reproduce the above
13
 *      copyright notice, this list of conditions and the following
14
 *      disclaimer in the documentation and/or other materials
15
 *      provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * The views and conclusions contained in the software and
31
 * documentation are those of the authors and should not be
32
 * interpreted as representing official policies, either expressed
33
 * or implied, of GRNET S.A.
34
 */
35

  
36
package gr.grnet.aquarium.rest
37
package actor
38

  
39
import gr.grnet.aquarium.MasterConf
40
import gr.grnet.aquarium.actor.RESTRole
41
import _root_.akka.actor._
42
import cc.spray.can.{ClientConfig, HttpClient, ServerConfig, HttpServer}
43

  
44
/**
45
 * 
46
 * @author Christos KK Loverdos <loverdos@gmail.com>.
47
 */
48
class RESTActorService extends RESTService {
49
  private[this] var _port: Int = 8080
50
  private[this] var _restActor: ActorRef = _
51
  private[this] var _serverActor: ActorRef = _
52
  private[this] var _clientActor: ActorRef = _
53

  
54
  def start(): Unit = {
55
    val mc = MasterConf.MasterConf
56
    this._port = mc.props.getInt(MasterConf.Keys.rest_port).getOr(this._port)
57
    this._restActor = mc.actorProvider.actorForRole(RESTRole)
58
    // Start Spray subsystem
59
    val serverConfig = ServerConfig(port = _port)
60
    val clientConfig = ClientConfig()
61
    this._serverActor = Actor.actorOf(new HttpServer(serverConfig)).start()
62
    this._clientActor = Actor.actorOf(new HttpClient(clientConfig)).start()
63
  }
64

  
65
  def stop(): Unit = {
66
    this._serverActor ! PoisonPill
67
    this._clientActor ! PoisonPill
68
  }
69
}
b/logic/src/test/scala/gr/grnet/aquarium/rest/actor/RESTActorTest.scala
55 55
 */
56 56
class RESTActorTest {
57 57
  @Test
58
  def testOneCall: Unit = {
58
  def testPing: Unit = {
59 59
    // Initialize configuration subsystem
60 60
    val mc = MasterConf.MasterConf
61
    mc.startServices()
61 62
    val port = mc.props.getInt(MasterConf.Keys.rest_port).getOr(8080)
62
    // Initialize REST actor
63
    val rest = mc.actorProvider.actorForRole(RESTRole)
64
    // Initialize spray underlying server
65
    val server = Actor.actorOf(new SprayHttpServer()).start()
66
    val client = Actor.actorOf(new SprayHttpClient()).start()
67 63
    val dialog = SprayHttpDialog("localhost", port)
68 64

  
69 65
    val pingReq = HttpRequest(method = GET, uri = "/ping", headers = HttpHeader("Content-Type", "text/plain; charset=UTF-8")::Nil)
......
86 82
          fail("Got nothing")
87 83
      }
88 84
    }
89
    
90
    Thread.sleep(3000)
91
    server ! PoisonPill
92
    client ! PoisonPill
93
    Actor.registry.shutdownAll()
85

  
86
    mc.stopServicesWithDelay(1000)
94 87
  }
95 88
}

Also available in: Unified diff