serf 0.14.0 → 0.15.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 +14 -6
- data/.travis.yml +4 -2
- data/README.md +21 -4
- data/lib/serf/builder.rb +24 -5
- data/lib/serf/errors/load_failure.rb +17 -0
- data/lib/serf/loader/loader.rb +13 -4
- data/lib/serf/loader/registry.rb +14 -4
- data/lib/serf/serfer.rb +17 -4
- data/lib/serf/util/error_handling.rb +3 -0
- data/lib/serf/util/uuidable.rb +12 -0
- data/lib/serf/version.rb +1 -9
- data/schemas/serf/events/caught_error.json +17 -4
- data/serf.gemspec +4 -2
- data/spec/data/construction_error.serf +3 -0
- data/spec/data/raises_error.serf +1 -0
- data/spec/serf/loader/loader_spec.rb +43 -1
- data/spec/serf/loader/registry_spec.rb +15 -0
- data/spec/serf/loader_spec.rb +2 -1
- data/spec/serf/serfer_spec.rb +98 -2
- data/spec/serf/util/error_handling_spec.rb +6 -1
- data/spec/serf/util/uuidable_spec.rb +20 -0
- metadata +9 -4
data/.gitignore
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
-
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
2
6
|
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
3
9
|
coverage
|
4
|
-
|
5
|
-
|
6
|
-
.yardoc
|
7
|
-
.bundle
|
8
|
-
vendor
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
9
12
|
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
10
17
|
tmp
|
18
|
+
vendor
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -31,13 +31,20 @@ the Domain Layer's Model (Entities, Value Objects and Entity Gateways).
|
|
31
31
|
|
32
32
|
1. Include the "Serf::Interactor" module in your class.
|
33
33
|
2. Implement the 'call(parcel)' method.
|
34
|
-
3. Return the tuple: (kind, message)
|
34
|
+
3. Return the tuple: (kind, message, headers)
|
35
35
|
a. The kind is the string representation of the message type,
|
36
36
|
This field is RECOMMENDED.
|
37
37
|
b. The message field provides detailed return data about the
|
38
|
-
interactor's processing.
|
38
|
+
interactor's processing. The main meat of the Domain Object.
|
39
39
|
Hashie::Mash is suggested for the message, nil is acceptable.
|
40
|
-
c.
|
40
|
+
c. The headers are OPTIONAL. The headers are there primarily to return
|
41
|
+
out of band data about the processing of the request. For example,
|
42
|
+
the Interactor can return debug tags about connections to external
|
43
|
+
databases.
|
44
|
+
The *ONE* semantic relevant piece of information is that the
|
45
|
+
Interactor may specify the version the domain object, as represented
|
46
|
+
by the message of type 'kind', in the 'version' header field.
|
47
|
+
d. By default, returning nil for both kind and message will still
|
41
48
|
result in a response parcel signifying that some Interactor received
|
42
49
|
the inbound parcel. But that is just a almost worthless piece of
|
43
50
|
information for the observer.
|
@@ -106,6 +113,7 @@ For example,
|
|
106
113
|
Serf *RESERVES* the following set of header names:
|
107
114
|
|
108
115
|
* kind
|
116
|
+
* version
|
109
117
|
* message
|
110
118
|
* uuid
|
111
119
|
* parent_uuid
|
@@ -134,6 +142,13 @@ may be used to route messages over messaging channels to Interactors.
|
|
134
142
|
The convention is 'mymodule/requests/my_business_request' for Requests,
|
135
143
|
and 'mymodule/events/my_business_event' for Events.
|
136
144
|
|
145
|
+
*version* field MAY be used to identify the semantic version of the
|
146
|
+
message of the given 'kind'. The triplet of (kind, version, message)
|
147
|
+
constitutes the prime parts of domain object as represented by the
|
148
|
+
parcel. All other header fields are incidental data that pertain to
|
149
|
+
the processing. This field is optional, and is returned in the
|
150
|
+
headers portion of the interactor's return results.
|
151
|
+
|
137
152
|
*UUIDs* are used to track request and events, providing a sequential
|
138
153
|
order of execution of commands. Already Implemented by Serf middleware.
|
139
154
|
|
@@ -320,7 +335,9 @@ Serf Builder Example
|
|
320
335
|
raise 'Error' if parcel.message.raise_an_error
|
321
336
|
|
322
337
|
# And return a message as result. Nil is valid response.
|
323
|
-
return 'my_lib/events/success_event',
|
338
|
+
return 'my_lib/events/success_event',
|
339
|
+
{ success: true },
|
340
|
+
{ version: "1.2.3" }
|
324
341
|
|
325
342
|
# Optionally just return the kind
|
326
343
|
# return 'my_lib/events/success_event'
|
data/lib/serf/builder.rb
CHANGED
@@ -28,19 +28,38 @@ module Serf
|
|
28
28
|
##
|
29
29
|
# Set a default chain of the following:
|
30
30
|
#
|
31
|
+
# use_default_middleware
|
32
|
+
# use_default_serfer_stage
|
33
|
+
#
|
34
|
+
def use_defaults
|
35
|
+
use_default_middleware
|
36
|
+
use_default_serfer_stage
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Add the following middleware to the chain:
|
41
|
+
#
|
42
|
+
# use Serf::Middleware::RequestTimer
|
31
43
|
# use Serf::Middleware::ParcelMasher
|
32
44
|
# use Serf::Middleware::UuidTagger
|
33
|
-
# use Serf::Middleware::ParcelFreezer
|
34
45
|
# use Serf::Middleware::ErrorHandler
|
35
|
-
# use Serf::Middleware::PolicyChecker, @policy_chain
|
36
|
-
# use Serf::Serfer
|
37
46
|
#
|
38
|
-
def
|
47
|
+
def use_default_middleware
|
39
48
|
use Serf::Middleware::RequestTimer
|
40
49
|
use Serf::Middleware::ParcelMasher
|
41
50
|
use Serf::Middleware::UuidTagger
|
42
|
-
use Serf::Middleware::ParcelFreezer
|
43
51
|
use Serf::Middleware::ErrorHandler
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Add the following middleware to the chain:
|
56
|
+
#
|
57
|
+
# use Serf::Middleware::ParcelFreezer
|
58
|
+
# use Serf::Middleware::PolicyChecker, @policy_chain
|
59
|
+
# use Serf::Serfer
|
60
|
+
#
|
61
|
+
def use_default_serfer_stage
|
62
|
+
use Serf::Middleware::ParcelFreezer
|
44
63
|
use Serf::Middleware::PolicyChecker, policy_chain: @policy_chain
|
45
64
|
use Serf::Serfer
|
46
65
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Serf
|
2
|
+
module Errors
|
3
|
+
|
4
|
+
##
|
5
|
+
# An error occurred while loading serfs.
|
6
|
+
#
|
7
|
+
class LoadFailure < RuntimeError
|
8
|
+
attr_accessor :cause
|
9
|
+
|
10
|
+
def initialize(message=nil, cause=nil)
|
11
|
+
@cause = cause
|
12
|
+
super(message)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/serf/loader/loader.rb
CHANGED
@@ -2,6 +2,7 @@ require 'hashie'
|
|
2
2
|
require 'optser'
|
3
3
|
|
4
4
|
require 'serf/builder'
|
5
|
+
require 'serf/errors/load_failure'
|
5
6
|
require 'serf/loader/registry'
|
6
7
|
|
7
8
|
module Serf
|
@@ -63,9 +64,13 @@ module Loader
|
|
63
64
|
globs.each do |glob_pattern|
|
64
65
|
globs = Dir.glob File.join(base_path, glob_pattern)
|
65
66
|
globs.each do |filename|
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
begin
|
68
|
+
File.open filename do |file|
|
69
|
+
contents = file.read
|
70
|
+
instance_eval(contents)
|
71
|
+
end
|
72
|
+
rescue => e
|
73
|
+
raise Serf::Errors::LoadFailure.new "File: #{filename}", e
|
69
74
|
end
|
70
75
|
end
|
71
76
|
end
|
@@ -73,7 +78,11 @@ module Loader
|
|
73
78
|
# Construct all the "serfs"
|
74
79
|
map = Hashie::Mash.new
|
75
80
|
serfs.each do |serf|
|
76
|
-
|
81
|
+
begin
|
82
|
+
map[serf] = @registry[serf]
|
83
|
+
rescue => e
|
84
|
+
raise Serf::Errors::LoadFailure.new "Kind: #{serf}", e
|
85
|
+
end
|
77
86
|
raise "Missing Serf: #{serf}" if map[serf].nil?
|
78
87
|
end
|
79
88
|
|
data/lib/serf/loader/registry.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'hashie'
|
2
2
|
require 'optser'
|
3
3
|
|
4
|
+
require 'serf/errors/load_failure'
|
5
|
+
|
4
6
|
module Serf
|
5
7
|
module Loader
|
6
8
|
|
@@ -47,6 +49,7 @@ module Loader
|
|
47
49
|
class Registry
|
48
50
|
attr_reader :blocks
|
49
51
|
attr_reader :values
|
52
|
+
attr_reader :env
|
50
53
|
|
51
54
|
def initialize(*args)
|
52
55
|
opts = Optser.extract_options! args
|
@@ -62,7 +65,7 @@ module Loader
|
|
62
65
|
# @params &block the proc that generates the component instance.
|
63
66
|
#
|
64
67
|
def add(name, &block)
|
65
|
-
|
68
|
+
blocks[name.to_sym] = block
|
66
69
|
end
|
67
70
|
|
68
71
|
##
|
@@ -73,11 +76,18 @@ module Loader
|
|
73
76
|
#
|
74
77
|
def [](name)
|
75
78
|
name = name.to_sym
|
76
|
-
return
|
79
|
+
return values[name] if values.has_key? name
|
77
80
|
# No memoized value, so grab the block, call it and memoize it
|
78
81
|
# return the block's return value, or nil.
|
79
|
-
if block =
|
80
|
-
|
82
|
+
if block = blocks[name]
|
83
|
+
begin
|
84
|
+
value = block.call self, env
|
85
|
+
values[name] = value
|
86
|
+
blocks.delete name
|
87
|
+
return value
|
88
|
+
rescue => e
|
89
|
+
raise Serf::Errors::LoadFailure.new("Name: #{name}", e)
|
90
|
+
end
|
81
91
|
end
|
82
92
|
end
|
83
93
|
|
data/lib/serf/serfer.rb
CHANGED
@@ -26,16 +26,29 @@ module Serf
|
|
26
26
|
#
|
27
27
|
def call(parcel)
|
28
28
|
# 1. Execute interactor
|
29
|
-
response_kind, response_message = interactor.call parcel
|
30
|
-
|
31
|
-
# 2.
|
29
|
+
response_kind, response_message, response_headers = interactor.call parcel
|
30
|
+
|
31
|
+
# 2. Extract a possible version embedded in the response_kind.
|
32
|
+
# This is sugar syntax for kind and version.
|
33
|
+
if response_kind
|
34
|
+
kind_part, version_part = response_kind.split '#', 2
|
35
|
+
response_kind = kind_part if version_part
|
36
|
+
if version_part
|
37
|
+
response_headers ||= {}
|
38
|
+
response_headers[:version] = version_part
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# 3. Return a new response parcel with:
|
32
43
|
# a. uuids set from parent parcel
|
33
44
|
# b. kind set to response kind
|
34
45
|
# c. the message set to response_message
|
46
|
+
# d. add extra headers to the parcel
|
35
47
|
return parcel_factory.create(
|
36
48
|
parent: parcel,
|
37
49
|
kind: response_kind,
|
38
|
-
message: response_message
|
50
|
+
message: response_message,
|
51
|
+
headers: response_headers)
|
39
52
|
end
|
40
53
|
|
41
54
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
1
3
|
require 'serf/util/protected_call'
|
2
4
|
|
3
5
|
module Serf
|
@@ -31,6 +33,7 @@ module Util
|
|
31
33
|
error: e.class.to_s,
|
32
34
|
message: e.message,
|
33
35
|
process_env: ENV.to_hash,
|
36
|
+
hostname: Socket.gethostname,
|
34
37
|
backtrace: e.backtrace.join("\n")
|
35
38
|
}
|
36
39
|
end
|
data/lib/serf/util/uuidable.rb
CHANGED
@@ -42,6 +42,18 @@ module Util
|
|
42
42
|
uuid_tool.parse_raw Base64.urlsafe_decode64("#{coded_uuid}==")
|
43
43
|
end
|
44
44
|
|
45
|
+
##
|
46
|
+
# Parses a coded_uuid and returns a time object for the Timestamped UUID.
|
47
|
+
#
|
48
|
+
# @param coded_uuid the coded uuid from which to get a time.
|
49
|
+
#
|
50
|
+
# @return ruby time object for which the coded_uuid was timestamped.
|
51
|
+
#
|
52
|
+
def coded_uuid_time(coded_uuid)
|
53
|
+
uuid = parse_coded_uuid coded_uuid
|
54
|
+
uuid.timestamp.utc
|
55
|
+
end
|
56
|
+
|
45
57
|
##
|
46
58
|
# Create a new set of uuids.
|
47
59
|
#
|
data/lib/serf/version.rb
CHANGED
@@ -3,16 +3,29 @@
|
|
3
3
|
"type": "object",
|
4
4
|
"properties": {
|
5
5
|
"error": {
|
6
|
-
"
|
6
|
+
"description": "The error class",
|
7
|
+
"type": "string",
|
8
|
+
"required": true
|
7
9
|
},
|
8
10
|
"message": {
|
9
|
-
"
|
11
|
+
"description": "The description of the error",
|
12
|
+
"type": "string",
|
13
|
+
"required": true
|
10
14
|
},
|
11
15
|
"process_env": {
|
12
|
-
"
|
16
|
+
"description": "The ENV context of the error",
|
17
|
+
"type": "object",
|
18
|
+
"required": true
|
19
|
+
},
|
20
|
+
"hostname": {
|
21
|
+
"description": "The hostname of the process of the error",
|
22
|
+
"type": "string",
|
23
|
+
"required": true
|
13
24
|
},
|
14
25
|
"backtrace": {
|
15
|
-
"
|
26
|
+
"description": "The backtrace of the error",
|
27
|
+
"type": "string",
|
28
|
+
"required": true
|
16
29
|
}
|
17
30
|
}
|
18
31
|
}
|
data/serf.gemspec
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'serf/version'
|
3
5
|
|
4
6
|
Gem::Specification.new do |gem|
|
5
7
|
gem.name = 'serf'
|
6
|
-
gem.version = Serf::
|
8
|
+
gem.version = Serf::VERSION
|
7
9
|
gem.authors = ['Benjamin Yu']
|
8
10
|
gem.email = 'benjaminlyu@gmail.com'
|
9
11
|
gem.description = 'Interactors with policy protection'
|
@@ -0,0 +1 @@
|
|
1
|
+
raise 'Intentional Error'
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
require 'serf/errors/load_failure'
|
3
4
|
require 'serf/loader/loader'
|
4
5
|
|
5
6
|
describe Serf::Loader::Loader do
|
@@ -14,7 +15,8 @@ describe Serf::Loader::Loader do
|
|
14
15
|
subject {
|
15
16
|
Serf::Loader::Loader.new.serfup(
|
16
17
|
globs: [
|
17
|
-
'example/**/*.serf'
|
18
|
+
'example/components/**/*.serf',
|
19
|
+
'example/serfs/**/*.serf'
|
18
20
|
],
|
19
21
|
serfs: [
|
20
22
|
'subsystem/requests/create_widget'
|
@@ -70,4 +72,44 @@ describe Serf::Loader::Loader do
|
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
75
|
+
context '#serfup with construction error' do
|
76
|
+
let(:serfup_config) {
|
77
|
+
Hashie::Mash.new(
|
78
|
+
globs: [
|
79
|
+
'spec/data/construction_error.serf'
|
80
|
+
],
|
81
|
+
serfs: [
|
82
|
+
'spec/data/bad_construction'
|
83
|
+
])
|
84
|
+
}
|
85
|
+
|
86
|
+
it 'raises an error' do
|
87
|
+
expect {
|
88
|
+
Serf::Loader::Loader.new.serfup serfup_config
|
89
|
+
}.to raise_error { |error|
|
90
|
+
expect(error).to be_a(Serf::Errors::LoadFailure)
|
91
|
+
expect(error.message).to match(/Kind: .+$/)
|
92
|
+
}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context '#serfup Serf Map bad serf file' do
|
97
|
+
let(:serfup_config) {
|
98
|
+
Hashie::Mash.new(
|
99
|
+
globs: [
|
100
|
+
'spec/data/raises_error.serf'
|
101
|
+
],
|
102
|
+
serfs: [])
|
103
|
+
}
|
104
|
+
|
105
|
+
it 'raises an error' do
|
106
|
+
expect {
|
107
|
+
Serf::Loader::Loader.new.serfup serfup_config
|
108
|
+
}.to raise_error { |error|
|
109
|
+
expect(error).to be_a(Serf::Errors::LoadFailure)
|
110
|
+
expect(error.message).to match(/^File: .+$/)
|
111
|
+
}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
73
115
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
require 'serf/errors/load_failure'
|
3
4
|
require 'serf/loader/registry'
|
4
5
|
|
5
6
|
describe Serf::Loader::Registry do
|
@@ -59,4 +60,18 @@ describe Serf::Loader::Registry do
|
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
63
|
+
context '#[] with error' do
|
64
|
+
it 'raises LoadFailure on error' do
|
65
|
+
subject.add 'component_name' do
|
66
|
+
raise 'Intentional Error'
|
67
|
+
end
|
68
|
+
expect {
|
69
|
+
subject['component_name']
|
70
|
+
}.to raise_error { |error|
|
71
|
+
expect(error).to be_a(Serf::Errors::LoadFailure)
|
72
|
+
expect(error.message).to match(/^Name: .+$/)
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
62
77
|
end
|
data/spec/serf/loader_spec.rb
CHANGED
data/spec/serf/serfer_spec.rb
CHANGED
@@ -11,12 +11,21 @@ describe Serf::Serfer do
|
|
11
11
|
let(:request_parcel) {
|
12
12
|
FactoryGirl.create :random_parcel
|
13
13
|
}
|
14
|
+
let(:versioned_response_kind_version) {
|
15
|
+
SecureRandom.hex
|
16
|
+
}
|
17
|
+
let(:versioned_response_kind) {
|
18
|
+
"#{response_kind}\##{versioned_response_kind_version}"
|
19
|
+
}
|
14
20
|
let(:response_kind) {
|
15
21
|
SecureRandom.hex
|
16
22
|
}
|
17
23
|
let(:response_message) {
|
18
24
|
FactoryGirl.create :random_hash
|
19
25
|
}
|
26
|
+
let(:response_headers) {
|
27
|
+
FactoryGirl.create :random_hash
|
28
|
+
}
|
20
29
|
let(:disconnected_response_parcel) {
|
21
30
|
FactoryGirl.create :random_parcel
|
22
31
|
}
|
@@ -49,14 +58,55 @@ describe Serf::Serfer do
|
|
49
58
|
expect(parcel.message).to eq(response_message)
|
50
59
|
end
|
51
60
|
|
52
|
-
it 'uses parcel factory w/
|
61
|
+
it 'uses parcel factory w/ parent (w/ nil kind+message+headers)' do
|
62
|
+
mock_parcel_factory = double 'parcel_factory'
|
63
|
+
mock_parcel_factory.
|
64
|
+
should_receive(:create).
|
65
|
+
with({
|
66
|
+
parent: request_parcel,
|
67
|
+
kind: nil,
|
68
|
+
message: nil,
|
69
|
+
headers: nil
|
70
|
+
}).
|
71
|
+
and_return(disconnected_response_parcel)
|
72
|
+
|
73
|
+
serfer = described_class.new(
|
74
|
+
lambda { |obj| },
|
75
|
+
parcel_factory: mock_parcel_factory)
|
76
|
+
parcel = serfer.call request_parcel
|
77
|
+
|
78
|
+
expect(parcel).to eq(disconnected_response_parcel)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'uses parcel factory w/ kind, parent (w/ nil message+headers)' do
|
82
|
+
mock_parcel_factory = double 'parcel_factory'
|
83
|
+
mock_parcel_factory.
|
84
|
+
should_receive(:create).
|
85
|
+
with({
|
86
|
+
parent: request_parcel,
|
87
|
+
kind: response_kind,
|
88
|
+
message: nil,
|
89
|
+
headers: nil
|
90
|
+
}).
|
91
|
+
and_return(disconnected_response_parcel)
|
92
|
+
|
93
|
+
serfer = described_class.new(
|
94
|
+
lambda { |obj| return response_kind },
|
95
|
+
parcel_factory: mock_parcel_factory)
|
96
|
+
parcel = serfer.call request_parcel
|
97
|
+
|
98
|
+
expect(parcel).to eq(disconnected_response_parcel)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'uses parcel factory w/ kind, parent and message (w/ nil headers)' do
|
53
102
|
mock_parcel_factory = double 'parcel_factory'
|
54
103
|
mock_parcel_factory.
|
55
104
|
should_receive(:create).
|
56
105
|
with({
|
57
106
|
parent: request_parcel,
|
58
107
|
kind: response_kind,
|
59
|
-
message: response_message
|
108
|
+
message: response_message,
|
109
|
+
headers: nil
|
60
110
|
}).
|
61
111
|
and_return(disconnected_response_parcel)
|
62
112
|
|
@@ -68,6 +118,52 @@ describe Serf::Serfer do
|
|
68
118
|
expect(parcel).to eq(disconnected_response_parcel)
|
69
119
|
end
|
70
120
|
|
121
|
+
it 'uses parcel factory w/ kind, parent, message and headers' do
|
122
|
+
mock_parcel_factory = double 'parcel_factory'
|
123
|
+
mock_parcel_factory.
|
124
|
+
should_receive(:create).
|
125
|
+
with({
|
126
|
+
parent: request_parcel,
|
127
|
+
kind: response_kind,
|
128
|
+
message: response_message,
|
129
|
+
headers: response_headers
|
130
|
+
}).
|
131
|
+
and_return(disconnected_response_parcel)
|
132
|
+
|
133
|
+
serfer = described_class.new(
|
134
|
+
lambda { |obj|
|
135
|
+
return response_kind, response_message, response_headers
|
136
|
+
},
|
137
|
+
parcel_factory: mock_parcel_factory)
|
138
|
+
parcel = serfer.call request_parcel
|
139
|
+
|
140
|
+
expect(parcel).to eq(disconnected_response_parcel)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'moves version info from a versioned kind to the headers' do
|
144
|
+
mock_parcel_factory = double 'parcel_factory'
|
145
|
+
mock_parcel_factory.
|
146
|
+
should_receive(:create).
|
147
|
+
with({
|
148
|
+
parent: request_parcel,
|
149
|
+
kind: response_kind,
|
150
|
+
message: response_message,
|
151
|
+
headers: {
|
152
|
+
version: versioned_response_kind_version
|
153
|
+
}
|
154
|
+
}).
|
155
|
+
and_return(disconnected_response_parcel)
|
156
|
+
|
157
|
+
serfer = described_class.new(
|
158
|
+
lambda { |obj|
|
159
|
+
return versioned_response_kind, response_message
|
160
|
+
},
|
161
|
+
parcel_factory: mock_parcel_factory)
|
162
|
+
parcel = serfer.call request_parcel
|
163
|
+
|
164
|
+
expect(parcel).to eq(disconnected_response_parcel)
|
165
|
+
end
|
166
|
+
|
71
167
|
end
|
72
168
|
|
73
169
|
end
|
@@ -12,7 +12,12 @@ describe Serf::Util::ErrorHandling do
|
|
12
12
|
expect(result).to be_nil
|
13
13
|
JsonSchemaTester.new.validate_for!(
|
14
14
|
'serf/events/caught_error',
|
15
|
-
error)
|
15
|
+
Hashie::Mash.new(error))
|
16
|
+
expect(error[:error]).to be_kind_of(String)
|
17
|
+
expect(error[:message]).to be_kind_of(String)
|
18
|
+
expect(error[:process_env]).to be_kind_of(Hash)
|
19
|
+
expect(error[:hostname]).to be_kind_of(String)
|
20
|
+
expect(error[:backtrace]).to be_kind_of(String)
|
16
21
|
end
|
17
22
|
|
18
23
|
end
|
@@ -21,6 +21,26 @@ describe Serf::Util::Uuidable do
|
|
21
21
|
|
22
22
|
end
|
23
23
|
|
24
|
+
describe '#coded_uuid_time' do
|
25
|
+
let(:coded_uuid) {
|
26
|
+
'RIEHuF5-EeKLPQQMzuOZ7g'
|
27
|
+
}
|
28
|
+
let(:time_seconds) {
|
29
|
+
1358190718
|
30
|
+
}
|
31
|
+
let(:time_usec) {
|
32
|
+
273324
|
33
|
+
}
|
34
|
+
|
35
|
+
it 'returns a valid time object' do
|
36
|
+
time = subject.coded_uuid_time coded_uuid
|
37
|
+
# Check that we have a good timestamp in seconds and nanoseconds
|
38
|
+
expect(time.to_i).to eq(time_seconds)
|
39
|
+
expect(time.tv_usec).to eq(time_usec)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
24
44
|
describe '#create_uuids' do
|
25
45
|
|
26
46
|
it 'works with no parent' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: serf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hashie
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- example/serfs/create_widget.serf
|
97
97
|
- lib/serf.rb
|
98
98
|
- lib/serf/builder.rb
|
99
|
+
- lib/serf/errors/load_failure.rb
|
99
100
|
- lib/serf/errors/policy_failure.rb
|
100
101
|
- lib/serf/loader.rb
|
101
102
|
- lib/serf/loader/loader.rb
|
@@ -115,6 +116,8 @@ files:
|
|
115
116
|
- lib/serf/version.rb
|
116
117
|
- schemas/serf/events/caught_error.json
|
117
118
|
- serf.gemspec
|
119
|
+
- spec/data/construction_error.serf
|
120
|
+
- spec/data/raises_error.serf
|
118
121
|
- spec/serf/builder_spec.rb
|
119
122
|
- spec/serf/errors/policy_failure_spec.rb
|
120
123
|
- spec/serf/loader/loader_spec.rb
|
@@ -155,7 +158,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
158
|
version: '0'
|
156
159
|
segments:
|
157
160
|
- 0
|
158
|
-
hash:
|
161
|
+
hash: 526665702158101187
|
159
162
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
163
|
none: false
|
161
164
|
requirements:
|
@@ -164,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
167
|
version: '0'
|
165
168
|
segments:
|
166
169
|
- 0
|
167
|
-
hash:
|
170
|
+
hash: 526665702158101187
|
168
171
|
requirements: []
|
169
172
|
rubyforge_project:
|
170
173
|
rubygems_version: 1.8.23
|
@@ -172,6 +175,8 @@ signing_key:
|
|
172
175
|
specification_version: 3
|
173
176
|
summary: Interactors with policy protection
|
174
177
|
test_files:
|
178
|
+
- spec/data/construction_error.serf
|
179
|
+
- spec/data/raises_error.serf
|
175
180
|
- spec/serf/builder_spec.rb
|
176
181
|
- spec/serf/errors/policy_failure_spec.rb
|
177
182
|
- spec/serf/loader/loader_spec.rb
|