lapin 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +27 -0
- data/.travis.yml +14 -0
- data/Gemfile +9 -0
- data/README.md +59 -0
- data/Rakefile +13 -0
- data/examples/subscriber.rb +26 -0
- data/lapin.gemspec +34 -0
- data/lib/lapin/config.rb +43 -0
- data/lib/lapin/server.rb +83 -0
- data/lib/lapin/version.rb +5 -0
- data/lib/lapin.rb +38 -0
- data/test/config_test.rb +29 -0
- data/test/server_test.rb +83 -0
- data/test/test_helper.rb +27 -0
- metadata +241 -0
data/.gitignore
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
coverage
|
6
|
+
InstalledFiles
|
7
|
+
lib/bundler/man
|
8
|
+
pkg
|
9
|
+
rdoc
|
10
|
+
spec/reports
|
11
|
+
test/tmp
|
12
|
+
test/version_tmp
|
13
|
+
tmp
|
14
|
+
public
|
15
|
+
example
|
16
|
+
|
17
|
+
# YARD artifacts
|
18
|
+
.yardoc
|
19
|
+
_yardoc
|
20
|
+
doc/
|
21
|
+
.DS_Store
|
22
|
+
config.ru.development
|
23
|
+
.rbx
|
24
|
+
log
|
25
|
+
.DS_Store
|
26
|
+
config.ru
|
27
|
+
Gemfile.lock
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Lapin
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/giraffi/lapin.png?branch=master)](http://travis-ci.org/giraffi/lapin) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/giraffi/lapin)
|
4
|
+
|
5
|
+
A sinatra-based app that provides a JSON endpoint over HTTP for interacting with an AMQP message broker.
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
* [RabbitMQ](http://www.rabbitmq.com/) server
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
```bash
|
14
|
+
$ gem install lapin
|
15
|
+
```
|
16
|
+
|
17
|
+
To use with bundler, drop in your Gemfile.
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem "lapin", :git => "git://github.com/giraffi/lapin.git"
|
21
|
+
```
|
22
|
+
|
23
|
+
## Setup
|
24
|
+
|
25
|
+
Create `config.ru` in the root folder of your app.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'lapin'
|
29
|
+
|
30
|
+
Lapin::Config.amqp_url = 'amqp://guest:guest@localhost/vhost'
|
31
|
+
Lapin::Config.exchange = 'amq.direct'
|
32
|
+
Lapin::Config.logging = true if ENV['RACK_ENV'] == 'development'
|
33
|
+
Lapin.options.quiet = false
|
34
|
+
|
35
|
+
run Lapin::Server
|
36
|
+
```
|
37
|
+
|
38
|
+
## Usage
|
39
|
+
|
40
|
+
Just do the following to start `Lapin::Server` using [thin](https://github.com/macournoyer/thin/) for the web server.
|
41
|
+
|
42
|
+
```bash
|
43
|
+
$ thin start -R config.ru
|
44
|
+
```
|
45
|
+
|
46
|
+
Or, for [passenger](http://www.modrails.com/) (standalone version),
|
47
|
+
|
48
|
+
```bash
|
49
|
+
$ passenger start -R config.ru
|
50
|
+
```
|
51
|
+
|
52
|
+
To handle a POST request like below, you need a running RabbitMQ server according to the `Lapin::Config.amqp_url` option beforehand.
|
53
|
+
|
54
|
+
```bash
|
55
|
+
$ curl -v \
|
56
|
+
> -H "Accept: application/json" -H "Content-type: application/json" -H "X-ROUTING-KEY: amqp.giraffi" \
|
57
|
+
> -X POST -d '{"user":{"name":"foo", "email":"hoge@example.com"}}' \
|
58
|
+
> http://localhost:3000/publish.json
|
59
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
desc "Default: run unit tests"
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc "Test Lapin"
|
9
|
+
Rake::TestTask.new(:test) do |test|
|
10
|
+
test.libs << 'lib' << 'test'
|
11
|
+
test.pattern = 'test/**/*_test.rb'
|
12
|
+
test.verbose = true
|
13
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require "amqp"
|
5
|
+
|
6
|
+
AMQP.start(host: 'localhost') do |conn|
|
7
|
+
channel = AMQP::Channel.new(conn)
|
8
|
+
exchange = channel.direct('amqp.direct')
|
9
|
+
queue = channel.queue("", exclusive: true)
|
10
|
+
queue.bind(exchange, routing_key: 'amqp.giraffi')
|
11
|
+
|
12
|
+
Signal.trap("INT") do
|
13
|
+
conn.close do
|
14
|
+
EM.stop { exit }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
puts " [*] Waiting for logs. To exit press CTRL+C"
|
19
|
+
|
20
|
+
i = 1
|
21
|
+
queue.subscribe do |header, payload|
|
22
|
+
#puts " [x] #{header}:#{payload}"
|
23
|
+
puts " [x] #{header} ----- #{i}"
|
24
|
+
i += 1
|
25
|
+
end
|
26
|
+
end
|
data/lapin.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'lapin/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "lapin"
|
8
|
+
s.version = Lapin::VERSION
|
9
|
+
s.authors = ["azukiwasher"]
|
10
|
+
s.email = ["azukiwasher@higanworks.com"]
|
11
|
+
s.homepage = "https://github.com/giraffi/lapin.git"
|
12
|
+
s.summary = %q{A sinatra-based app that redirects data received via HTTP to an AMQP message broker}
|
13
|
+
s.description = %q{A sinatra-based app that redirects data received via HTTP to an AMQP message broker.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "lapin"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency "rack", "~> 1.4.0"
|
23
|
+
s.add_dependency "bunny", "~> 0.8.0"
|
24
|
+
s.add_dependency "multi_json", "~> 1.3.0"
|
25
|
+
s.add_dependency "sinatra", "~> 1.3.0"
|
26
|
+
|
27
|
+
s.add_development_dependency "rake"
|
28
|
+
s.add_development_dependency "yajl-ruby"
|
29
|
+
s.add_development_dependency "rack-test"
|
30
|
+
s.add_development_dependency "shoulda"
|
31
|
+
s.add_development_dependency "simplecov"
|
32
|
+
s.add_development_dependency "mocha"
|
33
|
+
s.add_development_dependency "thin"
|
34
|
+
end
|
data/lib/lapin/config.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Lapin
|
5
|
+
class Config
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :amqp_url, :vhost
|
9
|
+
attr_accessor :exchange, :routing_key
|
10
|
+
attr_accessor :logging
|
11
|
+
|
12
|
+
def amqp_config
|
13
|
+
uri = URI.parse(amqp_url)
|
14
|
+
{
|
15
|
+
:user => uri.user,
|
16
|
+
:pass => uri.password,
|
17
|
+
:host => uri.host,
|
18
|
+
:port => (uri.port || 5672),
|
19
|
+
:vhost => @vhost || uri.path ,
|
20
|
+
:logging => @logging || false
|
21
|
+
}
|
22
|
+
rescue Object => e
|
23
|
+
raise "Invalid AMQP url: #{uri.inspect} (#{e})"
|
24
|
+
end
|
25
|
+
|
26
|
+
def amqp_url
|
27
|
+
@amqp_url ||= ENV["AMQP_URL"] || "amqp://guest:guest@localhost"
|
28
|
+
end
|
29
|
+
|
30
|
+
def vhost
|
31
|
+
@vhost
|
32
|
+
end
|
33
|
+
|
34
|
+
def exchange
|
35
|
+
@exchange ||= "amq.direct"
|
36
|
+
end
|
37
|
+
|
38
|
+
def routing_key
|
39
|
+
@routing_key ||= "*"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/lapin/server.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'multi_json'
|
4
|
+
|
5
|
+
module Lapin
|
6
|
+
class Server < Sinatra::Base
|
7
|
+
|
8
|
+
# Reduce the amount of data transferred
|
9
|
+
# from the app.
|
10
|
+
use Rack::Deflater
|
11
|
+
|
12
|
+
set :raise_error => false
|
13
|
+
set :show_exception => false
|
14
|
+
|
15
|
+
helpers do
|
16
|
+
# define helper methods
|
17
|
+
def json_status(code, reason)
|
18
|
+
content_type "application/json"
|
19
|
+
status code
|
20
|
+
MultiJson.encode({:status => code, :reason => reason})
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_json(data)
|
24
|
+
begin
|
25
|
+
if MultiJson.respond_to?(:adapter)
|
26
|
+
MultiJson.load(data)
|
27
|
+
else
|
28
|
+
MultiJson.decode(data)
|
29
|
+
end
|
30
|
+
return true
|
31
|
+
rescue
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
error do
|
38
|
+
e = request.env['sinatra.error']
|
39
|
+
Lapin.log "Error: #{e.class}: #{e.message}"
|
40
|
+
json_status 412, e.message
|
41
|
+
end
|
42
|
+
|
43
|
+
# Create an exchange from the current AMQP connection.
|
44
|
+
def exchange
|
45
|
+
@exchange ||= Lapin.client.exchange(Config.exchange, :type => 'direct')
|
46
|
+
end
|
47
|
+
|
48
|
+
# Recieve post data, validate and redirect it
|
49
|
+
# to an AMQP broker.
|
50
|
+
post '/publish.json' do
|
51
|
+
content_type :json
|
52
|
+
|
53
|
+
begin
|
54
|
+
# Set routing key from headers
|
55
|
+
Config.routing_key = request.env['HTTP_X_ROUTING_KEY']
|
56
|
+
|
57
|
+
# Set payload from bod
|
58
|
+
payload = request.body.read
|
59
|
+
|
60
|
+
if validate_json(payload)
|
61
|
+
exchange.publish(payload, :key => Config.routing_key)
|
62
|
+
|
63
|
+
# No Content
|
64
|
+
status 204
|
65
|
+
else
|
66
|
+
# Bad request
|
67
|
+
status 400
|
68
|
+
end
|
69
|
+
rescue Errno::ECONNRESET => e
|
70
|
+
Lapin.log "Error: #{e.class}: #{e.message}"
|
71
|
+
Lapin.client = nil
|
72
|
+
|
73
|
+
# Bad gateway
|
74
|
+
json_status 502, e.message
|
75
|
+
rescue Bunny::ConnectionError, Bunny::ServerDownError => e
|
76
|
+
Lapin.log "Error: #{e.class}: #{e.message}"
|
77
|
+
|
78
|
+
# Bad gateway
|
79
|
+
json_status 502, e.message
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/lapin.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
ENV['RACK_ENV'] ||= 'development'
|
5
|
+
|
6
|
+
require 'bunny'
|
7
|
+
require 'lapin/config'
|
8
|
+
require 'lapin/server'
|
9
|
+
|
10
|
+
module Lapin
|
11
|
+
class << self
|
12
|
+
attr_accessor :options
|
13
|
+
attr_accessor :client
|
14
|
+
|
15
|
+
def options
|
16
|
+
@options ||= Struct.new(:debug, :quiet).new
|
17
|
+
@options.debug ||= false
|
18
|
+
@options.quiet ||= false
|
19
|
+
@options
|
20
|
+
end
|
21
|
+
|
22
|
+
def client
|
23
|
+
unless @client
|
24
|
+
c = ::Bunny.new(Config.amqp_config)
|
25
|
+
c.start
|
26
|
+
@client = c
|
27
|
+
end
|
28
|
+
@client
|
29
|
+
end
|
30
|
+
|
31
|
+
def log(msg)
|
32
|
+
unless options.quiet
|
33
|
+
time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
|
34
|
+
puts "** [#{time}] #$$: #{msg}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/test/config_test.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class ConfigTest < Test::Unit::TestCase
|
5
|
+
context 'AMQP URL parsing' do
|
6
|
+
setup do
|
7
|
+
Lapin::Config.amqp_url = 'amqp://guest:guest@localhost:5671/my-vhost'
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'handle all options properly' do
|
11
|
+
assert_equal Lapin::Config.amqp_config[:user], 'guest'
|
12
|
+
assert_equal Lapin::Config.amqp_config[:pass], 'guest'
|
13
|
+
assert_equal Lapin::Config.amqp_config[:host], 'localhost'
|
14
|
+
assert_equal Lapin::Config.amqp_config[:port], 5671
|
15
|
+
assert_equal Lapin::Config.amqp_config[:vhost], '/my-vhost'
|
16
|
+
assert_equal Lapin::Config.amqp_config[:logging], false
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'overwrite vhost by the vhost attribute' do
|
20
|
+
Lapin::Config.vhost = 'your-vhost'
|
21
|
+
assert_equal Lapin::Config.amqp_config[:vhost], 'your-vhost'
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'set routing key to * when x-routing-key is nil' do
|
25
|
+
Lapin::Config.routing_key = nil
|
26
|
+
assert_equal "*", Lapin::Config.routing_key
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/test/server_test.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'test_helper'
|
3
|
+
require 'mocha'
|
4
|
+
|
5
|
+
class ServerTest < Test::Unit::TestCase
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
def app
|
9
|
+
Lapin::Server.new
|
10
|
+
end
|
11
|
+
|
12
|
+
context "POST /publish.json" do
|
13
|
+
setup do
|
14
|
+
@payload = "{\"data\": \"sample\"}"
|
15
|
+
Lapin::Config.amqp_url = 'amqp://guest:guest@localhost/'
|
16
|
+
end
|
17
|
+
|
18
|
+
teardown do
|
19
|
+
@payload = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
should "return 204 with an appropriate request" do
|
23
|
+
m = mock()
|
24
|
+
Bunny.expects(:new).with(Lapin::Config.amqp_config).returns(m)
|
25
|
+
m.expects(:start)
|
26
|
+
e = mock("exchange")
|
27
|
+
m.stubs(:exchange).with(Lapin::Config.exchange, {:type => 'direct'}).returns(e)
|
28
|
+
e.stubs(:publish).with(@payload, {:key => 'giraffi.nagios'})
|
29
|
+
|
30
|
+
post "/publish.json", @payload, {"CONTENT_TYPE" => "application/json", "HTTP_X_ROUTING_KEY" => "giraffi.nagios"}
|
31
|
+
assert_equal last_request.body.string, @payload
|
32
|
+
assert_equal last_response.status, 204
|
33
|
+
end
|
34
|
+
|
35
|
+
should "return 400 with a malformed request body" do
|
36
|
+
post "/publish.json", "malformed_body", {"CONTENT_TYPE" => "text/plain"}
|
37
|
+
assert_equal last_response.status, 400
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "Error handling" do
|
42
|
+
setup do
|
43
|
+
Lapin.options.quiet = true
|
44
|
+
end
|
45
|
+
|
46
|
+
should "return 412 when the sinatra.error is catched" do
|
47
|
+
m = mock()
|
48
|
+
Bunny.expects(:new).with(Lapin::Config.amqp_config).returns(m)
|
49
|
+
m.stubs(:start).raises(Exception.new)
|
50
|
+
|
51
|
+
post "/publish.json", @payload, {"CONTENT_TYPE" => "application/json"}
|
52
|
+
assert_equal last_response.status, 412
|
53
|
+
end
|
54
|
+
|
55
|
+
should "return 502 when the connection is reset by peer" do
|
56
|
+
m = mock()
|
57
|
+
Bunny.expects(:new).with(Lapin::Config.amqp_config).returns(m)
|
58
|
+
m.stubs(:start).raises(Errno::ECONNRESET.new)
|
59
|
+
|
60
|
+
post "/publish.json", @payload, {"CONTENT_TYPE" => "application/json"}
|
61
|
+
assert_equal last_response.status, 502
|
62
|
+
end
|
63
|
+
|
64
|
+
should "return 502 when the no connection and no socket are found" do
|
65
|
+
m = mock()
|
66
|
+
Bunny.expects(:new).with(Lapin::Config.amqp_config).returns(m)
|
67
|
+
m.stubs(:start).raises(Bunny::ConnectionError.new)
|
68
|
+
|
69
|
+
post "/publish.json", @payload, {"CONTENT_TYPE" => "application/json"}
|
70
|
+
assert_equal last_response.status, 502
|
71
|
+
end
|
72
|
+
|
73
|
+
should "return 502 when the broken pipe is catched" do
|
74
|
+
m = mock()
|
75
|
+
Bunny.expects(:new).with(Lapin::Config.amqp_config).returns(m)
|
76
|
+
m.stubs(:start).raises(Bunny::ServerDownError.new)
|
77
|
+
|
78
|
+
post "/publish.json", @payload, {"CONTENT_TYPE" => "application/json"}
|
79
|
+
assert_equal last_response.status, 502
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
# Configure Rack Environment
|
7
|
+
ENV['RACK_ENV'] = "test"
|
8
|
+
|
9
|
+
begin
|
10
|
+
Bundler.setup(:default, :development)
|
11
|
+
rescue Bundler::BundleError => e
|
12
|
+
$stderr.puts e.message
|
13
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
14
|
+
exit e.status_code
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'test/unit'
|
18
|
+
require 'shoulda'
|
19
|
+
require 'rack/test'
|
20
|
+
require 'simplecov'
|
21
|
+
SimpleCov.start
|
22
|
+
|
23
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
24
|
+
require 'lapin'
|
25
|
+
|
26
|
+
class Test::Unit::TestCase
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,241 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lapin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- azukiwasher
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rack
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.4.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.4.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bunny
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.8.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.8.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: multi_json
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.3.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.3.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: sinatra
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.3.0
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.3.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rake
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: yajl-ruby
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rack-test
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: shoulda
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: simplecov
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: mocha
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: thin
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
description: A sinatra-based app that redirects data received via HTTP to an AMQP
|
191
|
+
message broker.
|
192
|
+
email:
|
193
|
+
- azukiwasher@higanworks.com
|
194
|
+
executables: []
|
195
|
+
extensions: []
|
196
|
+
extra_rdoc_files: []
|
197
|
+
files:
|
198
|
+
- .gitignore
|
199
|
+
- .travis.yml
|
200
|
+
- Gemfile
|
201
|
+
- README.md
|
202
|
+
- Rakefile
|
203
|
+
- examples/subscriber.rb
|
204
|
+
- lapin.gemspec
|
205
|
+
- lib/lapin.rb
|
206
|
+
- lib/lapin/config.rb
|
207
|
+
- lib/lapin/server.rb
|
208
|
+
- lib/lapin/version.rb
|
209
|
+
- test/config_test.rb
|
210
|
+
- test/server_test.rb
|
211
|
+
- test/test_helper.rb
|
212
|
+
homepage: https://github.com/giraffi/lapin.git
|
213
|
+
licenses: []
|
214
|
+
post_install_message:
|
215
|
+
rdoc_options: []
|
216
|
+
require_paths:
|
217
|
+
- lib
|
218
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
219
|
+
none: false
|
220
|
+
requirements:
|
221
|
+
- - ! '>='
|
222
|
+
- !ruby/object:Gem::Version
|
223
|
+
version: '0'
|
224
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
225
|
+
none: false
|
226
|
+
requirements:
|
227
|
+
- - ! '>='
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
requirements: []
|
231
|
+
rubyforge_project: lapin
|
232
|
+
rubygems_version: 1.8.25
|
233
|
+
signing_key:
|
234
|
+
specification_version: 3
|
235
|
+
summary: A sinatra-based app that redirects data received via HTTP to an AMQP message
|
236
|
+
broker
|
237
|
+
test_files:
|
238
|
+
- test/config_test.rb
|
239
|
+
- test/server_test.rb
|
240
|
+
- test/test_helper.rb
|
241
|
+
has_rdoc:
|