From 367c5d7ceef68eb6e5260a9607f971845f52fc2f Mon Sep 17 00:00:00 2001 From: Christos KK Loverdos Date: Mon, 21 Nov 2011 12:00:13 +0200 Subject: [PATCH] WIP.First cut of amqp-rabbit configuration-based api --- .gitignore | 2 + logic/pom.xml | 17 +- .../grnet/aquarium/messaging/GenericMessage.scala | 107 +++++++++ .../messaging/amqp/AMQPConfiguration.scala | 51 +++++ .../messaging/amqp/AMQPConfigurations.scala | 48 ++++ .../aquarium/messaging/amqp/AMQPConnection.scala | 53 +++++ .../aquarium/messaging/amqp/AMQPConsumer.scala | 44 ++++ .../aquarium/messaging/amqp/AMQPProducer.scala | 48 ++++ .../amqp/rabbitmq/v091/RabbitMQConfiguration.scala | 98 +++++++++ .../rabbitmq/v091/RabbitMQConfigurations.scala | 103 +++++++++ .../amqp/rabbitmq/v091/RabbitMQConnection.scala | 61 ++++++ .../amqp/rabbitmq/v091/RabbitMQConsumer.scala | 49 +++++ .../amqp/rabbitmq/v091/RabbitMQProducer.scala | 73 +++++++ .../amqp/rabbitmq/v091/confmodel/confmodel.scala | 81 +++++++ .../scala/gr/grnet/aquarium/util/ConfModel.scala | 64 ++++++ .../gr/grnet/aquarium/util/KnownResources.scala | 45 ++++ .../gr/grnet/aquarium/util/Validateable.scala | 66 ++++++ .../scala/gr/grnet/aquarium/util/package.scala | 55 +++++ .../aquarium/util/xstream/ListConverter.scala | 71 ++++++ .../aquarium/util/xstream/XStreamHelpers.scala | 95 ++++++++ .../rabbitmq/aquarium_dev/aquarium_dev.properties | 8 + .../rabbitmq/aquarium_dev/aquarium_dev.xml | 13 ++ .../aquarium_dev/aquarium_dev.properties | 6 + .../consumers/main_consumer.properties | 1 + .../producers/main_producer.properties | 1 + .../resources/rabbitmq/configuration.properties | 1 + .../src/test/resources/rabbitmq/configurations.xml | 6 + .../rabbitmq/localhost/localhost.properties | 8 + .../resources/rabbitmq/localhost/localhost.xml | 13 ++ .../localhost/consumers/main_consumer.properties | 1 + .../localhost/localhost/localhost.properties | 6 + .../rabbitmq/localhost/localhost/localhost.xml | 6 + .../localhost/producers/main_producer.properties | 1 + .../grnet/aquarium/messaging/MessagingTest.scala | 230 ++++++++++++++++++++ 34 files changed, 1530 insertions(+), 2 deletions(-) create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/GenericMessage.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfiguration.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfigurations.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConnection.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConsumer.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPProducer.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfiguration.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfigurations.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConnection.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConsumer.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQProducer.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/confmodel/confmodel.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/util/ConfModel.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/util/KnownResources.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/util/Validateable.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/util/package.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/util/xstream/ListConverter.scala create mode 100644 logic/src/main/scala/gr/grnet/aquarium/util/xstream/XStreamHelpers.scala create mode 100644 logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.properties create mode 100644 logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.xml create mode 100644 logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/aquarium_dev.properties create mode 100644 logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/consumers/main_consumer.properties create mode 100644 logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/producers/main_producer.properties create mode 100644 logic/src/test/resources/rabbitmq/configuration.properties create mode 100644 logic/src/test/resources/rabbitmq/configurations.xml create mode 100644 logic/src/test/resources/rabbitmq/localhost/localhost.properties create mode 100644 logic/src/test/resources/rabbitmq/localhost/localhost.xml create mode 100644 logic/src/test/resources/rabbitmq/localhost/localhost/consumers/main_consumer.properties create mode 100644 logic/src/test/resources/rabbitmq/localhost/localhost/localhost.properties create mode 100644 logic/src/test/resources/rabbitmq/localhost/localhost/localhost.xml create mode 100644 logic/src/test/resources/rabbitmq/localhost/localhost/producers/main_producer.properties create mode 100644 logic/src/test/scala/gr/grnet/aquarium/messaging/MessagingTest.scala diff --git a/.gitignore b/.gitignore index 5497f3c..8d7c518 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ bin/ *.db lib_managed all-deps/ +project/ +projectFilesBackup/ diff --git a/logic/pom.xml b/logic/pom.xml index fe46329..4e96029 100644 --- a/logic/pom.xml +++ b/logic/pom.xml @@ -34,7 +34,8 @@ ~ or implied, of GRNET S.A. --> - + 4.0.0 @@ -106,7 +107,19 @@ com.rabbitmq amqp-client - 2.6.1 + 2.7.0 + + + + com.ckkloverdos + streamresource_2.9.1 + 0.1.1 + + + + com.thoughtworks.xstream + xstream + 1.4.1 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 index 0000000..88455bd --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/GenericMessage.scala @@ -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 . + */ +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 index 0000000..bbdd871 --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfiguration.scala @@ -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 . + */ +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 index 0000000..a1e3e27 --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConfigurations.scala @@ -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 . + */ +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 index 0000000..dacff4e --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConnection.scala @@ -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 . + */ +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 index 0000000..2cda8d5 --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPConsumer.scala @@ -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 . + */ +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 index 0000000..46183fd --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/AMQPProducer.scala @@ -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 . + */ +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 index 0000000..295d69a --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfiguration.scala @@ -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 . + */ +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 index 0000000..4ac6216 --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConfigurations.scala @@ -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 . + */ +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 .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 index 0000000..532da64 --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConnection.scala @@ -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 . + */ +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 index 0000000..4634a7d --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQConsumer.scala @@ -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 . + */ +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 index 0000000..1cc4fcc --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/RabbitMQProducer.scala @@ -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 . + */ +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 index 0000000..70d62cc --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/messaging/amqp/rabbitmq/v091/confmodel/confmodel.scala @@ -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 index 0000000..02630a0 --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/util/ConfModel.scala @@ -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 . + */ +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 index 0000000..693cd11 --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/util/KnownResources.scala @@ -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 . + */ +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 index 0000000..75aadce --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/util/Validateable.scala @@ -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 + */ +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 index 0000000..7818a9e --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/util/package.scala @@ -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 . + */ +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 index 0000000..593e514 --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/util/xstream/ListConverter.scala @@ -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 index 0000000..ff3fe9a --- /dev/null +++ b/logic/src/main/scala/gr/grnet/aquarium/util/xstream/XStreamHelpers.scala @@ -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 . + */ +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 index 0000000..ea45881 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.properties @@ -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 index 0000000..c908488 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev.xml @@ -0,0 +1,13 @@ + + aquarium + @qu@r1um + aquarium.dev.grnet.gr + 5672 + / + + aquarium.dev.grnet.gr + + + aquarium_dev + + \ 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 index 0000000..50a52d1 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/aquarium_dev.properties @@ -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 index 0000000..eb22411 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/consumers/main_consumer.properties @@ -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 index 0000000..4316905 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/aquarium_dev/aquarium_dev/producers/main_producer.properties @@ -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 index 0000000..8c70ac3 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/configuration.properties @@ -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 index 0000000..fdad7b8 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/configurations.xml @@ -0,0 +1,6 @@ + + + aquarium_dev + localhost + + diff --git a/logic/src/test/resources/rabbitmq/localhost/localhost.properties b/logic/src/test/resources/rabbitmq/localhost/localhost.properties new file mode 100644 index 0000000..9a30908 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/localhost/localhost.properties @@ -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 index 0000000..e384823 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/localhost/localhost.xml @@ -0,0 +1,13 @@ + + aquarium + @qu@r1um + localhost + 5672 + / + + localhost + + + localhost + + \ 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 index 0000000..eb22411 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/localhost/localhost/consumers/main_consumer.properties @@ -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 index 0000000..50a52d1 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/localhost/localhost/localhost.properties @@ -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 index 0000000..50a52d1 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/localhost/localhost/localhost.xml @@ -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 index 0000000..4316905 --- /dev/null +++ b/logic/src/test/resources/rabbitmq/localhost/localhost/producers/main_producer.properties @@ -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 index 0000000..845ffcd --- /dev/null +++ b/logic/src/test/scala/gr/grnet/aquarium/messaging/MessagingTest.scala @@ -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 . + */ +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 = """ + + + aquarium + aquarium + localhost + 5672 + + / + + + exchnage1 + direct + true + + + routing.key.1 + + + + + queue1 + + + + + + + """ + 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 -- 1.7.10.4