stapfen 1.4.3 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +5 -1
- data/lib/stapfen/destination.rb +35 -0
- data/lib/stapfen/message.rb +58 -0
- data/lib/stapfen/version.rb +1 -1
- data/lib/stapfen/worker.rb +99 -0
- data/lib/stapfen.rb +2 -0
- data/spec/destination_spec.rb +45 -0
- data/spec/message_spec.rb +96 -0
- data/spec/spec_helper.rb +15 -1
- data/spec/worker_spec.rb +25 -0
- data/stapfen.gemspec +0 -3
- metadata +11 -21
data/Gemfile
CHANGED
@@ -3,10 +3,14 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in stapfen.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
gem 'jruby-jms', :platform => :jruby
|
7
|
+
gem 'stomp', '>= 1.2.14'
|
6
8
|
|
7
9
|
group :development do
|
8
10
|
gem 'rake'
|
9
11
|
gem 'rspec', '~> 2.11'
|
10
12
|
gem 'guard-rspec'
|
11
|
-
gem '
|
13
|
+
gem 'pry'
|
14
|
+
gem 'debugger', :platform => :mri
|
15
|
+
gem 'debugger-pry', :platform => :mri
|
12
16
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Stapfen
|
2
|
+
class Destination
|
3
|
+
attr_accessor :name, :type
|
4
|
+
|
5
|
+
def queue?
|
6
|
+
@type == :queue
|
7
|
+
end
|
8
|
+
|
9
|
+
def topic?
|
10
|
+
@type == :topic
|
11
|
+
end
|
12
|
+
|
13
|
+
def as_stomp
|
14
|
+
if queue?
|
15
|
+
return "/queue/#{@name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
if topic?
|
19
|
+
return "/topic/#{@name}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Create a {Stapfen::Destination} from the given string
|
24
|
+
#
|
25
|
+
# @param [String] name
|
26
|
+
# @return [Stapfen::Destination]
|
27
|
+
def self.from_string(name)
|
28
|
+
destination = self.new
|
29
|
+
pieces = name.split('/')
|
30
|
+
destination.type = pieces[1].to_sym
|
31
|
+
destination.name = pieces[2 .. -1].join('/')
|
32
|
+
return destination
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
begin
|
2
|
+
require 'stomp'
|
3
|
+
rescue LoadError
|
4
|
+
# Can't process Stomp
|
5
|
+
end
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'java'
|
9
|
+
require 'jms'
|
10
|
+
rescue LoadError
|
11
|
+
# Can't process JMS
|
12
|
+
end
|
13
|
+
|
14
|
+
module Stapfen
|
15
|
+
class Message
|
16
|
+
attr_reader :message_id, :body, :original, :destination
|
17
|
+
|
18
|
+
def initialize(opts={})
|
19
|
+
super()
|
20
|
+
@body = opts[:body]
|
21
|
+
@destination = opts[:destination]
|
22
|
+
@message_id = opts[:message_id]
|
23
|
+
@original = opts[:original]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Create an instance of {Stapfen::Message} from the passed in
|
27
|
+
# {Stomp::Message}
|
28
|
+
#
|
29
|
+
# @param [Stomp::Message] message A message created by the Stomp gem
|
30
|
+
# @return [Stapfen::Message] A Stapfen wrapper object
|
31
|
+
def self.from_stomp(message)
|
32
|
+
unless message.kind_of? Stomp::Message
|
33
|
+
raise Stapfen::InvalidMessageError, message.inspect
|
34
|
+
end
|
35
|
+
|
36
|
+
return self.new(:body => message.body,
|
37
|
+
:destination => message.headers['destination'],
|
38
|
+
:message_id => message.headers['message-id'],
|
39
|
+
:original => message)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Create an instance of {Stapfen::Message} from the passed in
|
43
|
+
# +ActiveMQBytesMessage+ which a JMS consumer should receive
|
44
|
+
#
|
45
|
+
# @param [ActiveMQBytesMessage] message
|
46
|
+
# @return [Stapfen::Message] A Stapfen wrapper object
|
47
|
+
def self.from_jms(message)
|
48
|
+
unless message.kind_of? Java::JavaxJms::Message
|
49
|
+
raise Stapfen::InvalidMessageError, message.inspect
|
50
|
+
end
|
51
|
+
|
52
|
+
return self.new(:body => message.data,
|
53
|
+
:destination => message.jms_destination.getQualifiedName,
|
54
|
+
:message_id => message.jms_message_id,
|
55
|
+
:original => message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/stapfen/version.rb
CHANGED
data/lib/stapfen/worker.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
require 'stomp'
|
2
2
|
require 'stapfen/logger'
|
3
|
+
require 'stapfen/destination'
|
4
|
+
require 'stapfen/message'
|
3
5
|
|
4
6
|
module Stapfen
|
5
7
|
class Worker
|
6
8
|
include Stapfen::Logger
|
7
9
|
|
10
|
+
# Class variables!
|
8
11
|
@@signals_handled = false
|
9
12
|
@@workers = []
|
10
13
|
|
14
|
+
# Class instance variables!
|
15
|
+
@use_stomp = true
|
16
|
+
|
11
17
|
class << self
|
12
18
|
attr_accessor :configuration, :consumers, :logger, :destructor
|
19
|
+
|
13
20
|
end
|
14
21
|
|
15
22
|
# Instantiate a new +Worker+ instance and run it
|
@@ -33,6 +40,51 @@ module Stapfen
|
|
33
40
|
@configuration = block
|
34
41
|
end
|
35
42
|
|
43
|
+
# Force the worker to use STOMP as the messaging protocol (default)
|
44
|
+
#
|
45
|
+
# @return [Boolean]
|
46
|
+
def self.use_stomp!
|
47
|
+
begin
|
48
|
+
require 'stomp'
|
49
|
+
rescue LoadError
|
50
|
+
puts "You need the `stomp` gem to be installed to use stomp!"
|
51
|
+
raise
|
52
|
+
end
|
53
|
+
|
54
|
+
@use_stomp = true
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.stomp?
|
59
|
+
@use_stomp
|
60
|
+
end
|
61
|
+
|
62
|
+
# Force the worker to use JMS as the messaging protocol.
|
63
|
+
#
|
64
|
+
# *Note:* Only works under JRuby
|
65
|
+
#
|
66
|
+
# @return [Boolean]
|
67
|
+
def self.use_jms!
|
68
|
+
unless RUBY_PLATFORM == 'java'
|
69
|
+
raise Stapfen::ConfigurationError, "You cannot use JMS unless you're running under JRuby!"
|
70
|
+
end
|
71
|
+
|
72
|
+
begin
|
73
|
+
require 'java'
|
74
|
+
require 'jms'
|
75
|
+
rescue LoadError
|
76
|
+
puts "You need the `jms` gem to be installed to use JMS!"
|
77
|
+
raise
|
78
|
+
end
|
79
|
+
|
80
|
+
@use_stomp = false
|
81
|
+
return true
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.jms?
|
85
|
+
!(@use_stomp)
|
86
|
+
end
|
87
|
+
|
36
88
|
# Optional method, should be passed a block which will yield a {{Logger}}
|
37
89
|
# instance for the Stapfen worker to use
|
38
90
|
def self.log
|
@@ -105,6 +157,53 @@ module Stapfen
|
|
105
157
|
attr_accessor :client
|
106
158
|
|
107
159
|
def run
|
160
|
+
if self.class.stomp?
|
161
|
+
run_stomp
|
162
|
+
elsif self.class.jms?
|
163
|
+
run_jms
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def run_jms
|
168
|
+
JMS::Connection.start(self.class.configuration.call) do |connection|
|
169
|
+
@client = connection
|
170
|
+
debug("Running with #{@client} inside of Thread:#{Thread.current.inspect}")
|
171
|
+
|
172
|
+
self.class.consumers.each do |name, headers, block|
|
173
|
+
destination = Stapfen::Destination.from_string(name)
|
174
|
+
type = 'queue'
|
175
|
+
options = {}
|
176
|
+
|
177
|
+
if destination.queue?
|
178
|
+
options[:queue_name] = destination.name
|
179
|
+
end
|
180
|
+
|
181
|
+
if destination.topic?
|
182
|
+
type = 'topic'
|
183
|
+
options[:topic_name] = destination.name
|
184
|
+
end
|
185
|
+
|
186
|
+
method_name = "handle_#{type}_#{name}".to_sym
|
187
|
+
self.class.send(:define_method, method_name, &block)
|
188
|
+
|
189
|
+
connection.on_message(options) do |m|
|
190
|
+
message = Stapfen::Message.from_jms(m)
|
191
|
+
self.send(method_name, message)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
begin
|
196
|
+
loop do
|
197
|
+
sleep 1
|
198
|
+
end
|
199
|
+
debug("Exiting the JMS runloop for #{self}")
|
200
|
+
rescue Interrupt
|
201
|
+
exit_cleanly
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def run_stomp
|
108
207
|
@client = Stomp::Client.new(self.class.configuration.call)
|
109
208
|
debug("Running with #{@client} inside of Thread:#{Thread.current.inspect}")
|
110
209
|
|
data/lib/stapfen.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stapfen/destination'
|
3
|
+
|
4
|
+
describe Stapfen::Destination do
|
5
|
+
it { should respond_to :name }
|
6
|
+
it { should respond_to :type }
|
7
|
+
|
8
|
+
describe '#as_stomp' do
|
9
|
+
let(:name) { 'rspec/dlq' }
|
10
|
+
|
11
|
+
subject(:destination) do
|
12
|
+
d = described_class.new
|
13
|
+
d.type = :queue
|
14
|
+
d.name = name
|
15
|
+
d.as_stomp
|
16
|
+
end
|
17
|
+
|
18
|
+
it { should be_instance_of String }
|
19
|
+
it { should eql "/queue/#{name}" }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'class methods' do
|
23
|
+
describe '#from_string' do
|
24
|
+
subject(:destination) { described_class.from_string(name) }
|
25
|
+
|
26
|
+
context 'a simple queue' do
|
27
|
+
let(:name) { '/queue/rspec' }
|
28
|
+
its(:name) { should eql 'rspec' }
|
29
|
+
its(:type) { should eql :queue }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'a queue with slashes' do
|
33
|
+
let(:name) { '/queue/rspec/dlq' }
|
34
|
+
its(:name) { should eql 'rspec/dlq' }
|
35
|
+
its(:type) { should eql :queue }
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'a complex topic' do
|
39
|
+
let(:name) { '/topic/rspec/dlq' }
|
40
|
+
its(:name) { should eql 'rspec/dlq' }
|
41
|
+
its(:type) { should eql :topic }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stapfen/message'
|
3
|
+
|
4
|
+
if RUBY_PLATFORM == 'java'
|
5
|
+
require 'java'
|
6
|
+
require File.expand_path('./activemq-all-5.8.0.jar')
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Stapfen::Message do
|
10
|
+
context 'accessors' do
|
11
|
+
it { should respond_to :message_id }
|
12
|
+
it { should respond_to :body }
|
13
|
+
it { should respond_to :original }
|
14
|
+
it { should respond_to :destination }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#initialize' do
|
18
|
+
it 'should accept :body' do
|
19
|
+
body = 'hello'
|
20
|
+
m = described_class.new(:body => body)
|
21
|
+
expect(m.body).to eql(body)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'class methods' do
|
26
|
+
let(:body) { 'hello stapfen' }
|
27
|
+
let(:destination) { '/queue/rspec' }
|
28
|
+
let(:message_id) { rand.to_s }
|
29
|
+
|
30
|
+
describe '#from_stomp' do
|
31
|
+
subject(:result) { described_class.from_stomp(message) }
|
32
|
+
|
33
|
+
context 'when passed something other than a Stomp::Message' do
|
34
|
+
let(:message) { 'hello' }
|
35
|
+
|
36
|
+
it 'should raise an error' do
|
37
|
+
expect { result }.to raise_error(Stapfen::InvalidMessageError)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when passed a Stomp::Message' do
|
42
|
+
let(:message) do
|
43
|
+
m = Stomp::Message.new('') # empty frame
|
44
|
+
m.body = body
|
45
|
+
headers = {'destination' => destination,
|
46
|
+
'message-id' => message_id}
|
47
|
+
m.headers = headers
|
48
|
+
m
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should create an instance' do
|
52
|
+
expect(result).to be_instance_of Stapfen::Message
|
53
|
+
end
|
54
|
+
|
55
|
+
its(:body) { should eql body }
|
56
|
+
its(:destination) { should eql destination }
|
57
|
+
its(:message_id) { should eql message_id }
|
58
|
+
its(:original) { should be message }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#from_jms', :java => true do
|
63
|
+
subject(:result) { described_class.from_jms(message) }
|
64
|
+
|
65
|
+
context 'when passed something other than a JMS message' do
|
66
|
+
let(:message) { 'hello' }
|
67
|
+
|
68
|
+
it 'should raise an error' do
|
69
|
+
expect { result }.to raise_error(Stapfen::InvalidMessageError)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when passed an ActiveMQBytesMessage' do
|
74
|
+
let(:destination) { 'queue://rspec' }
|
75
|
+
|
76
|
+
let(:message) do
|
77
|
+
m = Java::OrgApacheActivemqCommand::ActiveMQBytesMessage.new
|
78
|
+
m.stub(:jms_destination => double('ActiveMQDestination mock', :getQualifiedName => destination))
|
79
|
+
m.stub(:jms_message_id => message_id)
|
80
|
+
m.stub(:data => body)
|
81
|
+
m
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should create an instance' do
|
85
|
+
expect(result).to be_instance_of Stapfen::Message
|
86
|
+
end
|
87
|
+
|
88
|
+
its(:body) { should eql body }
|
89
|
+
its(:destination) { should eql destination }
|
90
|
+
its(:message_id) { should eql message_id }
|
91
|
+
its(:original) { should be message }
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,18 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '../lib'))
|
2
2
|
|
3
3
|
require 'stapfen'
|
4
|
-
|
4
|
+
|
5
|
+
|
6
|
+
is_java = (RUBY_PLATFORM == 'java')
|
7
|
+
|
8
|
+
unless is_java
|
9
|
+
require 'debugger'
|
10
|
+
require 'debugger/pry'
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
RSpec.configure do |c|
|
15
|
+
unless is_java
|
16
|
+
c.filter_run_excluding :java => true
|
17
|
+
end
|
18
|
+
end
|
data/spec/worker_spec.rb
CHANGED
@@ -13,6 +13,31 @@ describe Stapfen::Worker do
|
|
13
13
|
it { should respond_to :log }
|
14
14
|
it { should respond_to :shutdown }
|
15
15
|
|
16
|
+
describe '#use_stomp!' do
|
17
|
+
subject(:result) { worker.use_stomp! }
|
18
|
+
|
19
|
+
it 'should update the instance variable' do
|
20
|
+
expect(result).to be_true
|
21
|
+
expect(worker).to be_stomp
|
22
|
+
expect(worker).not_to be_jms
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#use_jms!', :java => true do
|
27
|
+
subject(:result) { worker.use_jms! }
|
28
|
+
|
29
|
+
after :each do
|
30
|
+
# Reset to the default since we've modified the class
|
31
|
+
worker.use_stomp!
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should update the instance variable' do
|
35
|
+
expect(result).to be_true
|
36
|
+
expect(worker).to be_jms
|
37
|
+
expect(worker).not_to be_stomp
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
16
41
|
describe '#configure' do
|
17
42
|
it 'should error when not passed a block' do
|
18
43
|
expect {
|
data/stapfen.gemspec
CHANGED
@@ -16,7 +16,4 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
|
-
|
20
|
-
|
21
|
-
gem.add_dependency('stomp', '>= 1.2.14') # 1.2.14 fixes Stomp::Client#unreceive behavior
|
22
19
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stapfen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
13
|
-
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: stomp
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: 1.2.14
|
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.2.14
|
12
|
+
date: 2013-09-27 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
30
14
|
description: A simple gem for writing good basic STOMP workers
|
31
15
|
email:
|
32
16
|
- rtyler.croy@lookout.com
|
@@ -42,10 +26,14 @@ files:
|
|
42
26
|
- Rakefile
|
43
27
|
- examples/simple.rb
|
44
28
|
- lib/stapfen.rb
|
29
|
+
- lib/stapfen/destination.rb
|
45
30
|
- lib/stapfen/logger.rb
|
31
|
+
- lib/stapfen/message.rb
|
46
32
|
- lib/stapfen/version.rb
|
47
33
|
- lib/stapfen/worker.rb
|
34
|
+
- spec/destination_spec.rb
|
48
35
|
- spec/logger_spec.rb
|
36
|
+
- spec/message_spec.rb
|
49
37
|
- spec/spec_helper.rb
|
50
38
|
- spec/worker_spec.rb
|
51
39
|
- stapfen.gemspec
|
@@ -63,7 +51,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
63
51
|
version: '0'
|
64
52
|
segments:
|
65
53
|
- 0
|
66
|
-
hash: -
|
54
|
+
hash: -1455385429346077259
|
67
55
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
56
|
none: false
|
69
57
|
requirements:
|
@@ -72,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
60
|
version: '0'
|
73
61
|
segments:
|
74
62
|
- 0
|
75
|
-
hash: -
|
63
|
+
hash: -1455385429346077259
|
76
64
|
requirements: []
|
77
65
|
rubyforge_project:
|
78
66
|
rubygems_version: 1.8.25
|
@@ -80,6 +68,8 @@ signing_key:
|
|
80
68
|
specification_version: 3
|
81
69
|
summary: A simple gem for writing good basic STOMP workers
|
82
70
|
test_files:
|
71
|
+
- spec/destination_spec.rb
|
83
72
|
- spec/logger_spec.rb
|
73
|
+
- spec/message_spec.rb
|
84
74
|
- spec/spec_helper.rb
|
85
75
|
- spec/worker_spec.rb
|