From a37f12729d749bbc5d4e77a0a408116b07b1d9c2 Mon Sep 17 00:00:00 2001 From: Si Fraser Date: Sun, 15 Jul 2012 19:18:04 +0100 Subject: [PATCH 1/3] chapter 2 scala examples --- .gitignore | 7 +- scala/pom.xml | 127 ++++++++++++++++++ .../sourcecode/GenericConfiguration.scala | 19 +++ .../chapter2/Chapter2Configuration.scala | 17 +++ .../sourcecode/chapter2/Consumer.scala | 60 +++++++++ .../sourcecode/chapter2/Producer.scala | 64 +++++++++ 6 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 scala/pom.xml create mode 100644 scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala create mode 100644 scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Chapter2Configuration.scala create mode 100644 scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala create mode 100644 scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Producer.scala diff --git a/.gitignore b/.gitignore index 28269e5..ebc0627 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,11 @@ bin +target obj +.project +.cache +.settings +.classpath *.suo *.csproj.user *.class -*.jar \ No newline at end of file +*.jar diff --git a/scala/pom.xml b/scala/pom.xml new file mode 100644 index 0000000..bce8206 --- /dev/null +++ b/scala/pom.xml @@ -0,0 +1,127 @@ + + 4.0.0 + + rabbitmqinaction + sourcecode-scala + 0.0.1-SNAPSHOT + jar + + sourcecode-scala + http://maven.apache.org + + + UTF-8 + 2.9.1 + + + + + org.scala-lang + scala-library + ${scala.version} + + + com.rabbitmq + amqp-client + 2.8.4 + + + org.json + json + 20090211 + + + + junit + junit + 4.8.1 + test + + + org.scalatest + scalatest + 1.2 + test + + + + + + src/main/scala + src/test/scala + + + org.scala-tools + maven-scala-plugin + 2.15.0 + + + + compile + testCompile + + + + -make:transitive + -dependencyfile + ${project.build.directory}/.scala_dependencies + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.6 + + false + true + + + + **/*Test.* + **/*Suite.* + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.scala-tools + + maven-scala-plugin + + + [2.15.0,) + + + compile + testCompile + + + + + + + + + + + + + + + diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala new file mode 100644 index 0000000..170c1eb --- /dev/null +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala @@ -0,0 +1,19 @@ +/** + * RabbitMQ in Action - Generic constants + * + * @author Simon Fraser, Siniatech Ltd + */ +package rabbitmqinaction.sourcecode + +object GenericConfiguration { + val Active = false + val Passive = false + val Durable = true + val NonDurable = false + val AutoDelete = true + val NonAutoDelete = false + val DirectExchangeType = "direct" + val PlainContentType = "text/plain" + val EmptyJavaMap = new java.util.HashMap[String, Object] + def host: String = "192.168.0.19" +} \ No newline at end of file diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Chapter2Configuration.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Chapter2Configuration.scala new file mode 100644 index 0000000..a93471d --- /dev/null +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Chapter2Configuration.scala @@ -0,0 +1,17 @@ +/** + * RabbitMQ in Action - Chapter 2 Examples + * + * @author Alvaro Videla (original) + * @author Jason J. W. Williams (original) + * @author Simon Fraser, Siniatech Ltd (translation) + */ +package rabbitmqinaction.sourcecode.chapter2 + +object Chapter2Configuration { + val RoutingKey = "hola" + val Username = "guest" + val Password = "guest" + val Exchange = "hello-exchange" + val QueueName = "hello-queue" + val ConsumerTag = "hello-consumer" +} \ No newline at end of file diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala new file mode 100644 index 0000000..bda3048 --- /dev/null +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala @@ -0,0 +1,60 @@ +/** + * RabbitMQ in Action - Chapter 2 Examples + * + * @author Alvaro Videla (original) + * @author Jason J. W. Williams (original) + * @author Simon Fraser, Siniatech Ltd (translation) + */ +package rabbitmqinaction.sourcecode.chapter2 + +import com.rabbitmq.client.AMQP.BasicProperties +import com.rabbitmq.client.Channel +import com.rabbitmq.client.ConnectionFactory +import com.rabbitmq.client.DefaultConsumer +import com.rabbitmq.client.Envelope + +import Chapter2Configuration.ConsumerTag +import Chapter2Configuration.Exchange +import Chapter2Configuration.Password +import Chapter2Configuration.QueueName +import Chapter2Configuration.RoutingKey +import Chapter2Configuration.Username +import rabbitmqinaction.sourcecode.GenericConfiguration.Active +import rabbitmqinaction.sourcecode.GenericConfiguration.DirectExchangeType +import rabbitmqinaction.sourcecode.GenericConfiguration.Durable +import rabbitmqinaction.sourcecode.GenericConfiguration.EmptyJavaMap +import rabbitmqinaction.sourcecode.GenericConfiguration.NonAutoDelete +import rabbitmqinaction.sourcecode.GenericConfiguration.host + +object Consumer { + def main(args: Array[String]) { + val factory = new ConnectionFactory + factory.setUsername(Username) + factory.setPassword(Password) + factory.setHost(host) + + val connection = factory.newConnection(); + + val channel = connection.createChannel(); + channel.exchangeDeclare(Exchange, DirectExchangeType, Active, Durable, NonAutoDelete, EmptyJavaMap); + channel.queueDeclare(QueueName, Active, Durable, NonAutoDelete, null); + channel.queueBind(QueueName, Exchange, RoutingKey, EmptyJavaMap); + channel.basicConsume(QueueName, false, ConsumerTag, new ConsumerCallback(channel)); + } +} + +class ConsumerCallback(channel: Channel) extends DefaultConsumer(channel) { + override def handleDelivery(consumerTag: String, envelope: Envelope, props: BasicProperties, body: Array[Byte]) { + getChannel.basicAck(envelope.getDeliveryTag, false) + val msg = new String(body) + msg match { + case "quit" => { + getChannel.basicCancel(consumerTag) + getChannel.close + getChannel.getConnection.close + System.exit(1) + } + case _ => println(msg); + } + } +} \ No newline at end of file diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Producer.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Producer.scala new file mode 100644 index 0000000..59f3547 --- /dev/null +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Producer.scala @@ -0,0 +1,64 @@ +/** + * RabbitMQ in Action - Chapter 2 Examples + * + * @author Alvaro Videla (original) + * @author Jason J. W. Williams (original) + * @author Simon Fraser, Siniatech Ltd (translation) + */ +package rabbitmqinaction.sourcecode.chapter2 + +import com.rabbitmq.client.AMQP +import com.rabbitmq.client.ConfirmListener +import com.rabbitmq.client.ConnectionFactory + +import Chapter2Configuration.Exchange +import Chapter2Configuration.Password +import Chapter2Configuration.RoutingKey +import Chapter2Configuration.Username +import rabbitmqinaction.sourcecode.GenericConfiguration.PlainContentType +import rabbitmqinaction.sourcecode.GenericConfiguration.host + +object Producer { + + def main(args: Array[String]) { + if (args.length != 1) { + System.err.println("Message body must be supplied"); + System.exit(1); + } + + val factory = new ConnectionFactory + factory.setUsername(Username) + factory.setPassword(Password) + factory.setHost(host) + + val connection = factory.newConnection + + val msg = args.head + val msgPropertiesBuilder = new AMQP.BasicProperties.Builder + msgPropertiesBuilder.contentType(PlainContentType) + val msgProperties = msgPropertiesBuilder.build + + val channel = connection.createChannel + channel.confirmSelect + channel.addConfirmListener(ConfirmHandler); + channel.basicPublish(Exchange, RoutingKey, msgProperties, msg.getBytes) + channel.waitForConfirmsOrDie + + channel.close + connection.close + } +} + +object ConfirmHandler extends ConfirmListener { + override def handleAck(deliveryTag: Long, multiple: Boolean) { + println("Confirm receipt") + } + + override def handleNack(deliveryTag: Long, multiple: Boolean) { + println("Message lost"); + } +} + + + + From 48d6f82889b6154522711c36a6c6ae92dca55854 Mon Sep 17 00:00:00 2001 From: Si Fraser Date: Tue, 17 Jul 2012 21:00:50 +0100 Subject: [PATCH 2/3] Use localhost and correct successful exit code --- .../rabbitmqinaction/sourcecode/GenericConfiguration.scala | 2 +- .../scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala index 170c1eb..b3beb94 100644 --- a/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala @@ -15,5 +15,5 @@ object GenericConfiguration { val DirectExchangeType = "direct" val PlainContentType = "text/plain" val EmptyJavaMap = new java.util.HashMap[String, Object] - def host: String = "192.168.0.19" + def host: String = "localhost" } \ No newline at end of file diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala index bda3048..7069360 100644 --- a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala @@ -52,7 +52,7 @@ class ConsumerCallback(channel: Channel) extends DefaultConsumer(channel) { getChannel.basicCancel(consumerTag) getChannel.close getChannel.getConnection.close - System.exit(1) + System.exit(0) } case _ => println(msg); } From 5291878a1eccfddf3bd5006932a065f1270743c4 Mon Sep 17 00:00:00 2001 From: Si Fraser Date: Wed, 25 Jul 2012 21:45:07 +0100 Subject: [PATCH 3/3] added the variations on the ch.2 examples --- .../sourcecode/GenericConfiguration.scala | 2 +- .../sourcecode/chapter2/Consumer.scala | 1 - .../chapter2/ConsumerWithConfirms.scala | 60 +++++++++++++++++ .../sourcecode/chapter2/Producer.scala | 13 ---- .../chapter2/ProducerWithConfirms.scala | 64 +++++++++++++++++++ .../sourcecode/chapter2/ProducerWithTx.scala | 53 +++++++++++++++ 6 files changed, 178 insertions(+), 15 deletions(-) create mode 100644 scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ConsumerWithConfirms.scala create mode 100644 scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ProducerWithConfirms.scala create mode 100644 scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ProducerWithTx.scala diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala index b3beb94..e5c81b3 100644 --- a/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/GenericConfiguration.scala @@ -15,5 +15,5 @@ object GenericConfiguration { val DirectExchangeType = "direct" val PlainContentType = "text/plain" val EmptyJavaMap = new java.util.HashMap[String, Object] - def host: String = "localhost" + def host = "localhost" } \ No newline at end of file diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala index 7069360..b1804be 100644 --- a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala @@ -45,7 +45,6 @@ object Consumer { class ConsumerCallback(channel: Channel) extends DefaultConsumer(channel) { override def handleDelivery(consumerTag: String, envelope: Envelope, props: BasicProperties, body: Array[Byte]) { - getChannel.basicAck(envelope.getDeliveryTag, false) val msg = new String(body) msg match { case "quit" => { diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ConsumerWithConfirms.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ConsumerWithConfirms.scala new file mode 100644 index 0000000..4c3d3bd --- /dev/null +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ConsumerWithConfirms.scala @@ -0,0 +1,60 @@ +/** + * RabbitMQ in Action - Chapter 2 Examples + * + * @author Alvaro Videla (original) + * @author Jason J. W. Williams (original) + * @author Simon Fraser, Siniatech Ltd (translation) + */ +package rabbitmqinaction.sourcecode.chapter2 + +import com.rabbitmq.client.AMQP.BasicProperties +import com.rabbitmq.client.Channel +import com.rabbitmq.client.ConnectionFactory +import com.rabbitmq.client.DefaultConsumer +import com.rabbitmq.client.Envelope + +import Chapter2Configuration.ConsumerTag +import Chapter2Configuration.Exchange +import Chapter2Configuration.Password +import Chapter2Configuration.QueueName +import Chapter2Configuration.RoutingKey +import Chapter2Configuration.Username +import rabbitmqinaction.sourcecode.GenericConfiguration.Active +import rabbitmqinaction.sourcecode.GenericConfiguration.DirectExchangeType +import rabbitmqinaction.sourcecode.GenericConfiguration.Durable +import rabbitmqinaction.sourcecode.GenericConfiguration.EmptyJavaMap +import rabbitmqinaction.sourcecode.GenericConfiguration.NonAutoDelete +import rabbitmqinaction.sourcecode.GenericConfiguration.host + +object ConsumerWithConfirms { + def main(args: Array[String]) { + val factory = new ConnectionFactory + factory.setUsername(Username) + factory.setPassword(Password) + factory.setHost(host) + + val connection = factory.newConnection(); + + val channel = connection.createChannel(); + channel.exchangeDeclare(Exchange, DirectExchangeType, Active, Durable, NonAutoDelete, EmptyJavaMap); + channel.queueDeclare(QueueName, Active, Durable, NonAutoDelete, null); + channel.queueBind(QueueName, Exchange, RoutingKey, EmptyJavaMap); + channel.basicConsume(QueueName, false, ConsumerTag, new ConsumerCallbackWithConfirms(channel)); + } +} + +class ConsumerCallbackWithConfirms(channel: Channel) extends DefaultConsumer(channel) { + override def handleDelivery(consumerTag: String, envelope: Envelope, props: BasicProperties, body: Array[Byte]) { + getChannel.basicAck(envelope.getDeliveryTag, false) + val msg = new String(body) + msg match { + case "quit" => { + getChannel.basicCancel(consumerTag) + getChannel.close + getChannel.getConnection.close + System.exit(0) + } + case _ => println(msg); + } + } +} \ No newline at end of file diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Producer.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Producer.scala index 59f3547..5f12bad 100644 --- a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Producer.scala +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Producer.scala @@ -39,26 +39,13 @@ object Producer { val msgProperties = msgPropertiesBuilder.build val channel = connection.createChannel - channel.confirmSelect - channel.addConfirmListener(ConfirmHandler); channel.basicPublish(Exchange, RoutingKey, msgProperties, msg.getBytes) - channel.waitForConfirmsOrDie channel.close connection.close } } -object ConfirmHandler extends ConfirmListener { - override def handleAck(deliveryTag: Long, multiple: Boolean) { - println("Confirm receipt") - } - - override def handleNack(deliveryTag: Long, multiple: Boolean) { - println("Message lost"); - } -} - diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ProducerWithConfirms.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ProducerWithConfirms.scala new file mode 100644 index 0000000..6d45d53 --- /dev/null +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ProducerWithConfirms.scala @@ -0,0 +1,64 @@ +/** + * RabbitMQ in Action - Chapter 2 Examples + * + * @author Alvaro Videla (original) + * @author Jason J. W. Williams (original) + * @author Simon Fraser, Siniatech Ltd (translation) + */ +package rabbitmqinaction.sourcecode.chapter2 + +import com.rabbitmq.client.AMQP +import com.rabbitmq.client.ConfirmListener +import com.rabbitmq.client.ConnectionFactory + +import Chapter2Configuration.Exchange +import Chapter2Configuration.Password +import Chapter2Configuration.RoutingKey +import Chapter2Configuration.Username +import rabbitmqinaction.sourcecode.GenericConfiguration.PlainContentType +import rabbitmqinaction.sourcecode.GenericConfiguration.host + +object ProducerWithConfirms { + + def main(args: Array[String]) { + if (args.length != 1) { + System.err.println("Message body must be supplied"); + System.exit(1); + } + + val factory = new ConnectionFactory + factory.setUsername(Username) + factory.setPassword(Password) + factory.setHost(host) + + val connection = factory.newConnection + + val msg = args.head + val msgPropertiesBuilder = new AMQP.BasicProperties.Builder + msgPropertiesBuilder.contentType(PlainContentType) + val msgProperties = msgPropertiesBuilder.build + + val channel = connection.createChannel + channel.confirmSelect + channel.addConfirmListener(ConfirmHandler); + channel.basicPublish(Exchange, RoutingKey, msgProperties, msg.getBytes) + channel.waitForConfirmsOrDie + + channel.close + connection.close + } +} + +object ConfirmHandler extends ConfirmListener { + override def handleAck(deliveryTag: Long, multiple: Boolean) { + println("Confirm receipt") + } + + override def handleNack(deliveryTag: Long, multiple: Boolean) { + println("Message lost"); + } +} + + + + diff --git a/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ProducerWithTx.scala b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ProducerWithTx.scala new file mode 100644 index 0000000..aa604fd --- /dev/null +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/ProducerWithTx.scala @@ -0,0 +1,53 @@ +/** + * RabbitMQ in Action - Chapter 2 Examples + * + * @author Alvaro Videla (original) + * @author Jason J. W. Williams (original) + * @author Simon Fraser, Siniatech Ltd (translation) + */ +package rabbitmqinaction.sourcecode.chapter2 + +import com.rabbitmq.client.AMQP +import com.rabbitmq.client.ConnectionFactory + +import Chapter2Configuration.Exchange +import Chapter2Configuration.Password +import Chapter2Configuration.RoutingKey +import Chapter2Configuration.Username +import rabbitmqinaction.sourcecode.GenericConfiguration.PlainContentType +import rabbitmqinaction.sourcecode.GenericConfiguration.host + +object ProducerWithTx { + + def main(args: Array[String]) { + if (args.length != 1) { + System.err.println("Message body must be supplied"); + System.exit(1); + } + + val factory = new ConnectionFactory + factory.setUsername(Username) + factory.setPassword(Password) + factory.setHost(host) + + val connection = factory.newConnection + + val msg = args.head + val msgPropertiesBuilder = new AMQP.BasicProperties.Builder + msgPropertiesBuilder.contentType(PlainContentType) + val msgProperties = msgPropertiesBuilder.build + + val channel = connection.createChannel + channel.txSelect + channel.basicPublish(Exchange, RoutingKey, msgProperties, msg.getBytes) + channel.txCommit + + channel.close + connection.close + } +} + + + + +