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..e5c81b3 --- /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 = "localhost" +} \ 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..b1804be --- /dev/null +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Consumer.scala @@ -0,0 +1,59 @@ +/** + * 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]) { + 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/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 new file mode 100644 index 0000000..5f12bad --- /dev/null +++ b/scala/src/main/scala/rabbitmqinaction/sourcecode/chapter2/Producer.scala @@ -0,0 +1,51 @@ +/** + * 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.basicPublish(Exchange, RoutingKey, msgProperties, msg.getBytes) + + channel.close + connection.close + } +} + + + + 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 + } +} + + + + +