diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5aea6ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +target/ + +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +npm-debug.log +node_modules + diff --git a/README b/README deleted file mode 100644 index d523682..0000000 --- a/README +++ /dev/null @@ -1,16 +0,0 @@ -RabbitMQ Cloud Foundry Samples -============================== - -This repository contains sample applications to demonstrate the use of -the RabbitMQ service on Cloud Foundry -(). - -You can find further sample applications at -. In -particular, the 'stocks' application - -uses the RabbitMQ service. - -If you have any questions about these samples or the service, please -contact us using the forums on support.cloudfoundry.com -(). diff --git a/README.md b/README.md new file mode 100644 index 0000000..c9da1e0 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +RabbitMQ Cloud Foundry Samples +============================== + +This repository contains sample applications to demonstrate the use of [RabbitMQ](http://www.rabbitmq.com/) on [Cloud Foundry](http://www.cloudfoundry.com). + +Examples are provided for the following languages/runtimes: + +* [Java with Spring](spring) +* [Ruby with Rails](rails) +* [Ruby with Sinatra](sinatra) +* [Node.js](nodejs) diff --git a/nodejs/Procfile b/nodejs/Procfile new file mode 100644 index 0000000..e1d4131 --- /dev/null +++ b/nodejs/Procfile @@ -0,0 +1 @@ +web: node app.js diff --git a/nodejs/README b/nodejs/README deleted file mode 100644 index 07b6046..0000000 --- a/nodejs/README +++ /dev/null @@ -1,7 +0,0 @@ -This is a simple Node.JS application demonstrating the use of the -RabbitMQ service on Cloud Foundry. - -To run locally: - - $ npm install - $ node app.js diff --git a/nodejs/README.md b/nodejs/README.md new file mode 100644 index 0000000..85b4ae5 --- /dev/null +++ b/nodejs/README.md @@ -0,0 +1,9 @@ +This is a simple Node.js application demonstrating the use of RabbitMQ on Cloud Foundry. + +## Deploying to Cloud Foundry ## + +After installing in the 'cf' [command-line interface](http://docs.cloudfoundry.com/docs/using/managing-apps/cf/) for Cloud Foundry, targeting a Cloud Foundry instance, and logging in, the application can be pushed using these commands: + + $ cf push + +The provided `manifest.yml` file will be used to provide the application parameters to Cloud Foundry. You may need to provide a different URL for the application if the `rabbitmq-node` URL is already being used in your Cloud Foundry domain. The `manifest.yml` file specifies a RabbitMQ services that is available on the [run.pivotal.io](http://docs.cloudfoundry.com/docs/dotcom/getting-started.html) Cloud Foundry services marketplace. You may need to change the details of the RabbitMQ service to push to a different Cloud Foundry instance. diff --git a/nodejs/app.js b/nodejs/app.js index 62a1484..1467883 100644 --- a/nodejs/app.js +++ b/nodejs/app.js @@ -1,5 +1,3 @@ -require.paths.unshift('./node_modules'); - var http = require('http'); var amqp = require('amqp'); var URL = require('url'); @@ -7,8 +5,17 @@ var htmlEscape = require('sanitizer/sanitizer').escape; function rabbitUrl() { if (process.env.VCAP_SERVICES) { - conf = JSON.parse(process.env.VCAP_SERVICES); - return conf['rabbitmq-2.4'][0].credentials.url; + var svcInfo = JSON.parse(process.env.VCAP_SERVICES); + for (var label in svcInfo) { + var svcs = svcInfo[label]; + for (var index in svcs) { + var uri = svcs[index].credentials.uri; + if (uri.lastIndexOf("amqp", 0) == 0) { + return uri; + } + } + } + return null; } else { return "amqp://localhost"; diff --git a/nodejs/manifest.yml b/nodejs/manifest.yml new file mode 100644 index 0000000..630bf39 --- /dev/null +++ b/nodejs/manifest.yml @@ -0,0 +1,13 @@ +--- +applications: +- name: rabbitmq-node + memory: 256M + instances: 1 + url: rabbitmq-node.${target-base} + path: . + services: + rabbit-sample: + label: cloudamqp + provider: cloudamqp + version: n/a + plan: lemur diff --git a/nodejs/package.json b/nodejs/package.json index 69d27de..1bbedde 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -1,6 +1,5 @@ { - - "name":"node-srs-demo", + "name":"rabbitmq-node", "author": "Michael Bridgen", "version":"0.0.2", "dependencies":{ diff --git a/rails/README b/rails/README deleted file mode 100644 index 2f1f9ac..0000000 --- a/rails/README +++ /dev/null @@ -1,6 +0,0 @@ -This is a very simple Rails 3 application demonstrating the use of the -RabbitMQ service on Cloud Foundry. - -See - -for a tutorial corresponding to this application. diff --git a/rails/README.md b/rails/README.md new file mode 100644 index 0000000..400566a --- /dev/null +++ b/rails/README.md @@ -0,0 +1,9 @@ +This is a very simple Rails 3 application demonstrating the use of RabbitMQ on Cloud Foundry. + +## Deploying to Cloud Foundry ## + +After installing in the 'cf' [command-line interface](http://docs.cloudfoundry.com/docs/using/managing-apps/cf/) for Cloud Foundry, targeting a Cloud Foundry instance, and logging in, the application can be pushed using these commands: + + $ cf push + +The provided `manifest.yml` file will be used to provide the application parameters to Cloud Foundry. You may need to provide a different URL for the application if the `rabbitmq-rails` URL is already being used in your Cloud Foundry domain. The `manifest.yml` file specifies a RabbitMQ services that is available on the [run.pivotal.io](http://docs.cloudfoundry.com/docs/dotcom/getting-started.html) Cloud Foundry services marketplace. You may need to change the details of the RabbitMQ service to push to a different Cloud Foundry instance. diff --git a/rails/app/controllers/home_controller.rb b/rails/app/controllers/home_controller.rb index c980ae4..49c600b 100644 --- a/rails/app/controllers/home_controller.rb +++ b/rails/app/controllers/home_controller.rb @@ -13,8 +13,8 @@ def self.amqp_url services = JSON.parse(ENV['VCAP_SERVICES'], :symbolize_names => true) url = services.values.map do |srvs| srvs.map do |srv| - if srv[:label] =~ /^rabbitmq-/ - srv[:credentials][:url] + if srv[:credentials][:uri] =~ /^amqp/ + srv[:credentials][:uri] else [] end diff --git a/rails/config/application.rb b/rails/config/application.rb index c6d135d..b0a3612 100644 --- a/rails/config/application.rb +++ b/rails/config/application.rb @@ -1,6 +1,9 @@ require File.expand_path('../boot', __FILE__) -require 'rails/all' +require "action_controller/railtie" +require "action_mailer/railtie" +require "active_resource/railtie" +require "rails/test_unit/railtie" # If you have a Gemfile, require the gems listed there, including any gems # you've limited to :test, :development, or :production. diff --git a/rails/manifest.yml b/rails/manifest.yml new file mode 100644 index 0000000..6958e97 --- /dev/null +++ b/rails/manifest.yml @@ -0,0 +1,13 @@ +--- +applications: +- name: rabbitmq-rails + memory: 256M + instances: 1 + url: rabbitmq-rails.${target-base} + path: . + services: + rabbit-rails: + label: cloudamqp + provider: cloudamqp + version: n/a + plan: lemur diff --git a/sinatra/Gemfile.lock b/sinatra/Gemfile.lock index 09e5fea..396dd64 100644 --- a/sinatra/Gemfile.lock +++ b/sinatra/Gemfile.lock @@ -8,7 +8,7 @@ GEM rack (1.3.2) sinatra (1.2.6) rack (~> 1.1) - tilt (< 2.0, >= 1.2.2) + tilt (>= 1.2.2, < 2.0) thin (1.2.11) daemons (>= 1.0.9) eventmachine (>= 0.12.6) diff --git a/sinatra/README b/sinatra/README deleted file mode 100644 index 503fb3d..0000000 --- a/sinatra/README +++ /dev/null @@ -1,2 +0,0 @@ -This is a very simple Sinatra application demonstrating the use of the -RabbitMQ service on Cloud Foundry. diff --git a/sinatra/README.md b/sinatra/README.md new file mode 100644 index 0000000..75a08df --- /dev/null +++ b/sinatra/README.md @@ -0,0 +1,9 @@ +This is a very simple Sinatra application demonstrating the use of RabbitMQ on Cloud Foundry. + +## Deploying to Cloud Foundry ## + +After installing in the 'cf' [command-line interface](http://docs.cloudfoundry.com/docs/using/managing-apps/cf/) for Cloud Foundry, targeting a Cloud Foundry instance, and logging in, the application can be pushed using these commands: + + $ cf push + +The provided `manifest.yml` file will be used to provide the application parameters to Cloud Foundry. You may need to provide a different URL for the application if the `rabbitmq-sinatra` URL is already being used in your Cloud Foundry domain. The `manifest.yml` file specifies a RabbitMQ services that is available on the [run.pivotal.io](http://docs.cloudfoundry.com/docs/dotcom/getting-started.html) Cloud Foundry services marketplace. You may need to change the details of the RabbitMQ service to push to a different Cloud Foundry instance. diff --git a/sinatra/config.ru b/sinatra/config.ru new file mode 100644 index 0000000..427e688 --- /dev/null +++ b/sinatra/config.ru @@ -0,0 +1,3 @@ +require './rabbit' + +run RabbitMQ.new diff --git a/sinatra/manifest.yml b/sinatra/manifest.yml new file mode 100644 index 0000000..6002c72 --- /dev/null +++ b/sinatra/manifest.yml @@ -0,0 +1,13 @@ +--- +applications: +- name: rabbitmq-sinatra + memory: 256M + instances: 1 + url: rabbitmq-sinatra.${target-base} + path: . + services: + rabbit-sinatra: + label: cloudamqp + provider: cloudamqp + version: n/a + plan: lemur diff --git a/sinatra/rabbit.rb b/sinatra/rabbit.rb index 0eb3f07..377ac8d 100644 --- a/sinatra/rabbit.rb +++ b/sinatra/rabbit.rb @@ -1,91 +1,94 @@ -require 'sinatra' +require 'sinatra/base' require 'erb' require 'cgi' require 'bunny' require 'json' -enable :sessions -# Extract the connection string for the rabbitmq service from the -# service information provided by Cloud Foundry in an environment -# variable. -def amqp_url - services = JSON.parse(ENV['VCAP_SERVICES'], :symbolize_names => true) - url = services.values.map do |srvs| - srvs.map do |srv| - if srv[:label] =~ /^rabbitmq-/ - srv[:credentials][:url] - else - [] +class RabbitMQ < Sinatra::Base + enable :sessions + + # Extract the connection string for the rabbitmq service from the + # service information provided by Cloud Foundry in an environment + # variable. + def amqp_url + services = JSON.parse(ENV['VCAP_SERVICES'], :symbolize_names => true) + url = services.values.map do |srvs| + srvs.map do |srv| + if srv[:credentials][:uri] =~ /^amqp/ + srv[:credentials][:uri] + else + [] + end end - end - end.flatten!.first -end + end.flatten!.first + end -# Opens a client connection to the RabbitMQ service, if one isn't -# already open. This is a class method because a new instance of -# the controller class will be created upon each request. But AMQP -# connections can be long-lived, so we would like to re-use the -# connection across many requests. -def client - unless $client - c = Bunny.new(amqp_url) - c.start - $client = c + # Opens a client connection to the RabbitMQ service, if one isn't + # already open. This is a class method because a new instance of + # the controller class will be created upon each request. But AMQP + # connections can be long-lived, so we would like to re-use the + # connection across many requests. + def client + unless $client + c = Bunny.new(amqp_url) + c.start + $client = c - # We only want to accept one un-acked message - $client.qos :prefetch_count => 1 + # We only want to accept one un-acked message + $client.qos :prefetch_count => 1 + end + $client end - $client -end -# Return the "nameless exchange", pre-defined by AMQP as a means to -# send messages to specific queues. Again, we use a class method to -# share this across requests. -def nameless_exchange - $nameless_exchange ||= client.exchange('') -end + # Return the "nameless exchange", pre-defined by AMQP as a means to + # send messages to specific queues. Again, we use a class method to + # share this across requests. + def nameless_exchange + $nameless_exchange ||= client.exchange('') + end -# Return a queue named "messages". This will create the queue on -# the server, if it did not already exist. Again, we use a class -# method to share this across requests. -def messages_queue - $messages_queue ||= client.queue("messages") -end + # Return a queue named "messages". This will create the queue on + # the server, if it did not already exist. Again, we use a class + # method to share this across requests. + def messages_queue + $messages_queue ||= client.queue("messages") + end -def take_session key - res = session[key] - session[key] = nil - res -end + def take_session key + res = session[key] + session[key] = nil + res + end -get '/' do - @published = take_session(:published) - @got = take_session(:got) - erb :index -end + get '/' do + @published = take_session(:published) + @got = take_session(:got) + erb :index + end -post '/publish' do - # Send the message from the form's input box to the "messages" - # queue, via the nameless exchange. The name of the queue to - # publish to is specified in the routing key. - nameless_exchange.publish params[:message], :content_type => "text/plain", - :key => "messages" - # Notify the user that we published. - session[:published] = true - redirect to('/') -end + post '/publish' do + # Send the message from the form's input box to the "messages" + # queue, via the nameless exchange. The name of the queue to + # publish to is specified in the routing key. + nameless_exchange.publish params[:message], :content_type => "text/plain", + :key => "messages" + # Notify the user that we published. + session[:published] = true + redirect to('/') + end -post '/get' do - session[:got] = :queue_empty + post '/get' do + session[:got] = :queue_empty - # Wait for a message from the queue - messages_queue.subscribe(:ack => true, :timeout => 10, - :message_max => 1) do |msg| - # Show the user what we got - session[:got] = msg[:payload] - end + # Wait for a message from the queue + messages_queue.subscribe(:ack => true, :timeout => 10, + :message_max => 1) do |msg| + # Show the user what we got + session[:got] = msg[:payload] + end - redirect to('/') + redirect to('/') + end end diff --git a/spring/README b/spring/README deleted file mode 100644 index 2fe232f..0000000 --- a/spring/README +++ /dev/null @@ -1,6 +0,0 @@ -This is a very simple Spring application demonstrating the use of the -RabbitMQ service on Cloud Foundry. - -See - -for a tutorial corresponding to this application. \ No newline at end of file diff --git a/spring/README.md b/spring/README.md new file mode 100644 index 0000000..91189e2 --- /dev/null +++ b/spring/README.md @@ -0,0 +1,10 @@ +This is a very simple Java and Spring application demonstrating the use of RabbitMQ on Cloud Foundry. + +## Deploying to Cloud Foundry ## + +After installing in the 'cf' [command-line interface](http://docs.cloudfoundry.com/docs/using/managing-apps/cf/) for Cloud Foundry, targeting a Cloud Foundry instance, and logging in, the application can be pushed using these commands: + + $ mvn package + $ cf push + +The provided `manifest.yml` file will be used to provide the application parameters to Cloud Foundry. You may need to provide a different URL for the application if the `rabbitmq-spring` URL is already being used in your Cloud Foundry domain. The `manifest.yml` file specifies a RabbitMQ services that is available on the [run.pivotal.io](http://docs.cloudfoundry.com/docs/dotcom/getting-started.html) Cloud Foundry services marketplace. You may need to change the details of the RabbitMQ service to push to a different Cloud Foundry instance. diff --git a/spring/manifest.yml b/spring/manifest.yml new file mode 100644 index 0000000..f6ddda7 --- /dev/null +++ b/spring/manifest.yml @@ -0,0 +1,13 @@ +--- +applications: +- name: rabbitmq-spring + memory: 512M + instances: 1 + url: rabbitmq-spring.${target-base} + path: target/rabbitmq-spring-1.0-SNAPSHOT.war + services: + rabbit-sample: + label: cloudamqp + provider: cloudamqp + version: n/a + plan: lemur diff --git a/spring/pom.xml b/spring/pom.xml index 56cac68..fcf6aa9 100644 --- a/spring/pom.xml +++ b/spring/pom.xml @@ -2,10 +2,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.rabbitmq.cftutorial - simple + rabbitmq-spring war 1.0-SNAPSHOT - cftutorial-simple + rabbitmq-spring Simple Cloud Foundry Tutorial Application @@ -45,7 +45,7 @@ org.cloudfoundry cloudfoundry-runtime - 0.7.1 + 0.8.4