pomelo-citrus-admin 0.0.1
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 +7 -0
- data/README.md +20 -0
- data/Rakefile +0 -0
- data/citrus-admin.gemspec +34 -0
- data/lib/citrus-admin.rb +21 -0
- data/lib/citrus-admin/client/client.rb +142 -0
- data/lib/citrus-admin/console_service.rb +374 -0
- data/lib/citrus-admin/master_agent.rb +607 -0
- data/lib/citrus-admin/modules/console_module.rb +35 -0
- data/lib/citrus-admin/modules/monitor_log.rb +45 -0
- data/lib/citrus-admin/modules/process_info.rb +45 -0
- data/lib/citrus-admin/modules/system_info.rb +45 -0
- data/lib/citrus-admin/modules/watch_server.rb +45 -0
- data/lib/citrus-admin/monitor_agent.rb +166 -0
- data/lib/citrus-admin/util/protocol.rb +83 -0
- data/lib/citrus-admin/util/utils.rb +63 -0
- data/lib/citrus-admin/version.rb +7 -0
- data/spec/agent_spec.rb +424 -0
- data/spec/console_service_spec.rb +246 -0
- data/spec/spec_helper.rb +18 -0
- metadata +178 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 8 July 2014
|
4
|
+
|
5
|
+
module CitrusAdmin
|
6
|
+
# Utils
|
7
|
+
#
|
8
|
+
#
|
9
|
+
module Utils
|
10
|
+
#
|
11
|
+
#
|
12
|
+
#
|
13
|
+
def df_auth_user msg, env, &block
|
14
|
+
block_given? and yield nil
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
#
|
19
|
+
#
|
20
|
+
def df_auth_server_master msg, env, &block
|
21
|
+
block_given? and yield 'ok'
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
#
|
26
|
+
#
|
27
|
+
def df_auth_server_monitor msg, env, &block
|
28
|
+
block_given? and yield nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# EventEmitter
|
32
|
+
#
|
33
|
+
#
|
34
|
+
module EventEmitter
|
35
|
+
# Register event
|
36
|
+
#
|
37
|
+
# @param [String] event
|
38
|
+
def on event, &block
|
39
|
+
@on_blocks ||= {}
|
40
|
+
@on_blocks[event] = block
|
41
|
+
end
|
42
|
+
|
43
|
+
# Register event once
|
44
|
+
#
|
45
|
+
# @param [String] event
|
46
|
+
def once event, &block
|
47
|
+
@once_blocks ||= {}
|
48
|
+
@once_blocks[event] = block
|
49
|
+
end
|
50
|
+
|
51
|
+
# Emit event
|
52
|
+
def emit *args
|
53
|
+
event = args.shift
|
54
|
+
if @once_blocks && block = @once_blocks[event]
|
55
|
+
@once_blocks.delete event
|
56
|
+
elsif !@on_blocks || !block = @on_blocks[event]
|
57
|
+
return
|
58
|
+
end
|
59
|
+
block.call *args
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/spec/agent_spec.rb
ADDED
@@ -0,0 +1,424 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 13 July 2014
|
4
|
+
|
5
|
+
require File.expand_path('../spec_helper', __FILE__)
|
6
|
+
|
7
|
+
describe 'agent' do
|
8
|
+
|
9
|
+
master_host = '127.0.0.1'
|
10
|
+
master_port = 3333
|
11
|
+
|
12
|
+
MockConsoleService = Class.new {
|
13
|
+
include RSpec::Matchers
|
14
|
+
|
15
|
+
attr_reader :env, :auth_server
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@env = nil
|
19
|
+
@auth_server = Proc.new { |msg, env, &block|
|
20
|
+
block.call 'ok'
|
21
|
+
}
|
22
|
+
end
|
23
|
+
}
|
24
|
+
|
25
|
+
it 'should emit an error when listening on a port in use' do
|
26
|
+
error_count = 0
|
27
|
+
port = 80
|
28
|
+
|
29
|
+
master = MasterAgent.new
|
30
|
+
master.on('error') { |err|
|
31
|
+
expect(err).to be
|
32
|
+
error_count += 1
|
33
|
+
}
|
34
|
+
|
35
|
+
EM.run {
|
36
|
+
master.listen port
|
37
|
+
expect(error_count).to eql 1
|
38
|
+
|
39
|
+
EM.add_timer(0.1) {
|
40
|
+
EM.stop_event_loop
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should emit an error when connecting to an invalid address' do
|
46
|
+
error_count = 0
|
47
|
+
host = 'localhost'
|
48
|
+
port = -80
|
49
|
+
|
50
|
+
monitor = MonitorAgent.new
|
51
|
+
|
52
|
+
EM.run {
|
53
|
+
monitor.connect(port, host) { |err|
|
54
|
+
expect(err).to be
|
55
|
+
error_count += 1
|
56
|
+
}
|
57
|
+
|
58
|
+
EM.add_timer(0.1) {
|
59
|
+
expect(error_count).to eql 1
|
60
|
+
EM.stop_event_loop
|
61
|
+
}
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should send the request from master to the right monitor and get the response from callback by request' do
|
66
|
+
monitor_id1 = 'connector-server-1'
|
67
|
+
monitor_id2 = 'area-server-1'
|
68
|
+
monitor_type1 = 'connector'
|
69
|
+
monitor_type2 = 'area'
|
70
|
+
module_id1 = 'module-1'
|
71
|
+
module_id2 = 'module-2'
|
72
|
+
msg1 = { :msg => 'message to monitor1' }
|
73
|
+
msg2 = { :msg => 'message to monitor2' }
|
74
|
+
|
75
|
+
req1_count = 0
|
76
|
+
req2_count = 0
|
77
|
+
resp1_count = 0
|
78
|
+
resp2_count = 0
|
79
|
+
|
80
|
+
master = MasterAgent.new :console_service => MockConsoleService.new
|
81
|
+
|
82
|
+
monitor_console1 = MockConsoleService.new
|
83
|
+
monitor_console2 = MockConsoleService.new
|
84
|
+
|
85
|
+
monitor_console1.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
86
|
+
req1_count += 1
|
87
|
+
expect(module_id).to eql module_id1
|
88
|
+
block.call nil, msg
|
89
|
+
}
|
90
|
+
monitor_console2.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
91
|
+
req2_count += 1
|
92
|
+
expect(module_id).to eql module_id2
|
93
|
+
block.call nil, msg
|
94
|
+
}
|
95
|
+
|
96
|
+
monitor1 = MonitorAgent.new({
|
97
|
+
:console_service => monitor_console1,
|
98
|
+
:server_id => monitor_id1,
|
99
|
+
:server_type => monitor_type1
|
100
|
+
})
|
101
|
+
monitor2 = MonitorAgent.new({
|
102
|
+
:console_service => monitor_console2,
|
103
|
+
:server_id => monitor_id2,
|
104
|
+
:server_type => monitor_type2
|
105
|
+
})
|
106
|
+
|
107
|
+
EM.run {
|
108
|
+
master.listen master_port
|
109
|
+
|
110
|
+
monitor1.connect(master_port, master_host) { |err|
|
111
|
+
expect(err).to be_nil
|
112
|
+
master.request monitor_id1, module_id1, msg1, proc{ |err, resp|
|
113
|
+
resp1_count += 1
|
114
|
+
expect(err).to be_nil
|
115
|
+
expect(resp).to eql msg1
|
116
|
+
}
|
117
|
+
}
|
118
|
+
monitor2.connect(master_port, master_host) { |err|
|
119
|
+
expect(err).to be_nil
|
120
|
+
master.request monitor_id2, module_id2, msg2, proc{ |err, resp|
|
121
|
+
resp2_count += 1
|
122
|
+
expect(err).to be_nil
|
123
|
+
expect(resp).to eql msg2
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
EM.add_timer(0.1) {
|
128
|
+
expect(req1_count).to eql 1
|
129
|
+
expect(req2_count).to eql 1
|
130
|
+
expect(resp1_count).to eql 1
|
131
|
+
expect(resp2_count).to eql 1
|
132
|
+
EM.stop_event_loop
|
133
|
+
}
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should send back an error to master if monitor callback with an error' do
|
138
|
+
monitor_id = 'connector-server-1'
|
139
|
+
monitor_type = 'connector'
|
140
|
+
module_id = 'module-1'
|
141
|
+
msg = { msg => 'message to monitor' }
|
142
|
+
err_msg = 'some error message from monitor'
|
143
|
+
|
144
|
+
req_count = 0
|
145
|
+
resp_count = 0
|
146
|
+
|
147
|
+
master = MasterAgent.new :console_service => MockConsoleService.new
|
148
|
+
|
149
|
+
monitor_console = MockConsoleService.new
|
150
|
+
monitor_console.define_singleton_method :execute, proc{ |inner_module_id, method, msg, &block|
|
151
|
+
req_count += 1
|
152
|
+
expect(inner_module_id).to eql module_id
|
153
|
+
block.call Exception.new err_msg
|
154
|
+
}
|
155
|
+
|
156
|
+
monitor = MonitorAgent.new({
|
157
|
+
:console_service => monitor_console,
|
158
|
+
:server_id => monitor_id,
|
159
|
+
:server_type => monitor_type
|
160
|
+
})
|
161
|
+
|
162
|
+
EM.run {
|
163
|
+
master.listen master_port
|
164
|
+
|
165
|
+
monitor.connect(master_port, master_host) { |err|
|
166
|
+
expect(err).to be_nil
|
167
|
+
master.request monitor_id, module_id, msg, proc{ |err, resp|
|
168
|
+
resp_count += 1
|
169
|
+
expect(err).to be
|
170
|
+
expect(err[:msg]).to eql err_msg
|
171
|
+
expect(resp).to be_nil
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
EM.add_timer(0.1) {
|
176
|
+
expect(req_count).to eql 1
|
177
|
+
expect(resp_count).to eql 1
|
178
|
+
EM.stop_event_loop
|
179
|
+
}
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should send the message from master to the right monitor by notify' do
|
184
|
+
monitor_id1 = 'connector-server-1'
|
185
|
+
monitor_id2 = 'area-server-1'
|
186
|
+
monitor_type1 = 'connector'
|
187
|
+
monitor_type2 = 'area'
|
188
|
+
module_id1 = 'module-1'
|
189
|
+
module_id2 = 'module-2'
|
190
|
+
msg1 = { :msg => 'message to monitor1' }
|
191
|
+
msg2 = { :msg => 'message to server1' }
|
192
|
+
|
193
|
+
req1_count = 0
|
194
|
+
req2_count = 0
|
195
|
+
|
196
|
+
master = MasterAgent.new :console_service => MockConsoleService.new
|
197
|
+
|
198
|
+
monitor_console1 = MockConsoleService.new
|
199
|
+
monitor_console2 = MockConsoleService.new
|
200
|
+
|
201
|
+
monitor_console1.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
202
|
+
req1_count += 1
|
203
|
+
expect(module_id).to eql module_id1
|
204
|
+
}
|
205
|
+
monitor_console2.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
206
|
+
req2_count += 1
|
207
|
+
expect(module_id).to eql module_id2
|
208
|
+
}
|
209
|
+
|
210
|
+
monitor1 = MonitorAgent.new({
|
211
|
+
:console_service => monitor_console1,
|
212
|
+
:server_id => monitor_id1,
|
213
|
+
:server_type => monitor_type1
|
214
|
+
})
|
215
|
+
monitor2 = MonitorAgent.new({
|
216
|
+
:console_service => monitor_console2,
|
217
|
+
:server_id => monitor_id2,
|
218
|
+
:server_type => monitor_type2
|
219
|
+
})
|
220
|
+
|
221
|
+
EM.run {
|
222
|
+
master.listen master_port
|
223
|
+
|
224
|
+
monitor1.connect(master_port, master_host) { |err|
|
225
|
+
expect(err).to be_nil
|
226
|
+
master.notify monitor_id1, module_id1, msg1
|
227
|
+
}
|
228
|
+
monitor2.connect(master_port, master_host) { |err|
|
229
|
+
expect(err).to be_nil
|
230
|
+
master.notify monitor_id2, module_id2, msg2
|
231
|
+
}
|
232
|
+
|
233
|
+
EM.add_timer(0.1) {
|
234
|
+
expect(req1_count).to eql 1
|
235
|
+
expect(req2_count).to eql 1
|
236
|
+
EM.stop_event_loop
|
237
|
+
}
|
238
|
+
}
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'should send the message from master to the right monitor by notify_by_server_type' do
|
242
|
+
monitor_id1 = 'connector-server-1'
|
243
|
+
monitor_id2 = 'connector-server-2'
|
244
|
+
monitor_id3 = 'area-server-1'
|
245
|
+
monitor_type1 = 'connector'
|
246
|
+
monitor_type2 = 'area'
|
247
|
+
module_id1 = 'module-1'
|
248
|
+
module_id2 = 'module-2'
|
249
|
+
msg1 = { :msg => 'message to monitor_type1' }
|
250
|
+
msg2 = { :msg => 'message to monitor_type2' }
|
251
|
+
|
252
|
+
req1_count = 0
|
253
|
+
req2_count = 0
|
254
|
+
req3_count = 0
|
255
|
+
req_type1_count = 0
|
256
|
+
req_type2_count = 0
|
257
|
+
|
258
|
+
master = MasterAgent.new :console_service => MockConsoleService.new
|
259
|
+
|
260
|
+
monitor_console1 = MockConsoleService.new
|
261
|
+
monitor_console2 = MockConsoleService.new
|
262
|
+
monitor_console3 = MockConsoleService.new
|
263
|
+
|
264
|
+
monitor_console1.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
265
|
+
req1_count += 1
|
266
|
+
req_type1_count += 1
|
267
|
+
expect(module_id).to eql module_id1
|
268
|
+
expect(msg).to eql msg1
|
269
|
+
}
|
270
|
+
monitor_console2.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
271
|
+
req2_count += 1
|
272
|
+
req_type1_count += 1
|
273
|
+
expect(module_id).to eql module_id1
|
274
|
+
expect(msg).to eql msg1
|
275
|
+
}
|
276
|
+
monitor_console3.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
277
|
+
req3_count += 1
|
278
|
+
req_type2_count += 1
|
279
|
+
expect(module_id).to eql module_id2
|
280
|
+
expect(msg).to eql msg2
|
281
|
+
}
|
282
|
+
|
283
|
+
monitor1 = MonitorAgent.new({
|
284
|
+
:console_service => monitor_console1,
|
285
|
+
:server_id => monitor_id1,
|
286
|
+
:server_type => monitor_type1
|
287
|
+
})
|
288
|
+
monitor2 = MonitorAgent.new({
|
289
|
+
:console_service => monitor_console2,
|
290
|
+
:server_id => monitor_id2,
|
291
|
+
:server_type => monitor_type1
|
292
|
+
})
|
293
|
+
monitor3 = MonitorAgent.new({
|
294
|
+
:console_service => monitor_console3,
|
295
|
+
:server_id => monitor_id3,
|
296
|
+
:server_type => monitor_type2
|
297
|
+
})
|
298
|
+
|
299
|
+
EM.run {
|
300
|
+
master.listen master_port
|
301
|
+
|
302
|
+
monitor1.connect(master_port, master_host) { |err|
|
303
|
+
expect(err).to be_nil
|
304
|
+
}
|
305
|
+
monitor2.connect(master_port, master_host) { |err|
|
306
|
+
expect(err).to be_nil
|
307
|
+
}
|
308
|
+
monitor3.connect(master_port, master_host) { |err|
|
309
|
+
expect(err).to be_nil
|
310
|
+
}
|
311
|
+
|
312
|
+
EM.add_timer(0.1) {
|
313
|
+
master.notify_by_server_type monitor_type1, module_id1, msg1
|
314
|
+
master.notify_by_server_type monitor_type2, module_id2, msg2
|
315
|
+
}
|
316
|
+
|
317
|
+
EM.add_timer(0.2) {
|
318
|
+
expect(req1_count).to eql 1
|
319
|
+
expect(req2_count).to eql 1
|
320
|
+
expect(req3_count).to eql 1
|
321
|
+
expect(req_type1_count).to eql 2
|
322
|
+
expect(req_type2_count).to eql 1
|
323
|
+
EM.stop_event_loop
|
324
|
+
}
|
325
|
+
}
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'should send the message from master to all the monitors by broadcast_notify' do
|
329
|
+
monitor_id1 = 'connector-server-1'
|
330
|
+
monitor_id2 = 'area-server-1'
|
331
|
+
monitor_type1 = 'connector'
|
332
|
+
monitor_type2 = 'area'
|
333
|
+
org_module_id = 'module-1'
|
334
|
+
org_msg = { :msg => 'message to all' }
|
335
|
+
|
336
|
+
req1_count = 0
|
337
|
+
req2_count = 0
|
338
|
+
|
339
|
+
master = MasterAgent.new :console_service => MockConsoleService.new
|
340
|
+
|
341
|
+
monitor_console1 = MockConsoleService.new
|
342
|
+
monitor_console2 = MockConsoleService.new
|
343
|
+
|
344
|
+
monitor_console1.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
345
|
+
req1_count += 1
|
346
|
+
expect(module_id).to eql org_module_id
|
347
|
+
expect(msg).to eql org_msg
|
348
|
+
}
|
349
|
+
monitor_console2.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
350
|
+
req2_count += 1
|
351
|
+
expect(module_id).to eql org_module_id
|
352
|
+
expect(msg).to eql org_msg
|
353
|
+
}
|
354
|
+
|
355
|
+
monitor1 = MonitorAgent.new({
|
356
|
+
:console_service => monitor_console1,
|
357
|
+
:server_id => monitor_id1,
|
358
|
+
:server_type => monitor_type1
|
359
|
+
})
|
360
|
+
monitor2 = MonitorAgent.new({
|
361
|
+
:console_service => monitor_console2,
|
362
|
+
:server_id => monitor_id2,
|
363
|
+
:server_type => monitor_type1
|
364
|
+
})
|
365
|
+
|
366
|
+
EM.run {
|
367
|
+
master.listen master_port
|
368
|
+
|
369
|
+
monitor1.connect(master_port, master_host) { |err|
|
370
|
+
expect(err).to be_nil
|
371
|
+
}
|
372
|
+
monitor2.connect(master_port, master_host) { |err|
|
373
|
+
expect(err).to be_nil
|
374
|
+
}
|
375
|
+
|
376
|
+
EM.add_timer(0.1) {
|
377
|
+
master.broadcast_notify org_module_id, org_msg
|
378
|
+
}
|
379
|
+
|
380
|
+
EM.add_timer(0.2) {
|
381
|
+
expect(req1_count).to eql 1
|
382
|
+
expect(req2_count).to eql 1
|
383
|
+
EM.stop_event_loop
|
384
|
+
}
|
385
|
+
}
|
386
|
+
end
|
387
|
+
|
388
|
+
it 'should push the message from monitor to master by notify' do
|
389
|
+
monitor_id = 'connector-server-1'
|
390
|
+
monitor_type = 'connector'
|
391
|
+
org_module_id = 'module-1'
|
392
|
+
org_msg = 'message to master'
|
393
|
+
|
394
|
+
req_count = 0
|
395
|
+
|
396
|
+
master_console = MockConsoleService.new
|
397
|
+
master_console.define_singleton_method :execute, proc{ |module_id, method, msg, &block|
|
398
|
+
req_count += 1
|
399
|
+
expect(module_id).to eql org_module_id
|
400
|
+
expect(msg).to eql org_msg
|
401
|
+
}
|
402
|
+
|
403
|
+
master = MasterAgent.new :console_service => master_console
|
404
|
+
monitor = MonitorAgent.new({
|
405
|
+
:console_service => MockConsoleService.new,
|
406
|
+
:server_id => monitor_id,
|
407
|
+
:server_type => monitor_type
|
408
|
+
})
|
409
|
+
|
410
|
+
EM.run {
|
411
|
+
master.listen master_port
|
412
|
+
|
413
|
+
monitor.connect(master_port, master_host) { |err|
|
414
|
+
expect(err).to be_nil
|
415
|
+
monitor.notify org_module_id, org_msg
|
416
|
+
}
|
417
|
+
|
418
|
+
EM.add_timer(0.1) {
|
419
|
+
expect(req_count).to eql 1
|
420
|
+
EM.stop_event_loop
|
421
|
+
}
|
422
|
+
}
|
423
|
+
end
|
424
|
+
end
|