tdl-client-ruby 0.3.6 → 0.5.7
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.
- checksums.yaml +4 -4
- data/examples/add_numbers.rb +23 -6
- data/lib/tdl/abstractions/processing_rule.rb +10 -0
- data/lib/tdl/abstractions/processing_rules.rb +52 -0
- data/lib/tdl/abstractions/request.rb +10 -4
- data/lib/tdl/abstractions/response.rb +6 -2
- data/lib/tdl/actions/client_actions.rb +20 -0
- data/lib/tdl/actions/publish_action.rb +17 -0
- data/lib/tdl/actions/publish_and_stop_action.rb +16 -0
- data/lib/tdl/actions/stop_action.rb +17 -0
- data/lib/tdl/client.rb +68 -29
- data/lib/tdl/serialization/json_rpc_serialization_provider.rb +4 -5
- data/lib/tdl/transport/remote_broker.rb +7 -4
- data/lib/tdl/version.rb +2 -2
- data/tdl-client-ruby.iml +0 -1
- metadata +8 -6
- data/lib/tdl/deserialize_and_respond_to_message.rb +0 -24
- data/lib/tdl/respond/audit_traffic.rb +0 -20
- data/lib/tdl/respond/obtain_response.rb +0 -33
- data/lib/tdl/respond/validate_response.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f26c749800235135540aa9dbd89683d51c7acc2
|
4
|
+
data.tar.gz: 50a2516af1455cfca7428985e3f187ec281d33c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c65df7f640fcb09cd9aa9ff8e5dc79febc92d1d8a706c73b5ecf58b487aa7f22eb163a7cc35cb73bd85a11deb4b093cd600516a3e15ea5a0538212225303822f
|
7
|
+
data.tar.gz: ff0f24af5b8a58132d6e142f4c3b11c7033fbbd5b6560cd3b2a69566262f0aa7cbca9a227259f8a1bec53a2766d80aec00d53558529813c4781fad82b301d291
|
data/examples/add_numbers.rb
CHANGED
@@ -5,10 +5,27 @@ Logging.logger.root.appenders = Logging.appenders.stdout
|
|
5
5
|
Logging.logger.root.level = :info
|
6
6
|
|
7
7
|
|
8
|
-
|
8
|
+
def run_client
|
9
|
+
client = TDL::Client.new('localhost', 61613, 'julian')
|
10
|
+
include TDL::ClientActions
|
11
|
+
rules = TDL::ProcessingRules.new
|
12
|
+
rules.on('display_description').call(method(:display)).then(publish)
|
13
|
+
rules.on('display_required_methods').call(method(:display)).then(publish)
|
14
|
+
rules.on('increment').call(method(:increment)).then(publish_and_stop)
|
9
15
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
# puts processing_rules.to_yaml
|
17
|
+
|
18
|
+
client.go_live_with(rules)
|
19
|
+
end
|
20
|
+
|
21
|
+
def display(str)
|
22
|
+
puts str
|
23
|
+
'OK'
|
24
|
+
end
|
25
|
+
|
26
|
+
def increment(x)
|
27
|
+
x + 1
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
run_client
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'tdl/abstractions/processing_rule'
|
2
|
+
require 'tdl/actions/client_actions'
|
3
|
+
|
4
|
+
module TDL
|
5
|
+
class ProcessingRules
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@rules = Hash.new
|
9
|
+
end
|
10
|
+
|
11
|
+
# ~~~~ Builders
|
12
|
+
|
13
|
+
def add(method_name, user_implementation, client_action)
|
14
|
+
@rules[method_name] = ProcessingRule.new(user_implementation, client_action)
|
15
|
+
end
|
16
|
+
|
17
|
+
def on(method_name)
|
18
|
+
ProcessingRuleBuilder.new(self, method_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
class ProcessingRuleBuilder
|
23
|
+
|
24
|
+
def initialize(instance, method_name)
|
25
|
+
@instance = instance
|
26
|
+
@method_name = method_name
|
27
|
+
end
|
28
|
+
|
29
|
+
def call(user_implementation)
|
30
|
+
@user_implementation = user_implementation
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def then(client_action)
|
35
|
+
@instance.add(@method_name, @user_implementation, client_action)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
# ~~~~ Accessors
|
42
|
+
|
43
|
+
def get_rule_for(request)
|
44
|
+
if @rules.has_key?(request.method)
|
45
|
+
@rules[request.method]
|
46
|
+
else
|
47
|
+
raise NameError.new("Method #{request.method} did not match any processing rule.")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -1,10 +1,16 @@
|
|
1
1
|
module TDL
|
2
2
|
class Request
|
3
|
-
attr_reader :id, :params
|
3
|
+
attr_reader :original_message, :id, :method, :params
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
7
|
-
@
|
5
|
+
def initialize(original_message, request_data)
|
6
|
+
@original_message = original_message
|
7
|
+
@id = request_data['id']
|
8
|
+
@method = request_data['method']
|
9
|
+
@params = request_data['params']
|
10
|
+
end
|
11
|
+
|
12
|
+
def audit_text
|
13
|
+
"id = #{@id}, req = #{@method}(#{@params.join(', ')})"
|
8
14
|
end
|
9
15
|
end
|
10
16
|
end
|
@@ -2,8 +2,8 @@ module TDL
|
|
2
2
|
class Response
|
3
3
|
attr_reader :result, :id
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@id =
|
5
|
+
def initialize(id, result)
|
6
|
+
@id = id
|
7
7
|
@result = result
|
8
8
|
end
|
9
9
|
|
@@ -14,5 +14,9 @@ module TDL
|
|
14
14
|
:id => @id,
|
15
15
|
}
|
16
16
|
end
|
17
|
+
|
18
|
+
def audit_text
|
19
|
+
"resp = #{@result}"
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'tdl/actions/publish_action'
|
2
|
+
require 'tdl/actions/stop_action'
|
3
|
+
require 'tdl/actions/publish_and_stop_action'
|
4
|
+
|
5
|
+
module TDL
|
6
|
+
module ClientActions
|
7
|
+
|
8
|
+
def publish
|
9
|
+
PublishAction.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def stop
|
13
|
+
StopAction.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def publish_and_stop
|
17
|
+
PublishAndStopAction.new
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module TDL
|
2
|
+
class PublishAction
|
3
|
+
|
4
|
+
def audit_text
|
5
|
+
''
|
6
|
+
end
|
7
|
+
|
8
|
+
def after_response(remote_broker, request, response)
|
9
|
+
remote_broker.respond_to(request, response)
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare_for_next_request(remote_broker)
|
13
|
+
# DO nothing
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module TDL
|
2
|
+
class PublishAndStopAction
|
3
|
+
|
4
|
+
def audit_text
|
5
|
+
''
|
6
|
+
end
|
7
|
+
|
8
|
+
def after_response(remote_broker, request, response)
|
9
|
+
remote_broker.respond_to(request, response)
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare_for_next_request(remote_broker)
|
13
|
+
remote_broker.close
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module TDL
|
2
|
+
class StopAction
|
3
|
+
|
4
|
+
def audit_text
|
5
|
+
'(NOT PUBLISHED)'
|
6
|
+
end
|
7
|
+
|
8
|
+
def after_response(remote_broker, request, response)
|
9
|
+
# do nothing
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare_for_next_request(remote_broker)
|
13
|
+
remote_broker.close
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/tdl/client.rb
CHANGED
@@ -2,7 +2,10 @@ require 'stomp'
|
|
2
2
|
require 'logging'
|
3
3
|
|
4
4
|
require 'tdl/transport/remote_broker'
|
5
|
-
require 'tdl/
|
5
|
+
require 'tdl/abstractions/processing_rules'
|
6
|
+
require 'tdl/actions/stop_action'
|
7
|
+
|
8
|
+
require 'tdl/serialization/json_rpc_serialization_provider'
|
6
9
|
|
7
10
|
module TDL
|
8
11
|
|
@@ -15,19 +18,11 @@ module TDL
|
|
15
18
|
@logger = Logging.logger[self]
|
16
19
|
end
|
17
20
|
|
18
|
-
def go_live_with(
|
19
|
-
run(RespondToAllRequests.new(DeserializeAndRespondToMessage.using(user_implementation)))
|
20
|
-
end
|
21
|
-
|
22
|
-
def trial_run_with(user_implementation)
|
23
|
-
run(PeekAtFirstRequest.new(DeserializeAndRespondToMessage.using(user_implementation)))
|
24
|
-
end
|
25
|
-
|
26
|
-
def run(handling_strategy)
|
21
|
+
def go_live_with(processing_rules)
|
27
22
|
begin
|
28
23
|
@logger.info 'Starting client.'
|
29
24
|
remote_broker = RemoteBroker.new(@hostname, @port, @username)
|
30
|
-
remote_broker.subscribe(
|
25
|
+
remote_broker.subscribe(ApplyProcessingRules.new(processing_rules))
|
31
26
|
|
32
27
|
#DEBT: We should have no timeout here. We could put a special message in the queue
|
33
28
|
remote_broker.join(3)
|
@@ -35,37 +30,81 @@ module TDL
|
|
35
30
|
remote_broker.close
|
36
31
|
rescue Exception => e
|
37
32
|
@logger.error "Problem communicating with the broker. #{e.message}"
|
38
|
-
raise $! if ENV[
|
33
|
+
raise $! if ENV['RUBY_ENV'] == 'test'
|
39
34
|
end
|
40
35
|
end
|
41
36
|
|
37
|
+
|
42
38
|
#~~~~ Queue handling policies
|
43
39
|
|
44
|
-
class
|
45
|
-
|
46
|
-
|
40
|
+
class ApplyProcessingRules
|
41
|
+
|
42
|
+
def initialize(processing_rules)
|
43
|
+
@processing_rules = processing_rules
|
44
|
+
@logger = Logging.logger[self]
|
45
|
+
@audit = AuditStream.new
|
47
46
|
end
|
48
47
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
48
|
+
def process_next_request_from(remote_broker, request)
|
49
|
+
@audit.start_line
|
50
|
+
@audit.log(request)
|
51
|
+
|
52
|
+
# Obtain response from user
|
53
|
+
processing_rule = @processing_rules.get_rule_for(request)
|
54
|
+
response = get_response_for(processing_rule, request)
|
55
|
+
@audit.log(response ? response : Response.new('','empty'))
|
56
|
+
|
57
|
+
# Obtain action
|
58
|
+
client_action = response ? processing_rule.client_action : StopAction.new
|
59
|
+
|
60
|
+
# Act
|
61
|
+
client_action.after_response(remote_broker, request, response)
|
62
|
+
@audit.log(client_action)
|
63
|
+
@audit.end_line
|
64
|
+
client_action.prepare_for_next_request(remote_broker)
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_response_for(processing_rule, request)
|
68
|
+
begin
|
69
|
+
user_implementation = processing_rule.user_implementation
|
70
|
+
result = user_implementation.call(*request.params)
|
71
|
+
|
72
|
+
response = Response.new(request.id, result)
|
73
|
+
rescue Exception => e
|
74
|
+
response = nil
|
75
|
+
@logger.info "The user implementation has thrown exception. #{e.message}"
|
56
76
|
end
|
77
|
+
response
|
57
78
|
end
|
79
|
+
|
58
80
|
end
|
81
|
+
end
|
59
82
|
|
60
|
-
class PeekAtFirstRequest
|
61
|
-
def initialize(message_handler)
|
62
|
-
@message_handler = message_handler
|
63
|
-
end
|
64
83
|
|
65
|
-
|
66
|
-
|
67
|
-
|
84
|
+
# ~~~~ Utils
|
85
|
+
|
86
|
+
class AuditStream
|
87
|
+
|
88
|
+
def initialize
|
89
|
+
@logger = Logging.logger[self]
|
90
|
+
start_line
|
91
|
+
end
|
92
|
+
|
93
|
+
def start_line
|
94
|
+
@str = ''
|
95
|
+
end
|
96
|
+
|
97
|
+
def log(auditable)
|
98
|
+
text = auditable.audit_text
|
99
|
+
if not text.empty? and @str.length > 0
|
100
|
+
@str << ', '
|
68
101
|
end
|
102
|
+
|
103
|
+
@str << text
|
104
|
+
end
|
105
|
+
|
106
|
+
def end_line
|
107
|
+
@logger.info @str
|
69
108
|
end
|
70
109
|
|
71
110
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'json'
|
1
2
|
require 'tdl/abstractions/request'
|
2
3
|
require 'tdl/abstractions/response'
|
3
4
|
|
@@ -7,11 +8,9 @@ module TDL
|
|
7
8
|
@logger = Logging.logger[self]
|
8
9
|
end
|
9
10
|
|
10
|
-
def deserialize(
|
11
|
-
|
12
|
-
|
13
|
-
OpenStruct.new(json)
|
14
|
-
# DEBT means there is no Request object needed
|
11
|
+
def deserialize(msg)
|
12
|
+
request_data = JSON.parse(msg.body)
|
13
|
+
Request.new(msg, request_data)
|
15
14
|
end
|
16
15
|
|
17
16
|
def serialize(response)
|
@@ -3,17 +3,20 @@ module TDL
|
|
3
3
|
def initialize(hostname, port, username)
|
4
4
|
@stomp_client = Stomp::Client.new('', '', hostname, port)
|
5
5
|
@username = username
|
6
|
+
@serialization_provider = JSONRPCSerializationProvider.new
|
6
7
|
end
|
7
8
|
|
8
|
-
|
9
9
|
def subscribe(handling_strategy)
|
10
10
|
@stomp_client.subscribe("/queue/#{@username}.req", {:ack => 'client', 'activemq.prefetchSize' => 1}) do |msg|
|
11
|
-
|
11
|
+
request = @serialization_provider.deserialize(msg)
|
12
|
+
handling_strategy.process_next_request_from(self, request)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
|
-
def
|
16
|
-
@
|
16
|
+
def respond_to(request, response)
|
17
|
+
serialized_response = @serialization_provider.serialize(response)
|
18
|
+
@stomp_client.publish("/queue/#{@username}.resp", serialized_response)
|
19
|
+
@stomp_client.acknowledge(request.original_message)
|
17
20
|
end
|
18
21
|
|
19
22
|
def publish(response)
|
data/lib/tdl/version.rb
CHANGED
data/tdl-client-ruby.iml
CHANGED
@@ -40,7 +40,6 @@
|
|
40
40
|
<orderEntry type="library" scope="PROVIDED" name="multi_json (v1.11.2, rbenv: 2.2.2) [gem]" level="application" />
|
41
41
|
<orderEntry type="library" scope="PROVIDED" name="multi_test (v0.1.2, rbenv: 2.2.2) [gem]" level="application" />
|
42
42
|
<orderEntry type="library" scope="PROVIDED" name="netrc (v0.10.3, rbenv: 2.2.2) [gem]" level="application" />
|
43
|
-
<orderEntry type="library" scope="PROVIDED" name="rake (v10.4.2, rbenv: 2.2.2) [gem]" level="application" />
|
44
43
|
<orderEntry type="library" scope="PROVIDED" name="rest-client (v1.8.0, rbenv: 2.2.2) [gem]" level="application" />
|
45
44
|
<orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.7.5, rbenv: 2.2.2) [gem]" level="application" />
|
46
45
|
<orderEntry type="library" scope="PROVIDED" name="simplecov (v0.10.0, rbenv: 2.2.2) [gem]" level="application" />
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tdl-client-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julian Ghionoiu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: stomp
|
@@ -198,13 +198,15 @@ files:
|
|
198
198
|
- Rakefile
|
199
199
|
- examples/add_numbers.rb
|
200
200
|
- lib/tdl.rb
|
201
|
+
- lib/tdl/abstractions/processing_rule.rb
|
202
|
+
- lib/tdl/abstractions/processing_rules.rb
|
201
203
|
- lib/tdl/abstractions/request.rb
|
202
204
|
- lib/tdl/abstractions/response.rb
|
205
|
+
- lib/tdl/actions/client_actions.rb
|
206
|
+
- lib/tdl/actions/publish_action.rb
|
207
|
+
- lib/tdl/actions/publish_and_stop_action.rb
|
208
|
+
- lib/tdl/actions/stop_action.rb
|
203
209
|
- lib/tdl/client.rb
|
204
|
-
- lib/tdl/deserialize_and_respond_to_message.rb
|
205
|
-
- lib/tdl/respond/audit_traffic.rb
|
206
|
-
- lib/tdl/respond/obtain_response.rb
|
207
|
-
- lib/tdl/respond/validate_response.rb
|
208
210
|
- lib/tdl/serialization/json_rpc_serialization_provider.rb
|
209
211
|
- lib/tdl/transport/remote_broker.rb
|
210
212
|
- lib/tdl/version.rb
|
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'tdl/serialization/json_rpc_serialization_provider'
|
2
|
-
require 'tdl/respond/validate_response'
|
3
|
-
require 'tdl/respond/audit_traffic'
|
4
|
-
require 'tdl/respond/obtain_response'
|
5
|
-
|
6
|
-
module TDL
|
7
|
-
class DeserializeAndRespondToMessage
|
8
|
-
def initialize(user_implementation)
|
9
|
-
@serialization_provider = JSONRPCSerializationProvider.new
|
10
|
-
@response_strategy = ValidateResponse.new(AuditTraffic.new(ObtainResponse.new(user_implementation)))
|
11
|
-
@logger = Logging.logger[self]
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.using(user_implementation)
|
15
|
-
DeserializeAndRespondToMessage.new(user_implementation)
|
16
|
-
end
|
17
|
-
|
18
|
-
def respond_to(message_text)
|
19
|
-
request = @serialization_provider.deserialize(message_text)
|
20
|
-
response = @response_strategy.respond_to(request)
|
21
|
-
@serialization_provider.serialize(response)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'tdl/abstractions/request'
|
2
|
-
require 'tdl/abstractions/response'
|
3
|
-
|
4
|
-
module TDL
|
5
|
-
class AuditTraffic
|
6
|
-
def initialize(wrapped_strategy)
|
7
|
-
@wrapped_strategy = wrapped_strategy
|
8
|
-
@logger = Logging.logger[self]
|
9
|
-
end
|
10
|
-
|
11
|
-
def respond_to(request)
|
12
|
-
response = @wrapped_strategy.respond_to(request)
|
13
|
-
|
14
|
-
@logger.info "id = #{request.id}, req = #{request.to_h[:method]}(#{request.params.join(", ")}), resp = #{response.result}"
|
15
|
-
# DEBT method method taken on ostruct
|
16
|
-
|
17
|
-
response
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'tdl/abstractions/request'
|
2
|
-
require 'tdl/abstractions/response'
|
3
|
-
|
4
|
-
module TDL
|
5
|
-
class ObtainResponse
|
6
|
-
def initialize(user_implementation)
|
7
|
-
@user_implementation = user_implementation
|
8
|
-
@logger = Logging.logger[self]
|
9
|
-
end
|
10
|
-
|
11
|
-
def respond_to(request)
|
12
|
-
begin
|
13
|
-
# DEBT method is a default method on objects
|
14
|
-
# o = OpenStruct.new({method: 5})
|
15
|
-
# o.method !! Error
|
16
|
-
|
17
|
-
# DEBT object is treated and a collection of anonymous methods and not a normal object this is not ideomatic ruby
|
18
|
-
|
19
|
-
result = @user_implementation.send(request.to_h[:method], *request.params)
|
20
|
-
rescue Exception => e
|
21
|
-
@logger.info "The user implementation has thrown exception. #{e.message}"
|
22
|
-
result = nil
|
23
|
-
raise $! if ENV["RUBY_ENV"] == "test"
|
24
|
-
end
|
25
|
-
|
26
|
-
if result.nil?
|
27
|
-
@logger.info 'User implementation has returned "nil"'
|
28
|
-
end
|
29
|
-
|
30
|
-
Response.new(request, result)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'tdl/abstractions/request'
|
2
|
-
require 'tdl/abstractions/response'
|
3
|
-
|
4
|
-
module TDL
|
5
|
-
class ValidateResponse
|
6
|
-
def initialize(wrapped_strategy)
|
7
|
-
@wrapped_strategy = wrapped_strategy
|
8
|
-
@logger = Logging.logger[self]
|
9
|
-
end
|
10
|
-
|
11
|
-
def respond_to(request)
|
12
|
-
response = @wrapped_strategy.respond_to(request)
|
13
|
-
(response.result == nil) ? nil : response
|
14
|
-
# DEBT should pass nil response to top level
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|