jackalope 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e45828be5b1759f2e22e46f73695282e9ffa25e7
4
+ data.tar.gz: f345d5617158c83ee17fc1ccaf02529edd55b354
5
+ SHA512:
6
+ metadata.gz: 471dac8c6ebf0450ae06ea84ce59aa43e34503a74e019868a9411b7f605f7f4ae68fab6cb9c4a41702d5c58809ac5570a66c58b6b62e924171714b9a39b466ac
7
+ data.tar.gz: 0ab96b2c4213ea3d6a1bc4e7a38848eb054bf6dd11f0e23e6adf2d5433409271cdaa8cc57fe553c4d24c4f59bef4602cc5e03d489ca93cc073c719966ad8bed5
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require emoji-rspec
2
+ --format hearts
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
6
+ - 1.9.2
7
+ - jruby-19mode # JRuby in 1.9 mode
8
+ - ruby-head
9
+ - jruby-head
10
+ - rbx
@@ -0,0 +1,3 @@
1
+ # 0.0.1
2
+
3
+ * Initial version
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ platforms :rbx do
6
+ gem 'racc'
7
+ gem 'rubysl', '~> 2.0'
8
+ gem 'psych'
9
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Optoro, Inc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,38 @@
1
+ [![Build Status](https://travis-ci.org/rack-amqp/jackalope.png?branch=master)](https://travis-ci.org/rack-amqp/jackalope)
2
+
3
+ # Jackalope
4
+
5
+ ![Jackalope](http://beerpulse.com/wp-content/uploads/2010/11/jackalope-brewing.png)
6
+
7
+ AMQP-HTTP compliant Server to run your rack (rails) application using
8
+ AMQP as the transport protocol.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'jackalope'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install jackalope
23
+
24
+ ## Usage
25
+
26
+ jackalope -q <queue name> <rackup file>
27
+
28
+ for rails app:
29
+
30
+ jackalope -q my.queue config.ru
31
+
32
+ ## Contributing
33
+
34
+ 1. Fork it
35
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
36
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
37
+ 4. Push to the branch (`git push origin my-new-feature`)
38
+ 5. Create new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rack/amqp'
4
+ require 'optparse'
5
+
6
+ options = {
7
+ rabbitmq: 'localhost',
8
+ queue_name: 'default.queue',
9
+ debug: false,
10
+ }
11
+
12
+ OptionParser.new do |opts|
13
+ cmd = File.basename($0)
14
+ opts.banner = "Usage: #{cmd} [options] <rackup file>"
15
+
16
+ opts.on("-rHOST", "--rabbitmq HOST", "hostname of the rabbitmq server") do |host|
17
+ options[:rabbitmq] = host
18
+ end
19
+
20
+ opts.on("-qQUEUE", "--queue QUEUE", "queue name that this app subscribes to") do |queue|
21
+ options[:queue_name] = queue
22
+ end
23
+
24
+ opts.on("-d", "--debug", "turn on some debugging messages") do
25
+ options[:debug] = true
26
+ end
27
+
28
+ opts.on_tail("-h", "--help", "Show this message") do
29
+ puts opts.to_s
30
+ exit
31
+ end
32
+
33
+ opts.on_tail("-v", "--version", "Show version") do
34
+ puts "#{cmd} v#{Rack::AMQP::VERSION}"
35
+ exit
36
+ end
37
+
38
+ opts.parse! ARGV
39
+ end
40
+
41
+ Rack::AMQP::Server.start options.merge(rackup_file: File.absolute_path(ARGV[0]))
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rack/amqp/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jackalope"
8
+ spec.version = Rack::AMQP::VERSION
9
+ spec.authors = ["Joshua Szmajda", "John Nestoriak"]
10
+ spec.email = ["josh@optoro.com"]
11
+ spec.description = %q{AMQP-HTTP compliant Server for Rack applications}
12
+ spec.summary = %q{AMQP-HTTP compliant Server for Rack applications}
13
+ spec.homepage = "http://github.com/rack-amqp/jackalope"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "rack"
22
+ spec.add_dependency "amqp"
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "pry"
26
+ spec.add_development_dependency "rspec"
27
+ spec.add_development_dependency "emoji-rspec"
28
+ end
@@ -0,0 +1,12 @@
1
+ require 'rack'
2
+ require 'amqp'
3
+ require 'rack/content_length'
4
+ require 'rack/rewindable_input'
5
+
6
+ module Rack
7
+ module AMQP
8
+ end
9
+ end
10
+
11
+ require 'rack/amqp/version'
12
+ require 'rack/amqp/server'
@@ -0,0 +1,17 @@
1
+ module Rack
2
+ module AMQP
3
+ class << self
4
+ attr_accessor :configuration
5
+ end
6
+
7
+ def self.configure
8
+ self.configuration ||= Configuration.new
9
+ yield(configuration)
10
+ end
11
+
12
+ class Configuration
13
+ attr_accessor :rabbit_host
14
+ attr_accessor :queue_name
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,140 @@
1
+ require "rack/amqp/configuration"
2
+
3
+ module Rack
4
+ module AMQP
5
+ class Server
6
+
7
+ def self.start(options={})
8
+ new(options).start
9
+ end
10
+
11
+ attr_reader :options, :debug
12
+
13
+ def initialize(options)
14
+ @options = options
15
+ Rack::AMQP.configure do |config|
16
+ config.rabbit_host = options[:rabbitmq]
17
+ config.queue_name = options[:queue_name]
18
+ end
19
+ @debug = options[:debug]
20
+ end
21
+
22
+ def server_agent
23
+ "rabbicorn-#{Rack::AMQP::VERSION}"
24
+ end
25
+
26
+ def configuration
27
+ Rack::AMQP.configuration
28
+ end
29
+
30
+ def start
31
+ ::AMQP.start(host: configuration.rabbit_host) do |client, open_ok|
32
+ chan = ::AMQP::Channel.new(client)
33
+
34
+ chan.queue(configuration.queue_name, auto_delete: true).subscribe do |metadata, payload|
35
+ if debug
36
+ puts "Received meta: #{metadata.inspect}"
37
+ puts "Received message: #{payload.inspect}"
38
+ end
39
+ response, headers = handle_request(metadata, payload)
40
+
41
+ message_id = metadata.message_id
42
+ reply_to = metadata.reply_to
43
+
44
+ amqp_headers = {
45
+ routing_key: reply_to,
46
+ correlation_id: message_id,
47
+ type: 'REPLY',
48
+ app_id: server_agent,
49
+ timestamp: Time.now.to_i,
50
+ headers: headers
51
+ }
52
+ if type = headers['Content-Type']
53
+ amqp_headers[:content_type] = type
54
+ end
55
+ if enc = headers['Content-Encoding']
56
+ amqp_headers[:content_encoding] = enc
57
+ end
58
+
59
+ chan.direct("").publish(response, amqp_headers)
60
+ end
61
+
62
+ puts "#{server_agent} running"
63
+ end
64
+ end
65
+
66
+ def handle_request(meta, body)
67
+ headers = meta.headers
68
+ http_method = meta.type
69
+ path = headers['path']
70
+
71
+ parts = path.split(/\?/)
72
+ uri = parts[0]
73
+ query = parts[1] || ""
74
+
75
+ env = default_env
76
+ env.update({
77
+ 'REQUEST_METHOD' => http_method,
78
+ 'PATH_INFO' => uri,
79
+ 'QUERY_STRING' => query,
80
+ 'REQUEST_PATH' => uri,
81
+ 'CONTENT_LENGH' => headers['Content-Length'],
82
+ 'CONTENT_TYPE' => headers['Content-Type'],
83
+ "rack.input" => StringIO.new(body)
84
+ })
85
+
86
+ # puts "call env: #{env.inspect}"
87
+
88
+ response_code, headers, body = app.call(env)
89
+
90
+ headers.merge!('X-AMQP-HTTP-Status' => response_code)
91
+
92
+ body_chunks = []
93
+ body.each { |chunk| body_chunks << chunk }
94
+ body.close
95
+
96
+ [body_chunks.join, headers]
97
+ end
98
+
99
+ private
100
+
101
+ def default_env
102
+ @default_env = begin
103
+ env = ENV.to_hash
104
+ env.update({
105
+ "rack.version" => Rack::VERSION,
106
+ "rack.input" => Rack::RewindableInput.new($stdin),
107
+ "rack.errors" => $stderr,
108
+
109
+ "rack.multithread" => false,
110
+ "rack.multiprocess" => true,
111
+ "rack.run_once" => false,
112
+
113
+ "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http",
114
+
115
+ 'SERVER_NAME' => 'howdy',
116
+ 'SERVER_PORT' => '80',
117
+ 'HTTP_VERSION' => '1.1',
118
+ })
119
+ end
120
+ end
121
+
122
+ def app
123
+ @app ||= construct_app(options[:rackup_file])
124
+ end
125
+
126
+ def construct_app rackup_file_name
127
+ raw = ::File.read(rackup_file_name)
128
+ app = eval("Rack::Builder.new {( #{raw} )}.to_app")
129
+ Rack::Builder.new do
130
+ use Rack::ContentLength
131
+ # use Rack::Chunked TODO Maybe eventually
132
+ use Rack::ShowExceptions
133
+ use Rack::CommonLogger, $stderr
134
+ run app
135
+ end.to_app
136
+ end
137
+
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ module AMQP
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rack::AMQP::Configuration do
4
+ it 'yields a configuration' do
5
+ x = nil
6
+ Rack::AMQP.configure do |c|
7
+ x = c
8
+ end
9
+ expect(x).to_not be_nil
10
+ end
11
+
12
+ it 'allows configuration querying' do
13
+ expect(Rack::AMQP.configuration).to_not be_nil
14
+ end
15
+
16
+ it 'accepts the rabbit host' do
17
+ Rack::AMQP.configure { |c| c.rabbit_host = 'foo' }
18
+ expect(Rack::AMQP.configuration.rabbit_host).to eql('foo')
19
+ end
20
+
21
+ it 'accepts the queue name' do
22
+ Rack::AMQP.configure { |c| c.queue_name = 'bar' }
23
+ expect(Rack::AMQP.configuration.queue_name).to eql('bar')
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rack::AMQP::Server do
4
+ it 'passes input to rack'
5
+ it 'keeps running'
6
+
7
+ it 'calls handle_request on event input'
8
+
9
+ describe '#construct_app' do
10
+ it 'builds a Rack app with the given rackup file inside'
11
+ end
12
+
13
+ describe '#default_env' do
14
+ it 'looks like HTTP enough'
15
+ end
16
+
17
+ describe 'command line' do
18
+ it 'handles when the user forgets to specity the rackup file'
19
+ end
20
+
21
+ describe 'client failures' do
22
+ it 'handles when the client forgets to specify the http_method'
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rack::AMQP do
4
+ it 'exists' do
5
+ Rack::AMQP
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ require 'rspec'
2
+ require 'rack/amqp'
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jackalope
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Joshua Szmajda
8
+ - John Nestoriak
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-04-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: amqp
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: '1.3'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '1.3'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: emoji-rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: AMQP-HTTP compliant Server for Rack applications
113
+ email:
114
+ - josh@optoro.com
115
+ executables:
116
+ - jackalope
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - .gitignore
121
+ - .rspec
122
+ - .travis.yml
123
+ - CHANGELOG.md
124
+ - Gemfile
125
+ - LICENSE
126
+ - README.md
127
+ - Rakefile
128
+ - bin/jackalope
129
+ - jackalope.gemspec
130
+ - lib/rack/amqp.rb
131
+ - lib/rack/amqp/configuration.rb
132
+ - lib/rack/amqp/server.rb
133
+ - lib/rack/amqp/version.rb
134
+ - spec/rack/amqp/configuration_spec.rb
135
+ - spec/rack/amqp/server_spec.rb
136
+ - spec/rack/amqp_spec.rb
137
+ - spec/spec_helper.rb
138
+ homepage: http://github.com/rack-amqp/jackalope
139
+ licenses:
140
+ - MIT
141
+ metadata: {}
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 2.2.2
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: AMQP-HTTP compliant Server for Rack applications
162
+ test_files:
163
+ - spec/rack/amqp/configuration_spec.rb
164
+ - spec/rack/amqp/server_spec.rb
165
+ - spec/rack/amqp_spec.rb
166
+ - spec/spec_helper.rb