WIP.First cut of amqp-rabbit configuration-based api
authorChristos KK Loverdos <loverdos@gmail.com>
Mon, 21 Nov 2011 10:00:13 +0000 (12:00 +0200)
committerChristos KK Loverdos <loverdos@gmail.com>
Mon, 21 Nov 2011 10:00:13 +0000 (12:00 +0200)
34 files changed:
.gitignore
logic/pom.xml
logic/src/main/scala/gr/grnet/aquarium/messaging/GenericMessage.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfiguration.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfigurations.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConnection.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConsumer.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPProducer.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfiguration.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfigurations.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConnection.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConsumer.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQProducer.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/confmodel/confmodel.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/util/ConfModel.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/util/KnownResources.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/util/Validateable.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/util/package.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/util/xstream/ListConverter.scala [new file with mode: 0644]
logic/src/main/scala/gr/grnet/aquarium/util/xstream/XStreamHelpers.scala [new file with mode: 0644]
logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.properties [new file with mode: 0644]
logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.xml [new file with mode: 0644]
logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/aquarium_dev.properties [new file with mode: 0644]
logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/consumers/main_consumer.properties [new file with mode: 0644]
logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/producers/main_producer.properties [new file with mode: 0644]
logic/src/test/resources/rabbitmq/configuration.properties [new file with mode: 0644]
logic/src/test/resources/rabbitmq/configurations.xml [new file with mode: 0644]
logic/src/test/resources/rabbitmq/localhost/localhost.properties [new file with mode: 0644]
logic/src/test/resources/rabbitmq/localhost/localhost.xml [new file with mode: 0644]
logic/src/test/resources/rabbitmq/localhost/localhost/consumers/main_consumer.properties [new file with mode: 0644]
logic/src/test/resources/rabbitmq/localhost/localhost/localhost.properties [new file with mode: 0644]
logic/src/test/resources/rabbitmq/localhost/localhost/localhost.xml [new file with mode: 0644]
logic/src/test/resources/rabbitmq/localhost/localhost/producers/main_producer.properties [new file with mode: 0644]
logic/src/test/scala/gr/grnet/aquarium/messaging/MessagingTest.scala [new file with mode: 0644]

index 5497f3c..8d7c518 100644 (file)
@@ -16,3 +16,5 @@ bin/
 *.db
 lib_managed
 all-deps/
+project/
+projectFilesBackup/
index fe46329..4e96029 100644 (file)
@@ -34,7 +34,8 @@
   ~ or implied, of GRNET S.A.
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
     <dependency>
       <groupId>com.rabbitmq</groupId>
       <artifactId>amqp-client</artifactId>
-      <version>2.6.1</version>
+      <version>2.7.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.ckkloverdos</groupId>
+      <artifactId>streamresource_2.9.1</artifactId>
+      <version>0.1.1</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.thoughtworks.xstream</groupId>
+      <artifactId>xstream</artifactId>
+      <version>1.4.1</version>
     </dependency>
   </dependencies>
 </project>
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/GenericMessage.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/GenericMessage.scala
new file mode 100644 (file)
index 0000000..88455bd
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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.messaging
+
+import net.liftweb.json.{Extraction, parse => parseJson, DefaultFormats, Formats, JsonAST, Printer}
+import net.liftweb.json.ext.{JodaTimeSerializers}
+import net.liftweb.json.Xml
+
+/**
+ * The generic message format used within aquarium.
+ * All messages are transformed to this type for further processing within aquarium.
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+case class GenericMessage(
+    clientID: String,
+    clientEventID: String,
+    eventType: String,
+    eventTypeVersion: String,
+    timestamp: Long,
+    vmID: String,
+    vmFlavor: String,
+    other: Map[String, String]) {
+
+  def changedValue = other.get(GenericMessage.Keys.changedValue)
+  def aquariumEventID = other.get(GenericMessage.Keys.aquariumEventID)
+
+  def withAquariumEventID(aeid: String) = this.copy(other = other.updated(GenericMessage.Keys.aquariumEventID, aeid))
+  def withChangedValue(cv: String) = this.copy(other = other.updated(GenericMessage.Keys.changedValue, cv))
+
+  def toJValue: JsonAST.JValue = {
+    implicit val formats = GenericMessage.GenericMessageJsonFormats
+    Extraction.decompose(this)
+  }
+
+  def toJson: String = {
+    implicit val formats = GenericMessage.GenericMessageJsonFormats
+    Printer.pretty(JsonAST.render(this.toJValue))
+  }
+
+  def toBytes: Array[Byte] = {
+    toJson.getBytes("UTF-8")
+  }
+  
+  def toXml = Xml.toXml(toJValue)
+}
+
+object GenericMessage {
+  object Keys {
+    val changedValue    = "changedValue"
+    val aquariumEventID = "aquariumEventID"
+  }
+
+  val GenericMessageJsonFormats = DefaultFormats ++ JodaTimeSerializers.all
+
+  def fromJson(json: String): GenericMessage = {
+    implicit val formats = GenericMessageJsonFormats
+    val jsonAST = parseJson(json)
+    Extraction.extract(jsonAST)
+  }
+
+  def fromJValue(jsonAST: JsonAST.JValue): GenericMessage = {
+    implicit val formats = GenericMessageJsonFormats
+    Extraction.extract(jsonAST)
+  }
+
+  def fromBytes(bytes: Array[Byte]): GenericMessage = {
+    fromJson(new String(bytes, "UTF-8"))
+  }
+
+  def fromXml(xml: String): GenericMessage = {
+    fromJValue(Xml.toJson(scala.xml.XML.loadString(xml)))
+  }
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfiguration.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfiguration.scala
new file mode 100644 (file)
index 0000000..bbdd871
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.messaging.amqp
+
+import com.ckkloverdos.maybe.Maybe
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+trait AMQPConfiguration {
+  def name: String
+  def connections: List[AMQPConnection]
+
+  def connectionNames = connections.map(_.name)
+
+  def findConnection(name: String) = connections.find(_.name == name)
+}
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfigurations.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfigurations.scala
new file mode 100644 (file)
index 0000000..a1e3e27
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.messaging.amqp
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+trait AMQPConfigurations {
+  def configurations: List[AMQPConfiguration]
+
+  def configurationNames = configurations.map(_.name)
+
+  def findConfiguration(name: String): Option[AMQPConfiguration] = configurations.find(_.name == name)
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConnection.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConnection.scala
new file mode 100644 (file)
index 0000000..dacff4e
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.messaging.amqp
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+trait AMQPConnection {
+  def name: String
+
+  def producers: List[AMQPProducer]
+  def consumers: List[AMQPConsumer]
+
+  def producerNames = producers.map(_.name)
+  def consumerNames = consumers.map(_.name)
+
+  def findProducer(name: String): Option[AMQPProducer] = producers.find(_.name == name)
+  def findConsumer(name: String): Option[AMQPConsumer] = consumers.find(_.name == name)
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConsumer.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConsumer.scala
new file mode 100644 (file)
index 0000000..2cda8d5
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.messaging.amqp
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+trait AMQPConsumer {
+  def name: String
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPProducer.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPProducer.scala
new file mode 100644 (file)
index 0000000..46183fd
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.messaging.amqp
+
+import parallel.Future
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+trait AMQPProducer {
+  def name: String
+  def publish(message: String, headers: Map[String,  String] = Map()): Unit
+  def publishWithConfirm(message: String, headers: Map[String,  String] = Map()): Boolean
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfiguration.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfiguration.scala
new file mode 100644 (file)
index 0000000..295d69a
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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.messaging.amqp
+package rabbitmq
+package v091
+
+import com.rabbitmq.client.{Channel => JackRabbitChannel, Connection => JackRabbitConnection, ConnectionFactory => JackRabbitConnectionFactory}
+import confmodel.RabbitMQConfigurationModel
+import gr.grnet.aquarium.util.Loggable
+
+/**
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+class RabbitMQConfiguration(val confModel: RabbitMQConfigurationModel) extends AMQPConfiguration with Loggable {
+  private val underlyingConnectionFactory = new JackRabbitConnectionFactory
+
+  private val _name = confModel.name
+  def name = _name
+  
+  private lazy val _connections = confModel.connections.map(new RabbitMQConnection(_, underlyingConnectionFactory))
+  def connections = _connections
+}
+
+
+object RabbitMQConfiguration {
+
+  object RCFolders {
+    val rabbitmq = "rabbitmq"
+
+    val producers = "producers"
+    val consumers = "consumers"
+  }
+
+  object PropFiles {
+    val configurations = "configuration.properties"
+  }
+
+  object PropKeys {
+    val configurations = "configurations"
+
+    // configuration
+    val addresses = "addresses"
+    val username = "username"
+    val password = "password"
+    val host = "host"
+    val virtualHost = "virtualHost"
+    val port = "port"
+    val connections = "connections"
+
+    // connection
+    val exchange = "exchange"
+    val exchangeType = "exchangeType"
+    val exchangeIsDurable = "exchangeIsDurable"
+    val producers = "producers"
+    val consumers = "consumers"
+
+    // producer
+    val routingKey = "routingKey"
+
+    // consumer
+    val queue = "queue"
+  }
+
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfigurations.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfigurations.scala
new file mode 100644 (file)
index 0000000..4ac6216
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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.messaging.amqp
+package rabbitmq
+package v091
+
+
+import com.ckkloverdos.resource.StreamResourceContext
+import confmodel.RabbitMQConfigurationsModel
+import gr.grnet.aquarium.util.xstream.XStreamHelpers
+import com.ckkloverdos.maybe.{Failed, NoVal, Just, Maybe}
+import gr.grnet.aquarium.util.{ConfModel, Loggable, shortClassNameOf}
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+class RabbitMQConfigurations(val confModel: RabbitMQConfigurationsModel) extends AMQPConfigurations {
+  private val _configurations = confModel.configurations.map(new RabbitMQConfiguration(_))
+  def configurations = _configurations
+}
+
+object RabbitMQConfigurations extends Loggable {
+  object RCFolders {
+    val rabbitmq = "rabbitmq"
+
+    val producers = "producers"
+    val consumers = "consumers"
+  }
+
+  object PropFiles {
+//    val configurations = "configuration.properties"
+    val configurations = "configurations.xml"
+  }
+
+  def apply(baseRC: StreamResourceContext): Maybe[RabbitMQConfigurations] = {
+    val xs = XStreamHelpers.DefaultXStream
+    val rabbitMQRC = baseRC / RCFolders.rabbitmq
+
+    val maybeConfsResource = rabbitMQRC.getResource(PropFiles.configurations)
+    val maybeConfsModel = maybeConfsResource.flatMap(XStreamHelpers.parseType[RabbitMQConfigurationsModel](_, xs))
+
+    def logErrors(errors: List[ConfModel.ConfModelError], theClass: Class[_]): String = {
+      val errorMsg = "%s has %s error(s)".format(shortClassNameOf(theClass))
+      logger.error(errorMsg)
+      for(error <- errors) {
+        logger.error(error)
+      }
+      errorMsg
+    }
+
+    maybeConfsModel match {
+      case Just(confsModel) =>
+        // parsed <configurations>.xml (like: rabbitmq/configurations.xml)
+        // now have a RabbitMQConfigurationsModel
+        val confsModelErrors = confsModel.validateConfModel
+
+        if(confsModelErrors.size > 0) {
+          val errorMsg = logErrors(confsModelErrors, confsModel.getClass)
+          Failed(new Exception(errorMsg))
+        } else {
+          Just(new RabbitMQConfigurations(confsModel))
+        }
+      case NoVal =>
+        NoVal
+      case Failed(e, m) =>
+        Failed(e, m)
+    }
+  }
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConnection.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConnection.scala
new file mode 100644 (file)
index 0000000..532da64
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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.messaging.amqp
+package rabbitmq
+package v091
+
+import confmodel.RabbitMQConnectionModel
+import gr.grnet.aquarium.messaging.amqp.AMQPConnection
+
+import com.rabbitmq.client.{Channel => JackRabbitChannel, Connection => JackRabbitConnection, ConnectionFactory => JackRabbitConnectionFactory}
+
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+class RabbitMQConnection(val confModel: RabbitMQConnectionModel, underlyingConnectionFactory: JackRabbitConnectionFactory) extends AMQPConnection {
+  private[rabbitmq] val underlyingConnection: JackRabbitConnection = underlyingConnectionFactory.newConnection()
+
+  private val _name = confModel.name
+  def name = _name
+
+  private lazy val _producers = confModel.producers.map(new RabbitMQProducer(this, _))
+  def producers = _producers
+
+  private lazy val _consumers = confModel.consumers.map(new RabbitMQConsumer(this, _))
+  def consumers = _consumers
+}
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConsumer.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConsumer.scala
new file mode 100644 (file)
index 0000000..4634a7d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.messaging.amqp
+package rabbitmq
+package v091
+
+import confmodel.RabbitMQConsumerModel
+import com.rabbitmq.client.{Channel => JackRabbitChannel, Connection => JackRabbitConnection, ConnectionFactory => JackRabbitConnectionFactory}
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+class RabbitMQConsumer(owner: RabbitMQConnection, val confModel: RabbitMQConsumerModel) extends AMQPConsumer {
+  def name = confModel.name
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQProducer.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQProducer.scala
new file mode 100644 (file)
index 0000000..1cc4fcc
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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.messaging.amqp
+package rabbitmq
+package v091
+
+import confmodel.RabbitMQProducerModel
+import gr.grnet.aquarium.messaging.amqp.AMQPProducer
+import com.rabbitmq.client.{Channel => JackRabbitChannel, Connection => JackRabbitConnection, ConnectionFactory => JackRabbitConnectionFactory}
+import com.rabbitmq.client.AMQP.BasicProperties
+
+/**
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+class RabbitMQProducer(owner: RabbitMQConnection, val confModel: RabbitMQProducerModel) extends AMQPProducer {
+  private val underlyingChannel = owner.underlyingConnection.createChannel()
+
+  def name = confModel.name
+
+  private def _publish[A](message: String, headers: Map[String, String])(pre: JackRabbitChannel => Any)(post: JackRabbitChannel => A): A = {
+    import scala.collection.JavaConversions._
+    val jrChannel = underlyingChannel
+    val exchange = owner.confModel.exchange
+    val routingKey = confModel.routingKey
+    val jrProps = new BasicProperties.Builder().headers(headers).build()
+
+    pre(jrChannel)
+    jrChannel.basicPublish(exchange, routingKey, jrProps, message.getBytes("UTF-8"))
+    post(jrChannel)
+  }
+
+  def publish(message: String, headers: Map[String, String] = Map()) = {
+    _publish(message, headers){_ =>}{_ => ()}
+  }
+
+  def publishWithConfirm(message: String, headers: Map[String, String] = Map()) = {
+    _publish(message, headers){_.confirmSelect()}{_.waitForConfirms()}
+  }
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/confmodel/confmodel.scala b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/confmodel/confmodel.scala
new file mode 100644 (file)
index 0000000..70d62cc
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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.messaging.amqp
+package rabbitmq
+package v091
+package confmodel
+
+import gr.grnet.aquarium.util.ConfModel
+import gr.grnet.aquarium.util.ConfModel.ConfModelError
+
+sealed trait RabbitMQConfModel extends ConfModel {
+  def validateConfModel: List[ConfModelError] = Nil
+}
+
+case class RabbitMQConfigurationsModel(configurations: List[RabbitMQConfigurationModel]) extends RabbitMQConfModel
+
+case class RabbitMQConfigurationModel(
+    name: String,
+    username: String,
+    password: String,
+    host: String,
+    port: Int,
+    addresses: List[String],
+    virtualHost: String,
+    connections: List[RabbitMQConnectionModel]
+) extends RabbitMQConfModel {
+  
+  override def validateConfModel = {
+    ConfModel.applyValidations(
+      (() => host.size > 0 || addresses.size > 0, "At least one of host, addresses must be provided"),
+      (() => connections.size > 0               , "At least one connection must be specified")
+    )
+  }
+}
+
+case class RabbitMQConnectionModel(
+  name: String,
+  exchange: String,
+  exchangeType: String,
+  isDurable: Boolean,
+  producers: List[RabbitMQProducerModel],
+  consumers: List[RabbitMQConsumerModel]
+) extends RabbitMQConfModel {
+
+}
+
+case class RabbitMQProducerModel(name: String, routingKey: String) extends RabbitMQConfModel
+case class RabbitMQConsumerModel(name: String, queue: String) extends RabbitMQConfModel
diff --git a/logic/src/main/scala/gr/grnet/aquarium/util/ConfModel.scala b/logic/src/main/scala/gr/grnet/aquarium/util/ConfModel.scala
new file mode 100644 (file)
index 0000000..02630a0
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.util
+
+/**
+ * Marker trait for all configuration models.
+ *
+ * A configuration model is the OO representation of some configuration.
+ * The configuration itself can be originally provided in some other format e.g. in a `.properties` or  an `.xml` file.
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+trait ConfModel {
+  /**
+   * Validate this instance and return the list of errors
+   */
+  def validateConfModel: List[ConfModel.ConfModelError]
+}
+
+object ConfModel {
+  type ConfModelError = String
+
+  /**
+   * Given a map of validation checks and their respective errors return the list of errors for those checks that fail.
+   */
+  def applyValidations(checks: (() => Boolean, String)*): List[ConfModelError] = {
+    checks collect {
+      case (check, error) if(!check()) => error
+    } toList
+  }
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/util/KnownResources.scala b/logic/src/main/scala/gr/grnet/aquarium/util/KnownResources.scala
new file mode 100644 (file)
index 0000000..693cd11
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.util
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+object KnownResources {
+  val MasterProps = "aquarium_dev.properties"
+  val RabbitMQProps = "rabbitmq.properties"
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/util/Validateable.scala b/logic/src/main/scala/gr/grnet/aquarium/util/Validateable.scala
new file mode 100644 (file)
index 0000000..75aadce
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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.util
+
+import com.ckkloverdos.maybe.MaybeFailed
+
+/**
+ * Mix this in to everything that can validate itself.
+ *
+ * Also provided is the hook to an initialization procedure.
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>
+ */
+trait Validateable {
+  /**
+   * Validate this instance. On success return None, on failure return the error message.
+   */
+  def validate: Option[String]
+}
+
+trait ValidateableSkeleton extends Validateable {
+  protected lazy val (_isValid, _validationError) = validateImpl
+
+  protected def validateImpl: (Boolean, Option[String])
+  protected def initImpl: Unit
+
+  def validate: Option[String] = {
+    if(_isValid)
+      None
+    else
+      _validationError
+  }
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/util/package.scala b/logic/src/main/scala/gr/grnet/aquarium/util/package.scala
new file mode 100644 (file)
index 0000000..7818a9e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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
+
+/**
+ * Utility definitions.
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+package object util {
+  def tryOption[A](f: => A): Option[A] = {
+    try Some(f)
+    catch {
+      case _: Exception => None
+    }
+  }
+
+  def shortClassNameOf(theClass: Class[_]): String = {
+    val cname = theClass.getName
+    cname.substring(cname.lastIndexOf(".") + 1)
+  }
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/util/xstream/ListConverter.scala b/logic/src/main/scala/gr/grnet/aquarium/util/xstream/ListConverter.scala
new file mode 100644 (file)
index 0000000..593e514
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.util.xstream
+
+import com.thoughtworks.xstream.XStream
+import com.thoughtworks.xstream.converters.{MarshallingContext, UnmarshallingContext}
+import com.thoughtworks.xstream.io.{HierarchicalStreamWriter, HierarchicalStreamReader}
+import com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter
+import com.thoughtworks.xstream.mapper.Mapper
+
+/**
+ * Provides a human-friendlier xstream behavior for Scala lists.
+ *
+ * Taken from `http://stackoverflow.com/questions/1753511/how-can-i-get-xstream-to-output-scala-lists-nicely-can-i-write-a-custom-convert`
+ */
+class ListConverter(mapper: Mapper) extends AbstractCollectionConverter(mapper) {
+  def canConvert(clazz: Class[_]) = {
+    classOf[::[_]] == clazz
+  }
+
+  def marshal(value: AnyRef, writer: HierarchicalStreamWriter, context: MarshallingContext) = {
+    val list = value.asInstanceOf[List[_]]
+    for(item <- list) {
+      writeItem(item, context, writer)
+    }
+  }
+
+  def unmarshal(reader: HierarchicalStreamReader, context: UnmarshallingContext) = {
+    var list : List[_] = Nil
+    while(reader.hasMoreChildren()) {
+      reader.moveDown();
+      val item = readItem(reader, context, list);
+      list = list ::: List(item)
+      reader.moveUp();
+    }
+    list
+  }
+}
\ No newline at end of file
diff --git a/logic/src/main/scala/gr/grnet/aquarium/util/xstream/XStreamHelpers.scala b/logic/src/main/scala/gr/grnet/aquarium/util/xstream/XStreamHelpers.scala
new file mode 100644 (file)
index 0000000..ff3fe9a
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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.util
+package xstream
+
+import com.thoughtworks.xstream.XStream
+import com.ckkloverdos.maybe.{Failed, Just, Maybe}
+import com.ckkloverdos.resource.StreamResource
+import gr.grnet.aquarium.messaging.amqp.rabbitmq.confmodel._
+
+
+/**
+ * Utilities for making our life easier with the XStream library.
+ *
+ * If you need to grab an `XStream`, use `newXStream` or the `DefaultXStream`.
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+object XStreamHelpers {
+  val DefaultXStream = newXStream
+
+  def prepareXStreamAlias[T : Manifest](xs: XStream): XStream = {
+    val theClass = manifest[T].erasure
+    xs.alias(shortClassNameOf(theClass), theClass)
+    xs
+  }
+  
+  def prepareXStreamAliases(xs: XStream): XStream = {
+    prepareXStreamAlias[RabbitMQConfigurationsModel](xs)
+    prepareXStreamAlias[RabbitMQConfigurationModel](xs)
+    prepareXStreamAlias[RabbitMQConnectionModel](xs)
+    prepareXStreamAlias[RabbitMQProducerModel](xs)
+    prepareXStreamAlias[RabbitMQConsumerModel](xs)
+
+    xs.alias("List", classOf[::[_]])
+    xs.alias("Nil", manifest[Nil.type].erasure)
+    xs
+  }
+
+  def prepareXStreamConverters(xs: XStream): XStream = {
+    xs.registerConverter(new ListConverter(xs.getMapper))
+    xs
+  }
+
+  def prepareXStream(xs: XStream): XStream = {
+    prepareXStreamAliases(xs)
+    prepareXStreamConverters(xs)
+  }
+
+  def newXStream: XStream = prepareXStream(new XStream)
+  
+  def parseType[T: Manifest](xml: String, xs: XStream = DefaultXStream): Maybe[T] = {
+    try Just(xs.fromXML(xml).asInstanceOf[T])
+    catch {
+      case e: Exception => Failed(e, "XStream could not parse XML to value of type %s".format(manifest[T]))
+    }
+  }
+  
+  def parseType[T : Manifest](resource: StreamResource, xs: XStream): Maybe[T] = {
+    resource.mapString(parseType[T](_, xs)).flatten1
+  }
+}
\ No newline at end of file
diff --git a/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.properties b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.properties
new file mode 100644 (file)
index 0000000..ea45881
--- /dev/null
@@ -0,0 +1,8 @@
+addresses=aquarium.dev.grnet.gr
+username=aquarium
+password=@qu@r1um
+host=aquarium.dev.grnet.gr
+virtualHost=/
+port=5672
+
+connections=aquarium_dev
\ No newline at end of file
diff --git a/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.xml b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.xml
new file mode 100644 (file)
index 0000000..c908488
--- /dev/null
@@ -0,0 +1,13 @@
+<RabbitMQConfigurationModel>
+  <username>aquarium</username>
+  <password>@qu@r1um</password>
+  <host>aquarium.dev.grnet.gr</host>
+  <port>5672</port>
+  <virtualHost>/</virtualHost>
+  <addresses class="List">
+    <string>aquarium.dev.grnet.gr</string>
+  </addresses>
+  <connections class="List">
+    <string>aquarium_dev</string>
+  </connections>
+</RabbitMQConfigurationModel>
\ No newline at end of file
diff --git a/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/aquarium_dev.properties b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/aquarium_dev.properties
new file mode 100644 (file)
index 0000000..50a52d1
--- /dev/null
@@ -0,0 +1,6 @@
+exchange=aquarium
+exchangeType=direct
+exchangeIsDurable=true
+
+producers=main_producer
+consumers=main_consumer
diff --git a/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/consumers/main_consumer.properties b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/consumers/main_consumer.properties
new file mode 100644 (file)
index 0000000..eb22411
--- /dev/null
@@ -0,0 +1 @@
+queue=aquarium.dev.queue
diff --git a/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/producers/main_producer.properties b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/producers/main_producer.properties
new file mode 100644 (file)
index 0000000..4316905
--- /dev/null
@@ -0,0 +1 @@
+routingKey=aquarium.dev
diff --git a/logic/src/test/resources/rabbitmq/configuration.properties b/logic/src/test/resources/rabbitmq/configuration.properties
new file mode 100644 (file)
index 0000000..8c70ac3
--- /dev/null
@@ -0,0 +1 @@
+configurations=aquarium_dev,localhost
\ No newline at end of file
diff --git a/logic/src/test/resources/rabbitmq/configurations.xml b/logic/src/test/resources/rabbitmq/configurations.xml
new file mode 100644 (file)
index 0000000..fdad7b8
--- /dev/null
@@ -0,0 +1,6 @@
+<RabbitMQConfigurationsModel>
+  <configurationNames class="List">
+    <string>aquarium_dev</string>
+    <string>localhost</string>
+  </configurationNames>
+</RabbitMQConfigurationsModel>
diff --git a/logic/src/test/resources/rabbitmq/localhost/localhost.properties b/logic/src/test/resources/rabbitmq/localhost/localhost.properties
new file mode 100644 (file)
index 0000000..9a30908
--- /dev/null
@@ -0,0 +1,8 @@
+addresses=localhost
+username=aquarium
+password=@qu@r1um
+host=localhost
+virtualHost=/
+port=5672
+
+connections=localhost
\ No newline at end of file
diff --git a/logic/src/test/resources/rabbitmq/localhost/localhost.xml b/logic/src/test/resources/rabbitmq/localhost/localhost.xml
new file mode 100644 (file)
index 0000000..e384823
--- /dev/null
@@ -0,0 +1,13 @@
+<RabbitMQConfigurationModel>
+  <username>aquarium</username>
+  <password>@qu@r1um</password>
+  <host>localhost</host>
+  <port>5672</port>
+  <virtualHost>/</virtualHost>
+  <addresses class="List">
+    <string>localhost</string>
+  </addresses>
+  <connections class="List">
+    <string>localhost</string>
+  </connections>
+</RabbitMQConfigurationModel>
\ No newline at end of file
diff --git a/logic/src/test/resources/rabbitmq/localhost/localhost/consumers/main_consumer.properties b/logic/src/test/resources/rabbitmq/localhost/localhost/consumers/main_consumer.properties
new file mode 100644 (file)
index 0000000..eb22411
--- /dev/null
@@ -0,0 +1 @@
+queue=aquarium.dev.queue
diff --git a/logic/src/test/resources/rabbitmq/localhost/localhost/localhost.properties b/logic/src/test/resources/rabbitmq/localhost/localhost/localhost.properties
new file mode 100644 (file)
index 0000000..50a52d1
--- /dev/null
@@ -0,0 +1,6 @@
+exchange=aquarium
+exchangeType=direct
+exchangeIsDurable=true
+
+producers=main_producer
+consumers=main_consumer
diff --git a/logic/src/test/resources/rabbitmq/localhost/localhost/localhost.xml b/logic/src/test/resources/rabbitmq/localhost/localhost/localhost.xml
new file mode 100644 (file)
index 0000000..50a52d1
--- /dev/null
@@ -0,0 +1,6 @@
+exchange=aquarium
+exchangeType=direct
+exchangeIsDurable=true
+
+producers=main_producer
+consumers=main_consumer
diff --git a/logic/src/test/resources/rabbitmq/localhost/localhost/producers/main_producer.properties b/logic/src/test/resources/rabbitmq/localhost/localhost/producers/main_producer.properties
new file mode 100644 (file)
index 0000000..4316905
--- /dev/null
@@ -0,0 +1 @@
+routingKey=aquarium.dev
diff --git a/logic/src/test/scala/gr/grnet/aquarium/messaging/MessagingTest.scala b/logic/src/test/scala/gr/grnet/aquarium/messaging/MessagingTest.scala
new file mode 100644 (file)
index 0000000..845ffcd
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * 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.messaging
+
+import amqp.rabbitmq.confmodel._
+import org.junit.Test
+import org.junit.Assert._
+import com.ckkloverdos.resource.DefaultResourceContext
+import com.ckkloverdos.props.Props
+import com.ckkloverdos.maybe.Just
+import com.thoughtworks.xstream.XStream
+import gr.grnet.aquarium.util.xstream.XStreamHelpers
+
+/**
+ * 
+ * @author Christos KK Loverdos <loverdos@gmail.com>.
+ */
+class MessagingTest {
+  object RCFolders {
+    val rabbitmq = "rabbitmq"
+
+    val aquarium_dev = "aquarium_dev"
+
+    val producers = "producers"
+    val consumers = "consumers"
+  }
+  
+  object PropFiles {
+    val configurations = "configuration.properties"
+
+    val aquarium_dev = "aquarium_dev.properties"
+
+    val main_producer = "main_producer.properties"
+
+    val main_consumer = "main_consumer.properties"
+  }
+
+  object PropKeys {
+    val configurations = "configurations"
+
+    // configuration
+    val addresses = "addresses"
+    val username  = "username"
+    val password = "password"
+    val host = "host"
+    val virtualHost = "virtualHost"
+    val port = "port"
+    val connections = "connections"
+
+    // connection
+    val exchange = "exchange"
+    val exchangeType = "exchangeType"
+    val exchangeIsDurable = "exchangeIsDurable"
+    val producers = "producers"
+    val consumers = "consumers"
+
+    // producer
+    val routingKey = "routingKey"
+
+    // consumer
+    val queue = "queue"
+  }
+  
+  object PropValues {
+    val aquarium_dev = "aquarium_dev"
+    val localhost = "localhost"
+  }
+
+  val baseRC = DefaultResourceContext
+  val rabbitmqRC = baseRC / RCFolders.rabbitmq
+
+  @Test
+  def testConfigurationsExist {
+    assertTrue(rabbitmqRC.getResource(PropFiles.configurations).isJust)
+  }
+  
+  @Test
+  def testConfigurations {
+    val props = Props(PropFiles.configurations, rabbitmqRC).getOr(Props.empty)
+    val confList = props.getTrimmedList(PropKeys.configurations)
+    assertEquals(List(PropValues.aquarium_dev, PropValues.localhost), confList)
+
+    val xs = XStreamHelpers.newXStream
+
+    val cm1 = new RabbitMQConsumerModel("queue1")
+    val pm1 = new RabbitMQProducerModel("routing.key.1")
+    val con1 = new RabbitMQConnectionModel("exchnage1", "direct", true, List(pm1), List(cm1))
+    val conf1 = new RabbitMQConfigurationModel("aquarium", "aquarium", "localhost", 5672, Nil, "/", List(con1))
+    val confs = new RabbitMQConfigurationsModel2(List(conf1))
+    
+    val xml = xs.toXML(confs)
+    println(xml)
+
+    val xml2 = """<gr.grnet.aquarium.messaging.amqp.rabbitmq.confmodel.RabbitMQConfigurationsModel2>
+      <configurations class="List">
+        <RabbitMQConfigurationModel>
+          <username>aquarium</username>
+          <password>aquarium</password>
+          <host>localhost</host>
+          <port>5672</port>
+          <addresses class="Nil"/>
+          <virtualHost>/</virtualHost>
+          <connections class="List">
+            <RabbitMQConnectionModel>
+              <exchange>exchnage1</exchange>
+              <exchangeType>direct</exchangeType>
+              <isDurable>true</isDurable>
+              <producers class="List">
+                <RabbitMQProducerModel>
+                  <routingKey>routing.key.1</routingKey>
+                </RabbitMQProducerModel>
+              </producers>
+              <consumers class="List">
+                <RabbitMQConsumerModel>
+                  <queue>queue1</queue>
+                </RabbitMQConsumerModel>
+              </consumers>
+            </RabbitMQConnectionModel>
+          </connections>
+        </RabbitMQConfigurationModel>
+      </configurations>
+    </gr.grnet.aquarium.messaging.amqp.rabbitmq.confmodel.RabbitMQConfigurationsModel2>"""
+    for(model2 <- XStreamHelpers.parseType[RabbitMQConfigurationsModel2](xml2, xs)) {
+      println(model2.configurations(0).addresses)
+    }
+  }
+
+  @Test
+  def testConfigurationAquarium_DevExists {
+    val aquariumDevRC = rabbitmqRC / RCFolders.aquarium_dev
+    assertTrue(aquariumDevRC.getResource(PropFiles.aquarium_dev).isJust)
+  }
+
+  @Test
+  def testConfigurationAquarium_Dev {
+    val props = Props(PropFiles.aquarium_dev, rabbitmqRC / RCFolders.aquarium_dev).getOr(Props.empty)
+
+    assertTrue(props.get(PropKeys.username).isJust)
+    assertTrue(props.get(PropKeys.password).isJust)
+    assertTrue(props.get(PropKeys.addresses).isJust)
+    assertTrue(props.get(PropKeys.host).isJust)
+    assertTrue(props.get(PropKeys.virtualHost).isJust)
+    assertTrue(props.get(PropKeys.port).isJust)
+    assertTrue(props.get(PropKeys.connections).isJust)
+    
+    assertEquals(Just(PropValues.aquarium_dev), props.get(PropKeys.connections))
+  }
+
+  @Test
+  def testConnectionAquarium_DevExists {
+    val aquariumDevRC2 = rabbitmqRC / RCFolders.aquarium_dev / RCFolders.aquarium_dev
+    assertTrue(aquariumDevRC2.getResource(PropFiles.aquarium_dev).isJust)
+  }
+  
+  @Test
+  def testConnectionAquarium_Dev {
+    val props = Props(PropFiles.aquarium_dev, rabbitmqRC / RCFolders.aquarium_dev / RCFolders.aquarium_dev).getOr(Props.empty)
+    
+    assertTrue(props.get(PropKeys.exchange).isJust)
+    assertTrue(props.get(PropKeys.exchangeType).isJust)
+    assertTrue(props.get(PropKeys.exchangeIsDurable).isJust)
+    assertTrue(props.get(PropKeys.producers).isJust)
+    assertTrue(props.get(PropKeys.consumers).isJust)
+
+    assertEquals(List("main_producer"), props.getTrimmedList(PropKeys.producers))
+    assertEquals(List("main_consumer"), props.getTrimmedList(PropKeys.consumers))
+  }
+
+  @Test
+  def testProducerMainProducerExists {
+    val rc = rabbitmqRC / RCFolders.aquarium_dev / RCFolders.aquarium_dev / RCFolders.producers
+    assertTrue(rc.getResource(PropFiles.main_producer).isJust)
+  }
+
+  @Test
+  def testProducerMainProducer {
+    val props = Props(PropFiles.main_producer, rabbitmqRC / RCFolders.aquarium_dev / RCFolders.aquarium_dev / RCFolders.producers).getOr(Props.empty)
+
+    assertTrue(props.get(PropKeys.routingKey).isJust)
+  }
+
+
+
+
+  @Test
+  def testConsumerMainConsumerExists {
+    val rc = rabbitmqRC / RCFolders.aquarium_dev / RCFolders.aquarium_dev / RCFolders.consumers
+    assertTrue(rc.getResource(PropFiles.main_consumer).isJust)
+  }
+
+  @Test
+  def testConsumerMainConsumer {
+    val props = Props(PropFiles.main_consumer, rabbitmqRC / RCFolders.aquarium_dev / RCFolders.aquarium_dev / RCFolders.consumers).getOr(Props.empty)
+
+    assertTrue(props.get(PropKeys.queue).isJust)
+  }
+}
\ No newline at end of file