serf 0.10.0 → 0.11.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/.gitignore +21 -0
- data/.travis.yml +7 -0
- data/Gemfile +20 -26
- data/Guardfile +16 -0
- data/NOTICE.txt +1 -1
- data/README.md +223 -207
- data/Rakefile +3 -18
- data/lib/serf/builder.rb +31 -136
- data/lib/serf/errors/policy_failure.rb +10 -0
- data/lib/serf/middleware/error_handler.rb +53 -0
- data/lib/serf/middleware/parcel_freezer.rb +36 -0
- data/lib/serf/middleware/parcel_masher.rb +39 -0
- data/lib/serf/middleware/policy_checker.rb +31 -0
- data/lib/serf/middleware/uuid_tagger.rb +13 -11
- data/lib/serf/parcel_builder.rb +30 -0
- data/lib/serf/serfer.rb +27 -66
- data/lib/serf/util/error_handling.rb +13 -36
- data/lib/serf/util/protected_call.rb +2 -2
- data/lib/serf/util/uuidable.rb +14 -38
- data/lib/serf/version.rb +1 -1
- data/schemas/{caught_exception_event.json → serf/events/caught_error.json} +4 -7
- data/serf.gemspec +22 -101
- data/spec/serf/builder_spec.rb +44 -0
- data/spec/serf/errors/policy_failure_spec.rb +11 -0
- data/spec/serf/middleware/error_handler_spec.rb +48 -0
- data/spec/serf/middleware/parcel_freezer_spec.rb +20 -0
- data/spec/serf/middleware/parcel_masher_spec.rb +30 -0
- data/spec/serf/middleware/policy_checker_spec.rb +70 -0
- data/spec/serf/middleware/uuid_tagger_spec.rb +32 -0
- data/spec/serf/parcel_builder_spec.rb +46 -0
- data/spec/serf/serfer_spec.rb +61 -0
- data/spec/serf/util/error_handling_spec.rb +35 -0
- data/spec/serf/util/null_object_spec.rb +26 -0
- data/spec/serf/util/options_extraction_spec.rb +62 -0
- data/spec/serf/util/protected_call_spec.rb +33 -0
- data/spec/serf/util/uuidable_spec.rb +56 -0
- data/spec/serf_spec.rb +1 -4
- data/spec/spec_helper.rb +3 -0
- data/spec/support/error_handling_wrapper.rb +5 -0
- data/spec/support/factories.rb +32 -0
- data/spec/support/failing_policy.rb +9 -0
- data/spec/support/json_schema_tester.rb +14 -0
- data/spec/support/options_extraction_wrapper.rb +10 -0
- data/spec/support/passing_policy.rb +7 -0
- data/spec/support/protected_call_wrapper.rb +5 -0
- metadata +81 -131
- data/.document +0 -5
- data/.rspec +0 -1
- data/Gemfile.lock +0 -58
- data/docs/thread_pools.txt +0 -16
- data/lib/serf/command.rb +0 -79
- data/lib/serf/error.rb +0 -11
- data/lib/serf/errors/not_found.rb +0 -8
- data/lib/serf/middleware/girl_friday_async.rb +0 -39
- data/lib/serf/middleware/masherize.rb +0 -25
- data/lib/serf/routing/regexp_matcher.rb +0 -35
- data/lib/serf/routing/route.rb +0 -35
- data/lib/serf/routing/route_set.rb +0 -64
- data/schemas/message_accepted_event.json +0 -14
data/lib/serf/util/uuidable.rb
CHANGED
@@ -2,6 +2,8 @@ require 'base64'
|
|
2
2
|
require 'hashie'
|
3
3
|
require 'uuidtools'
|
4
4
|
|
5
|
+
require 'serf/util/options_extraction'
|
6
|
+
|
5
7
|
module Serf
|
6
8
|
module Util
|
7
9
|
|
@@ -11,30 +13,14 @@ module Util
|
|
11
13
|
# 1. Primarily to create and parse 'coded' UUIDs, which are just
|
12
14
|
# base64 encoded UUIDs without trailing '='.
|
13
15
|
#
|
14
|
-
|
15
|
-
|
16
|
-
##
|
17
|
-
# @see self.create_coded_uuid
|
18
|
-
def create_coded_uuid
|
19
|
-
Uuidable.create_coded_uuid
|
20
|
-
end
|
21
|
-
|
22
|
-
##
|
23
|
-
# @see self.parse_coded_uuid
|
24
|
-
def parse_coded_uuid(coded_uuid)
|
25
|
-
Uuidable.parse_coded_uuid coded_uuid
|
26
|
-
end
|
16
|
+
class Uuidable
|
17
|
+
include Serf::Util::OptionsExtraction
|
27
18
|
|
28
|
-
|
29
|
-
# @see self.create_uuids
|
30
|
-
def create_uuids(parent={})
|
31
|
-
Uuidable.create_uuids parent
|
32
|
-
end
|
19
|
+
attr_reader :uuid_tool
|
33
20
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
Uuidable.annotate_with_uuids! message, parent
|
21
|
+
def initialize(*args)
|
22
|
+
extract_options! args
|
23
|
+
@uuid_tool = opts :uuid_tool, UUIDTools::UUID
|
38
24
|
end
|
39
25
|
|
40
26
|
##
|
@@ -42,27 +28,28 @@ module Util
|
|
42
28
|
#
|
43
29
|
# NOTE: UUIDTools TimeStamp code creates a UTC based timestamp UUID.
|
44
30
|
#
|
45
|
-
def
|
31
|
+
def create_coded_uuid
|
46
32
|
# All raw UUIDs are 16 bytes long. Base64 lengthens the string to
|
47
33
|
# 24 bytes long. We chomp off the last two equal signs '==' to
|
48
34
|
# trim the string length to 22 bytes. This gives us an overhead
|
49
35
|
# of an extra 6 bytes over raw UUID, but with the readability
|
50
36
|
# benefit. And saves us 14 bytes of size from the 'standard'
|
51
37
|
# string hex representation of UUIDs.
|
52
|
-
Base64.urlsafe_encode64(
|
38
|
+
Base64.urlsafe_encode64(uuid_tool.timestamp_create.raw).chomp('==')
|
53
39
|
end
|
54
40
|
|
55
41
|
##
|
56
42
|
# @param coded_uuid a coded uuid to parse.
|
57
43
|
#
|
58
|
-
def
|
59
|
-
|
44
|
+
def parse_coded_uuid(coded_uuid)
|
45
|
+
uuid_tool.parse_raw Base64.urlsafe_decode64("#{coded_uuid}==")
|
60
46
|
end
|
61
47
|
|
62
48
|
##
|
63
49
|
# Create a new set of uuids.
|
64
50
|
#
|
65
|
-
def
|
51
|
+
def create_uuids(parent=nil)
|
52
|
+
parent ||= {}
|
66
53
|
Hashie::Mash.new(
|
67
54
|
uuid: create_coded_uuid,
|
68
55
|
parent_uuid: parent[:uuid],
|
@@ -72,17 +59,6 @@ module Util
|
|
72
59
|
parent[:uuid]))
|
73
60
|
end
|
74
61
|
|
75
|
-
##
|
76
|
-
# Set a message's UUIDs with new UUIDs based on the parent's UUIDs.
|
77
|
-
#
|
78
|
-
def self.annotate_with_uuids!(message, parent={})
|
79
|
-
uuids = self.create_uuids parent
|
80
|
-
message[:uuid] ||= uuids[:uuid]
|
81
|
-
message[:parent_uuid] ||= uuids[:parent_uuid]
|
82
|
-
message[:origin_uuid] ||= uuids[:origin_uuid]
|
83
|
-
return nil
|
84
|
-
end
|
85
|
-
|
86
62
|
end
|
87
63
|
|
88
64
|
end
|
data/lib/serf/version.rb
CHANGED
@@ -1,20 +1,17 @@
|
|
1
1
|
{
|
2
|
-
"description": "
|
2
|
+
"description": "serf/events/caught_error",
|
3
3
|
"type": "object",
|
4
4
|
"properties": {
|
5
|
-
"context": {
|
6
|
-
"type": "object"
|
7
|
-
},
|
8
5
|
"error": {
|
9
6
|
"type": "string"
|
10
7
|
},
|
11
8
|
"message": {
|
12
9
|
"type": "string"
|
13
10
|
},
|
14
|
-
"
|
15
|
-
"type": "
|
11
|
+
"process_env": {
|
12
|
+
"type": "object"
|
16
13
|
},
|
17
|
-
"
|
14
|
+
"backtrace": {
|
18
15
|
"type": "string"
|
19
16
|
}
|
20
17
|
}
|
data/serf.gemspec
CHANGED
@@ -1,107 +1,28 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/serf/version', __FILE__)
|
5
3
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'serf'
|
6
|
+
gem.version = Serf::Version::STRING
|
7
|
+
gem.authors = ['Benjamin Yu']
|
8
|
+
gem.email = 'benjaminlyu@gmail.com'
|
9
|
+
gem.description = 'Interactors with policy protection'
|
10
|
+
gem.summary = 'Interactors with policy protection'
|
11
|
+
gem.homepage = 'http://github.com/byu/serf'
|
12
|
+
gem.licenses = ['Apache 2.0']
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
gem.rubygems_version = '1.8.17'
|
15
|
+
gem.files = `git ls-files`.split($\)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
gem.extra_rdoc_files = [
|
20
|
+
'LICENSE.txt',
|
21
|
+
'NOTICE.txt',
|
22
|
+
'README.md'
|
18
23
|
]
|
19
|
-
s.files = [
|
20
|
-
".document",
|
21
|
-
".rspec",
|
22
|
-
"Gemfile",
|
23
|
-
"Gemfile.lock",
|
24
|
-
"LICENSE.txt",
|
25
|
-
"NOTICE.txt",
|
26
|
-
"README.md",
|
27
|
-
"Rakefile",
|
28
|
-
"docs/thread_pools.txt",
|
29
|
-
"lib/serf.rb",
|
30
|
-
"lib/serf/builder.rb",
|
31
|
-
"lib/serf/command.rb",
|
32
|
-
"lib/serf/error.rb",
|
33
|
-
"lib/serf/errors/not_found.rb",
|
34
|
-
"lib/serf/middleware/girl_friday_async.rb",
|
35
|
-
"lib/serf/middleware/masherize.rb",
|
36
|
-
"lib/serf/middleware/uuid_tagger.rb",
|
37
|
-
"lib/serf/routing/regexp_matcher.rb",
|
38
|
-
"lib/serf/routing/route.rb",
|
39
|
-
"lib/serf/routing/route_set.rb",
|
40
|
-
"lib/serf/serfer.rb",
|
41
|
-
"lib/serf/util/error_handling.rb",
|
42
|
-
"lib/serf/util/null_object.rb",
|
43
|
-
"lib/serf/util/options_extraction.rb",
|
44
|
-
"lib/serf/util/protected_call.rb",
|
45
|
-
"lib/serf/util/uuidable.rb",
|
46
|
-
"lib/serf/version.rb",
|
47
|
-
"schemas/caught_exception_event.json",
|
48
|
-
"schemas/message_accepted_event.json",
|
49
|
-
"serf.gemspec",
|
50
|
-
"spec/serf_spec.rb",
|
51
|
-
"spec/spec_helper.rb"
|
52
|
-
]
|
53
|
-
s.homepage = "http://github.com/byu/serf"
|
54
|
-
s.licenses = ["Apache 2.0"]
|
55
|
-
s.require_paths = ["lib"]
|
56
|
-
s.rubygems_version = "1.8.17"
|
57
|
-
s.summary = "Event-Driven SOA with CQRS"
|
58
|
-
|
59
|
-
if s.respond_to? :specification_version then
|
60
|
-
s.specification_version = 3
|
61
24
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
s.add_runtime_dependency(%q<hashie>, [">= 1.2.0"])
|
66
|
-
s.add_runtime_dependency(%q<uuidtools>, [">= 2.1.2"])
|
67
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
68
|
-
s.add_development_dependency(%q<yard>, ["~> 0.7.5"])
|
69
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.1.3"])
|
70
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
|
71
|
-
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
72
|
-
s.add_development_dependency(%q<log4r>, [">= 1.1.10"])
|
73
|
-
s.add_development_dependency(%q<msgpack>, [">= 0.4.6"])
|
74
|
-
s.add_development_dependency(%q<eventmachine>, [">= 0.12.10"])
|
75
|
-
s.add_development_dependency(%q<girl_friday>, [">= 0.9.7"])
|
76
|
-
else
|
77
|
-
s.add_dependency(%q<activesupport>, [">= 3.2.0"])
|
78
|
-
s.add_dependency(%q<i18n>, [">= 0.6.0"])
|
79
|
-
s.add_dependency(%q<hashie>, [">= 1.2.0"])
|
80
|
-
s.add_dependency(%q<uuidtools>, [">= 2.1.2"])
|
81
|
-
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
82
|
-
s.add_dependency(%q<yard>, ["~> 0.7.5"])
|
83
|
-
s.add_dependency(%q<bundler>, ["~> 1.1.3"])
|
84
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
85
|
-
s.add_dependency(%q<simplecov>, [">= 0"])
|
86
|
-
s.add_dependency(%q<log4r>, [">= 1.1.10"])
|
87
|
-
s.add_dependency(%q<msgpack>, [">= 0.4.6"])
|
88
|
-
s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
|
89
|
-
s.add_dependency(%q<girl_friday>, [">= 0.9.7"])
|
90
|
-
end
|
91
|
-
else
|
92
|
-
s.add_dependency(%q<activesupport>, [">= 3.2.0"])
|
93
|
-
s.add_dependency(%q<i18n>, [">= 0.6.0"])
|
94
|
-
s.add_dependency(%q<hashie>, [">= 1.2.0"])
|
95
|
-
s.add_dependency(%q<uuidtools>, [">= 2.1.2"])
|
96
|
-
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
97
|
-
s.add_dependency(%q<yard>, ["~> 0.7.5"])
|
98
|
-
s.add_dependency(%q<bundler>, ["~> 1.1.3"])
|
99
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
100
|
-
s.add_dependency(%q<simplecov>, [">= 0"])
|
101
|
-
s.add_dependency(%q<log4r>, [">= 1.1.10"])
|
102
|
-
s.add_dependency(%q<msgpack>, [">= 0.4.6"])
|
103
|
-
s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
|
104
|
-
s.add_dependency(%q<girl_friday>, [">= 0.9.7"])
|
105
|
-
end
|
25
|
+
gem.add_runtime_dependency('hashie', ['>= 1.2.0'])
|
26
|
+
gem.add_runtime_dependency('ice_nine', ['>= 0.4.0'])
|
27
|
+
gem.add_runtime_dependency('uuidtools', ['>= 2.1.3'])
|
106
28
|
end
|
107
|
-
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'serf/builder'
|
4
|
+
|
5
|
+
describe Serf::Builder do
|
6
|
+
let(:request_parcel) {
|
7
|
+
FactoryGirl.create :random_parcel
|
8
|
+
}
|
9
|
+
let(:response_kind) {
|
10
|
+
'MyResponseKindMessage'
|
11
|
+
}
|
12
|
+
let(:app) {
|
13
|
+
lambda { |parcel|
|
14
|
+
return parcel, response_kind
|
15
|
+
}
|
16
|
+
}
|
17
|
+
subject {
|
18
|
+
described_class.new interactor: app
|
19
|
+
}
|
20
|
+
|
21
|
+
describe '#to_app' do
|
22
|
+
|
23
|
+
it 'builds a callable app' do
|
24
|
+
subject.to_app.should respond_to(:call)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with build app' do
|
30
|
+
|
31
|
+
describe '#call' do
|
32
|
+
|
33
|
+
it 'runs the app' do
|
34
|
+
response = subject.to_app.call request_parcel
|
35
|
+
puts response.to_hash
|
36
|
+
response.message.should == request_parcel.message
|
37
|
+
response.headers.kind.should == response_kind
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'serf/middleware/error_handler'
|
4
|
+
|
5
|
+
describe Serf::Middleware::ErrorHandler do
|
6
|
+
|
7
|
+
describe '#call' do
|
8
|
+
|
9
|
+
context 'has a raised error' do
|
10
|
+
subject {
|
11
|
+
described_class.new(proc { |parcel|
|
12
|
+
raise 'Some Runtime Error'
|
13
|
+
})
|
14
|
+
}
|
15
|
+
|
16
|
+
it 'returns an error parcel' do
|
17
|
+
parcel = subject.call({})
|
18
|
+
JsonSchemaTester.new.validate_for!(
|
19
|
+
'serf/events/caught_error',
|
20
|
+
parcel[:message])
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'has an error parcel kind' do
|
24
|
+
parcel = subject.call({})
|
25
|
+
parcel[:headers][:kind].should == 'serf/events/caught_error'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'has a succeeding app' do
|
30
|
+
subject {
|
31
|
+
described_class.new(proc { |parcel|
|
32
|
+
response_parcel
|
33
|
+
})
|
34
|
+
}
|
35
|
+
let(:response_parcel) {
|
36
|
+
FactoryGirl.create :random_parcel
|
37
|
+
}
|
38
|
+
|
39
|
+
it 'returns a good response parcel' do
|
40
|
+
parcel = subject.call({})
|
41
|
+
parcel.should == response_parcel
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'serf/middleware/parcel_freezer'
|
4
|
+
|
5
|
+
describe Serf::Middleware::ParcelFreezer do
|
6
|
+
|
7
|
+
describe '#call' do
|
8
|
+
|
9
|
+
it 'freezes the parcel' do
|
10
|
+
parcel = {}
|
11
|
+
app = described_class.new proc { |parcel|
|
12
|
+
parcel.frozen?.should be_true
|
13
|
+
}
|
14
|
+
app.call parcel
|
15
|
+
parcel.frozen?.should be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'hashie'
|
4
|
+
|
5
|
+
require 'serf/middleware/parcel_masher'
|
6
|
+
|
7
|
+
describe Serf::Middleware::ParcelMasher do
|
8
|
+
|
9
|
+
describe '#call' do
|
10
|
+
|
11
|
+
it 'should Hashie::Mash the parcel' do
|
12
|
+
parcel = nil
|
13
|
+
app = described_class.new proc { |parcel|
|
14
|
+
parcel.should be_a_kind_of(Hashie::Mash)
|
15
|
+
}
|
16
|
+
app.call parcel
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should autocreate headers and message' do
|
20
|
+
parcel = nil
|
21
|
+
app = described_class.new proc { |parcel|
|
22
|
+
parcel.headers.should be_a_kind_of(Hashie::Mash)
|
23
|
+
parcel.message.should be_a_kind_of(Hashie::Mash)
|
24
|
+
}
|
25
|
+
app.call parcel
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'serf/errors/policy_failure'
|
4
|
+
require 'serf/middleware/policy_checker'
|
5
|
+
|
6
|
+
describe Serf::Middleware::PolicyChecker do
|
7
|
+
|
8
|
+
describe '#call' do
|
9
|
+
|
10
|
+
context 'when policy raises error' do
|
11
|
+
|
12
|
+
it 'should not call app' do
|
13
|
+
uncalled_mock = double 'uncalled mock'
|
14
|
+
app = described_class.new(
|
15
|
+
uncalled_mock,
|
16
|
+
policy_chain: [
|
17
|
+
PassingPolicy.new,
|
18
|
+
FailingPolicy.new,
|
19
|
+
PassingPolicy.new
|
20
|
+
])
|
21
|
+
expect {
|
22
|
+
app.call nil
|
23
|
+
}.to raise_error(Serf::Errors::PolicyFailure)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when all policies pass' do
|
29
|
+
|
30
|
+
it 'should call the app' do
|
31
|
+
parcel = double 'parcel'
|
32
|
+
parcel.should_receive :some_success
|
33
|
+
app = described_class.new(
|
34
|
+
proc { |parcel|
|
35
|
+
parcel.some_success
|
36
|
+
},
|
37
|
+
policy_chain: [
|
38
|
+
PassingPolicy.new,
|
39
|
+
PassingPolicy.new
|
40
|
+
])
|
41
|
+
app.call parcel
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should iterate the policy chain' do
|
47
|
+
count = 10
|
48
|
+
policy_chain = (1..count).map { |i|
|
49
|
+
policy = double 'policy'
|
50
|
+
policy.should_receive(:check!).once do |parcel|
|
51
|
+
parcel.check_called
|
52
|
+
end
|
53
|
+
policy
|
54
|
+
}
|
55
|
+
|
56
|
+
parcel = double 'parcel'
|
57
|
+
parcel.should_receive(:check_called).exactly(count).times
|
58
|
+
parcel.should_receive :some_success
|
59
|
+
|
60
|
+
app = described_class.new(
|
61
|
+
proc { |parcel|
|
62
|
+
parcel.some_success
|
63
|
+
},
|
64
|
+
policy_chain: policy_chain)
|
65
|
+
app.call parcel
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'serf/middleware/uuid_tagger'
|
4
|
+
|
5
|
+
describe Serf::Middleware::UuidTagger do
|
6
|
+
|
7
|
+
describe '#call' do
|
8
|
+
|
9
|
+
it 'should add uuid the parcel header' do
|
10
|
+
parcel = {}
|
11
|
+
app = described_class.new proc { |parcel|
|
12
|
+
parcel[:headers][:uuid].should_not be_nil
|
13
|
+
}
|
14
|
+
app.call parcel
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should not change the existing uuid' do
|
18
|
+
uuid = '0d3eccaabcc46c3bcbe2a53c4505e352'
|
19
|
+
parcel = {
|
20
|
+
headers: {
|
21
|
+
uuid: uuid
|
22
|
+
}
|
23
|
+
}
|
24
|
+
app = described_class.new proc { |parcel|
|
25
|
+
parcel[:headers][:uuid].should == uuid
|
26
|
+
}
|
27
|
+
app.call parcel
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'hashie'
|
4
|
+
|
5
|
+
require 'serf/parcel_builder'
|
6
|
+
|
7
|
+
describe Serf::ParcelBuilder do
|
8
|
+
|
9
|
+
describe '#build' do
|
10
|
+
let(:random_headers) {
|
11
|
+
FactoryGirl.create :random_headers
|
12
|
+
}
|
13
|
+
let(:random_message) {
|
14
|
+
FactoryGirl.create :random_message
|
15
|
+
}
|
16
|
+
|
17
|
+
it 'returns a Hashie' do
|
18
|
+
parcel = subject.build
|
19
|
+
parcel.should be_a_kind_of(Hashie::Mash)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'sets default parcel headers' do
|
23
|
+
parcel = subject.build
|
24
|
+
parcel[:headers].should == {}
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'sets default parcel message' do
|
28
|
+
parcel = subject.build
|
29
|
+
parcel[:headers].should == {}
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'sets given headers and message' do
|
33
|
+
parcel = subject.build random_headers, random_message
|
34
|
+
parcel[:headers].should == random_headers
|
35
|
+
parcel[:message].should == random_message
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'will coerce headers and message into Hashie::Mash' do
|
39
|
+
parcel = subject.build nil, nil
|
40
|
+
parcel[:headers].should be_a_kind_of(Hashie::Mash)
|
41
|
+
parcel[:message].should be_a_kind_of(Hashie::Mash)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'serf/serfer'
|
4
|
+
|
5
|
+
describe Serf::Serfer do
|
6
|
+
|
7
|
+
describe '#call' do
|
8
|
+
let(:request_message) {
|
9
|
+
FactoryGirl.create :random_message
|
10
|
+
}
|
11
|
+
let(:response_message) {
|
12
|
+
FactoryGirl.create :random_message
|
13
|
+
}
|
14
|
+
|
15
|
+
it 'calls app with message' do
|
16
|
+
mock_app = double 'mock_app'
|
17
|
+
mock_app.should_receive(:call).with(request_message)
|
18
|
+
serfer = described_class.new mock_app
|
19
|
+
serfer.call(
|
20
|
+
headers: nil,
|
21
|
+
message: request_message)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'returns a parcel' do
|
25
|
+
mock_app = double 'mock_app'
|
26
|
+
mock_app.
|
27
|
+
should_receive(:call).
|
28
|
+
with(request_message).
|
29
|
+
and_return(response_message)
|
30
|
+
serfer = described_class.new mock_app
|
31
|
+
parcel = serfer.call(
|
32
|
+
headers: nil,
|
33
|
+
message: request_message)
|
34
|
+
parcel.message.should == response_message
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'sets the kind header in response' do
|
38
|
+
mock_app = double 'mock_app'
|
39
|
+
mock_app.
|
40
|
+
should_receive(:call).
|
41
|
+
with(request_message).
|
42
|
+
and_return([response_message, 'KIND'])
|
43
|
+
serfer = described_class.new mock_app
|
44
|
+
parcel = serfer.call(
|
45
|
+
headers: nil,
|
46
|
+
message: request_message)
|
47
|
+
parcel.headers.kind.should == 'KIND'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'generate uuids' do
|
51
|
+
uuidable = double 'uuidable'
|
52
|
+
uuidable.should_receive(:create_uuids).and_return({})
|
53
|
+
serfer = described_class.new(
|
54
|
+
lambda {|obj| return obj },
|
55
|
+
uuidable: uuidable)
|
56
|
+
serfer.call({})
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Serf::Util::ErrorHandling do
|
4
|
+
subject { ErrorHandlingWrapper.new }
|
5
|
+
|
6
|
+
context 'has a raised error' do
|
7
|
+
|
8
|
+
it 'returns an error message' do
|
9
|
+
result, error = subject.with_error_handling do
|
10
|
+
raise 'Some Error Message'
|
11
|
+
end
|
12
|
+
result.should be_nil
|
13
|
+
JsonSchemaTester.new.validate_for!(
|
14
|
+
'serf/events/caught_error',
|
15
|
+
error)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'has a succeeding app' do
|
21
|
+
let(:response_parcel) {
|
22
|
+
FactoryGirl.create :random_parcel
|
23
|
+
}
|
24
|
+
|
25
|
+
it 'returns a good response parcel' do
|
26
|
+
result, error = subject.with_error_handling do
|
27
|
+
response_parcel
|
28
|
+
end
|
29
|
+
result.should == response_parcel
|
30
|
+
error.should be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|