*.db
lib_managed
all-deps/
+project/
+projectFilesBackup/
~ 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>
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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)
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+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
--- /dev/null
+<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
--- /dev/null
+exchange=aquarium
+exchangeType=direct
+exchangeIsDurable=true
+
+producers=main_producer
+consumers=main_consumer
--- /dev/null
+queue=aquarium.dev.queue
--- /dev/null
+routingKey=aquarium.dev
--- /dev/null
+configurations=aquarium_dev,localhost
\ No newline at end of file
--- /dev/null
+<RabbitMQConfigurationsModel>
+ <configurationNames class="List">
+ <string>aquarium_dev</string>
+ <string>localhost</string>
+ </configurationNames>
+</RabbitMQConfigurationsModel>
--- /dev/null
+addresses=localhost
+username=aquarium
+password=@qu@r1um
+host=localhost
+virtualHost=/
+port=5672
+
+connections=localhost
\ No newline at end of file
--- /dev/null
+<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
--- /dev/null
+queue=aquarium.dev.queue
--- /dev/null
+exchange=aquarium
+exchangeType=direct
+exchangeIsDurable=true
+
+producers=main_producer
+consumers=main_consumer
--- /dev/null
+exchange=aquarium
+exchangeType=direct
+exchangeIsDurable=true
+
+producers=main_producer
+consumers=main_consumer
--- /dev/null
+routingKey=aquarium.dev
--- /dev/null
+/*
+ * 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