SMService 0.1.4 → 0.1.8
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/Dockerfile +2 -1
- data/Gemfile.lock +7 -1
- data/{smservice.gemspec → SMService.gemspec} +1 -0
- data/bin/console +64 -7
- data/docker-compose.yml +15 -0
- data/docker.sh +4 -0
- data/examples/dummy.rb +25 -0
- data/lib/smservice/version.rb +1 -1
- data/lib/smservice.rb +98 -45
- metadata +20 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 99628cf63e1cded8cfdd814002fb905aecd17833a19bd474da23671fe692c78e
|
|
4
|
+
data.tar.gz: 4eb82e840f5f730707784fb51fddd90f3accfe4501d9e3b5e9aa731133915490
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d3d7a51b6da0ff3144deefa211fd27fdd15473f2197ee0baf55d9b669e32bfd032e7c0a6d8c350c151b6c062530968c7a8e6cb13ff224799949d4e8ec456a3c1
|
|
7
|
+
data.tar.gz: f879a7f6182bbbac5c336f551991ea395f08953425ae6691d49712767947132413a7ef90fb898ff1495dde014f37ca0e5dfe1aceb644588c9b5e228d1133e092
|
data/Dockerfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
SMService (0.1.
|
|
4
|
+
SMService (0.1.8)
|
|
5
5
|
ffi-rzmq (~> 2.0)
|
|
6
6
|
logger (~> 1.2)
|
|
7
7
|
msgpack (~> 1.1)
|
|
@@ -9,6 +9,7 @@ PATH
|
|
|
9
9
|
GEM
|
|
10
10
|
remote: https://rubygems.org/
|
|
11
11
|
specs:
|
|
12
|
+
coderay (1.1.2)
|
|
12
13
|
diff-lcs (1.3)
|
|
13
14
|
ffi (1.9.18)
|
|
14
15
|
ffi-rzmq (2.0.5)
|
|
@@ -16,7 +17,11 @@ GEM
|
|
|
16
17
|
ffi-rzmq-core (1.0.6)
|
|
17
18
|
ffi
|
|
18
19
|
logger (1.2.8)
|
|
20
|
+
method_source (0.9.0)
|
|
19
21
|
msgpack (1.1.0)
|
|
22
|
+
pry (0.11.3)
|
|
23
|
+
coderay (~> 1.1.0)
|
|
24
|
+
method_source (~> 0.9.0)
|
|
20
25
|
rake (10.5.0)
|
|
21
26
|
rspec (3.7.0)
|
|
22
27
|
rspec-core (~> 3.7.0)
|
|
@@ -38,6 +43,7 @@ PLATFORMS
|
|
|
38
43
|
DEPENDENCIES
|
|
39
44
|
SMService!
|
|
40
45
|
bundler (~> 1.16)
|
|
46
|
+
pry (~> 0.11)
|
|
41
47
|
rake (~> 10.0)
|
|
42
48
|
rspec (~> 3.0)
|
|
43
49
|
|
data/bin/console
CHANGED
|
@@ -1,16 +1,73 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'pry'
|
|
3
5
|
require 'bundler'
|
|
4
6
|
Bundler.setup
|
|
5
7
|
Bundler.require
|
|
6
8
|
require 'smservice'
|
|
9
|
+
require_relative '../examples/dummy'
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
class SMService::TestCase
|
|
12
|
+
include SMService
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
def initialize
|
|
15
|
+
super name: 'test_ruby', actions: 'test'
|
|
16
|
+
end
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
def action_test(headers, message)
|
|
19
|
+
LOGGER.info "#{self.class} - Processing action 'test'. Headers: #{headers.inspect}, message: #{message.inspect}"
|
|
20
|
+
|
|
21
|
+
# triggering 'someaction' as part of test plan
|
|
22
|
+
@tc_reply_to = headers['reply_to'] # where TC shall report-to at the end
|
|
23
|
+
message[:parent_action_headers] = headers # sending also parameters from caller
|
|
24
|
+
execute action: 'someaction', message: message
|
|
25
|
+
|
|
26
|
+
if headers['reply_to']
|
|
27
|
+
# sending reply back
|
|
28
|
+
LOGGER.info "#{self.class} - Action 'test' sending reply"
|
|
29
|
+
|
|
30
|
+
execute action: 'REPLY',
|
|
31
|
+
reply_to: headers['reply_to'],
|
|
32
|
+
message: {status: 'OK', more_data: ['...']}
|
|
33
|
+
|
|
34
|
+
LOGGER.info "#{self.class} - Action 'test' reply sent"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
LOGGER.info "#{self.class} - Terminating action 'test'"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def action_reply(headers, message)
|
|
41
|
+
LOGGER.info "#{self.class} - Processing action 'reply'. Headers: #{headers.inspect}, message: #{message.inspect}"
|
|
42
|
+
|
|
43
|
+
# ... if conditions and validations to ensure that it is reply for this TC, by searching UUID etc etc, and by the end:
|
|
44
|
+
#
|
|
45
|
+
LOGGER.info "#{self.class} - Forwarding collected TC data to the caller, which is #{@tc_reply_to}"
|
|
46
|
+
execute action: 'REPLY',
|
|
47
|
+
reply_to: @tc_reply_to,
|
|
48
|
+
message: message
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class SMService::API
|
|
53
|
+
include SMService
|
|
54
|
+
|
|
55
|
+
def initialize
|
|
56
|
+
super name: 'api'
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
dummy = SMService::Dummy.new
|
|
62
|
+
dummy.start!
|
|
63
|
+
|
|
64
|
+
tc = SMService::TestCase.new
|
|
65
|
+
tc.start!
|
|
66
|
+
|
|
67
|
+
api = SMService::API.new
|
|
68
|
+
api.start!
|
|
69
|
+
|
|
70
|
+
sleep 3
|
|
71
|
+
api.execute(action: 'test', message: {my_request: 'ping', my_data: 'add whatever data needed'})
|
|
72
|
+
|
|
73
|
+
binding.pry
|
data/docker-compose.yml
ADDED
data/docker.sh
ADDED
data/examples/dummy.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class SMService::Dummy
|
|
2
|
+
include SMService
|
|
3
|
+
|
|
4
|
+
def initialize
|
|
5
|
+
super name: 'dummy_ruby', actions: 'someaction'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def action_someaction(headers, message)
|
|
9
|
+
LOGGER.info "#{self.class} - Processing action 'someaction'. Headers: #{headers.inspect}, message: #{message.inspect}"
|
|
10
|
+
|
|
11
|
+
if headers['reply_to']
|
|
12
|
+
# sending reply back
|
|
13
|
+
LOGGER.info "#{self.class} - Action 'someaction' sending reply"
|
|
14
|
+
|
|
15
|
+
execute action: 'REPLY',
|
|
16
|
+
reply_to: headers['reply_to'],
|
|
17
|
+
message: {status: 'OK', whatever: 'add it here'}
|
|
18
|
+
|
|
19
|
+
LOGGER.info "#{self.class} - Action 'someaction' reply sent"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
LOGGER.info "#{self.class} - Terminating action 'someaction'"
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/smservice/version.rb
CHANGED
data/lib/smservice.rb
CHANGED
|
@@ -10,14 +10,37 @@ module SMService
|
|
|
10
10
|
ENDPOINT_OUT = 'tcp://proxy:6660'
|
|
11
11
|
ENDPOINT_IN = 'tcp://proxy:6661'
|
|
12
12
|
|
|
13
|
-
REGISTER_WAIT_TIME
|
|
13
|
+
REGISTER_WAIT_TIME = 'infinite'
|
|
14
|
+
REGISTER_RETRY = 10
|
|
14
15
|
KEEPALIVE_WAIT_TIME = 30
|
|
15
16
|
|
|
16
17
|
attr_accessor :socket_in, :socket_out
|
|
17
18
|
attr_reader :service_name
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
# When registering node, following parameters is mandatory:
|
|
21
|
+
#
|
|
22
|
+
# name: name of service/node with its id;
|
|
23
|
+
# actions: list of actions, should be in lowercase and compatible to naming standard for ruby methods
|
|
24
|
+
# actions could be presented as array or as string if service registering only single action
|
|
25
|
+
#
|
|
26
|
+
# Example:
|
|
27
|
+
# SMService::SomeService.new(name: 'dummy-ruby', actions: %w(a b c ping pong))
|
|
28
|
+
#
|
|
29
|
+
# Following actions should be defined as methods for new service, i.e.
|
|
30
|
+
#
|
|
31
|
+
# def action_ping(headers, message)
|
|
32
|
+
# LOGGER.info "#{self.class} - Processing action: PING with headers: #{headers.inspect} and message: #{message.inspect}"
|
|
33
|
+
# # ... business logic here
|
|
34
|
+
# end
|
|
35
|
+
#
|
|
36
|
+
# Prohibited names for actions is register and update, those are reserved to let service communicate with SM.
|
|
37
|
+
# Check SMService::Dummy source code (in examples folder) for detais
|
|
38
|
+
#
|
|
39
|
+
def initialize(name:, actions: [])
|
|
20
40
|
@service_name = name
|
|
41
|
+
@actions = [%w(ping), actions].flatten.sort.uniq
|
|
42
|
+
|
|
43
|
+
@mutex = Mutex.new
|
|
21
44
|
|
|
22
45
|
context = ZMQ::Context.new
|
|
23
46
|
@socket_in = context.socket ZMQ::DEALER
|
|
@@ -30,21 +53,46 @@ module SMService
|
|
|
30
53
|
@socket_out.connect ENDPOINT_OUT
|
|
31
54
|
end
|
|
32
55
|
|
|
33
|
-
|
|
56
|
+
# starting infinite loop in order to process service logic.
|
|
57
|
+
# start! or service_poller methods could be modified implementing different services, i.e. to run as threaded metod
|
|
58
|
+
def start!
|
|
59
|
+
register
|
|
60
|
+
keep_alive!
|
|
61
|
+
poller!
|
|
62
|
+
@started = true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def started?
|
|
66
|
+
@started
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def poller!
|
|
70
|
+
Thread.start do
|
|
71
|
+
poller
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def poller
|
|
76
|
+
loop do
|
|
77
|
+
pull
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def register(wait_time: REGISTER_WAIT_TIME)
|
|
34
82
|
if wait_time.to_f <= 0
|
|
35
83
|
loop do
|
|
36
|
-
|
|
84
|
+
register_service
|
|
37
85
|
break if registered?
|
|
38
86
|
# not registered, retrying in 10 seconds
|
|
39
|
-
sleep
|
|
87
|
+
sleep REGISTER_RETRY
|
|
40
88
|
end
|
|
41
89
|
else
|
|
42
90
|
Timeout::timeout(wait_time) do
|
|
43
91
|
loop do
|
|
44
|
-
|
|
92
|
+
register_service
|
|
45
93
|
break if registered?
|
|
46
94
|
# not registered, retrying in 10 seconds
|
|
47
|
-
sleep
|
|
95
|
+
sleep REGISTER_RETRY
|
|
48
96
|
end
|
|
49
97
|
end
|
|
50
98
|
end
|
|
@@ -52,11 +100,11 @@ module SMService
|
|
|
52
100
|
|
|
53
101
|
def keep_alive!(wait_time: KEEPALIVE_WAIT_TIME)
|
|
54
102
|
Thread.start do
|
|
55
|
-
LOGGER.info "Starting registration update loop with periodic interval #{wait_time} sec"
|
|
103
|
+
LOGGER.info "#{self.class} - Starting registration update loop with periodic interval #{wait_time} sec"
|
|
56
104
|
loop do
|
|
57
105
|
break unless registered?
|
|
58
106
|
sleep wait_time
|
|
59
|
-
|
|
107
|
+
request(action: 'UPDATE')
|
|
60
108
|
end
|
|
61
109
|
LOGGER.info 'Registration update loop terminated'
|
|
62
110
|
end
|
|
@@ -66,55 +114,66 @@ module SMService
|
|
|
66
114
|
@registered
|
|
67
115
|
end
|
|
68
116
|
|
|
69
|
-
def
|
|
70
|
-
|
|
71
|
-
|
|
117
|
+
def action_register(headers, message)
|
|
118
|
+
if headers['action'] == 'REGISTER' && message['result'] == 'OK'
|
|
119
|
+
@registered = true
|
|
120
|
+
LOGGER.info "#{self.class} - Action: REGISTER (successful), headers: #{headers.inspect}, message: #{message.inspect}"
|
|
121
|
+
else
|
|
122
|
+
LOGGER.info "#{self.class} - Action: REGISTER (failure), headers: #{headers.inspect}, message: #{message.inspect}"
|
|
123
|
+
end
|
|
72
124
|
end
|
|
73
125
|
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
pull_action
|
|
77
|
-
end
|
|
126
|
+
def action_ping(headers, message)
|
|
127
|
+
LOGGER.info "#{self.class} - Processing action 'ping'. Headers: #{headers.inspect}, message: #{message.inspect}"
|
|
78
128
|
end
|
|
79
129
|
|
|
80
|
-
def
|
|
81
|
-
|
|
82
|
-
keep_alive!
|
|
83
|
-
service_poller
|
|
130
|
+
def action_update(headers, message)
|
|
131
|
+
LOGGER.info "#{self.class} - Processing action 'update'. Headers: #{headers.inspect}, message: #{message.inspect}"
|
|
84
132
|
end
|
|
85
133
|
|
|
86
|
-
def
|
|
87
|
-
LOGGER.info
|
|
134
|
+
def action_reply(headers, message)
|
|
135
|
+
LOGGER.info "#{self.class} - Processing action 'reply'. Headers: #{headers.inspect}, message: #{message.inspect}"
|
|
88
136
|
end
|
|
89
137
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
138
|
+
# Requesting another service, registered at SM to execute given action, example:
|
|
139
|
+
# execute(action: 'create_customer_portal', message: {my_request: 'should create a customer', my_data: 'add whatever data needed'})
|
|
140
|
+
#
|
|
141
|
+
def execute(action:, reply_to: nil, message: nil)
|
|
142
|
+
LOGGER.info "#{self.class} - SM execute request. Action: #{action.inspect}, message: #{message.inspect}"
|
|
143
|
+
action = {service: action, reply_to: (reply_to || @service_name)}.to_msgpack
|
|
144
|
+
message = message.to_msgpack
|
|
145
|
+
@socket_out.send_strings [action, message]
|
|
97
146
|
end
|
|
98
147
|
|
|
99
148
|
private
|
|
100
149
|
|
|
150
|
+
def register_service
|
|
151
|
+
LOGGER.info "#{self.class} - Registering service #{service_name}"
|
|
152
|
+
request(action: 'REGISTER', message: {services: @actions})
|
|
153
|
+
pull
|
|
154
|
+
end
|
|
155
|
+
|
|
101
156
|
# Sending request to the Service Manager
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
LOGGER.info "SM request. Action: #{action.inspect}, message: #{message.inspect}"
|
|
157
|
+
def request(action:, message: nil)
|
|
158
|
+
LOGGER.info "#{self.class} - SM request. Action: #{action.inspect}, message: #{message.inspect}"
|
|
105
159
|
action = {action: action}.to_msgpack
|
|
106
160
|
message = message.to_msgpack
|
|
107
|
-
@
|
|
161
|
+
@mutex.synchronize do
|
|
162
|
+
@socket_in.send_strings [action, message]
|
|
163
|
+
end
|
|
108
164
|
end
|
|
109
165
|
|
|
110
|
-
def
|
|
111
|
-
|
|
166
|
+
def pull
|
|
167
|
+
response = []
|
|
168
|
+
@mutex.synchronize do
|
|
169
|
+
@socket_in.recv_strings(response)
|
|
170
|
+
end
|
|
112
171
|
|
|
113
172
|
headers, message = response
|
|
114
173
|
headers = MessagePack.unpack(headers)
|
|
115
174
|
message = MessagePack.unpack(message)
|
|
116
175
|
|
|
117
|
-
LOGGER.info "SM response received by
|
|
176
|
+
LOGGER.info "#{self.class} - SM response received by pull. Headers: #{headers.inspect}, message: #{message.inspect}"
|
|
118
177
|
|
|
119
178
|
# Validates is action_name exists as class method and calling it.
|
|
120
179
|
# In case, if Service Manager return headers['action'] == 'METHOD_NAME',
|
|
@@ -128,17 +187,11 @@ private
|
|
|
128
187
|
# - action_register, that confirms registration of node with Service Manager, and
|
|
129
188
|
# - action_update, that confirms successfule registration update, we need it to support keep-alive
|
|
130
189
|
#
|
|
131
|
-
action_name = "action_#{headers['action'].downcase}".to_sym
|
|
190
|
+
action_name = "action_#{(headers['action'] || headers['service']).downcase}".to_sym
|
|
132
191
|
if respond_to? action_name.to_sym
|
|
133
192
|
send(action_name, headers, message)
|
|
193
|
+
else
|
|
194
|
+
LOGGER.error "#{self.class} - Method #{action_name} does not exist in class instance for action name #{headers['action']}"
|
|
134
195
|
end
|
|
135
196
|
end
|
|
136
197
|
end
|
|
137
|
-
|
|
138
|
-
class SMService::Dummy
|
|
139
|
-
include SMService
|
|
140
|
-
|
|
141
|
-
def initialize
|
|
142
|
-
super name: 'dummy-ruby'
|
|
143
|
-
end
|
|
144
|
-
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: SMService
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrius Kairiukstis
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-11-
|
|
11
|
+
date: 2017-11-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: logger
|
|
@@ -66,6 +66,20 @@ dependencies:
|
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '1.16'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: pry
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0.11'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0.11'
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
84
|
name: rake
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -112,11 +126,14 @@ files:
|
|
|
112
126
|
- LICENSE.txt
|
|
113
127
|
- README.md
|
|
114
128
|
- Rakefile
|
|
129
|
+
- SMService.gemspec
|
|
115
130
|
- bin/console
|
|
116
131
|
- bin/setup
|
|
132
|
+
- docker-compose.yml
|
|
133
|
+
- docker.sh
|
|
134
|
+
- examples/dummy.rb
|
|
117
135
|
- lib/smservice.rb
|
|
118
136
|
- lib/smservice/version.rb
|
|
119
|
-
- smservice.gemspec
|
|
120
137
|
homepage: https://github.com/andrius/smservice
|
|
121
138
|
licenses:
|
|
122
139
|
- MIT
|