cloudi 1.3.2

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.
Files changed (5) hide show
  1. data.tar.gz.sig +1 -0
  2. data/README.markdown +7 -0
  3. data/lib/cloudi.rb +668 -0
  4. metadata +117 -0
  5. metadata.gz.sig +0 -0
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ 1LȅsH����?/�"E1�3#������{v������]x=���[��|�N��[��YI�9c���s��`9)O�� kc���5p>����W*�g6����i��1C�1�90-�/����e�1�dk28�"b2�o"��&g9�:�u$�@$��I�U��exW4�����=�F���s��<�=f�=%�����>��Ct�'�@һ4}�:�V_��B�A���ll�B8��_��_��:��c�:�Q
data/README.markdown ADDED
@@ -0,0 +1,7 @@
1
+ `cloudi_api_ruby`
2
+ =================
3
+
4
+ [![Build Status](https://travis-ci.org/CloudI/cloudi_api_ruby.png)](https://travis-ci.org/CloudI/cloudi_api_ruby)
5
+
6
+ Ruby [CloudI API](http://cloudi.org/api.html#1_Intro)
7
+
data/lib/cloudi.rb ADDED
@@ -0,0 +1,668 @@
1
+ #!/usr/bin/env ruby
2
+ #-*-Mode:ruby;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*-
3
+ # ex: set ft=ruby fenc=utf-8 sts=4 ts=4 sw=4 et:
4
+ #
5
+ # BSD LICENSE
6
+ #
7
+ # Copyright (c) 2011-2014, Michael Truog <mjtruog at gmail dot com>
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright
14
+ # notice, this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright
16
+ # notice, this list of conditions and the following disclaimer in
17
+ # the documentation and/or other materials provided with the
18
+ # distribution.
19
+ # * All advertising materials mentioning features or use of this
20
+ # software must display the following acknowledgment:
21
+ # This product includes software developed by Michael Truog
22
+ # * The name of the author may not be used to endorse or promote
23
+ # products derived from this software without specific prior
24
+ # written permission
25
+ #
26
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
27
+ # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
28
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
31
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
37
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
39
+ # DAMAGE.
40
+ #
41
+
42
+ $:.unshift File.dirname(__FILE__)
43
+
44
+ $stdout.sync = true
45
+ $stderr.sync = true
46
+
47
+ require 'erlang'
48
+
49
+ module CloudI
50
+ class API
51
+ include Erlang
52
+ # unbuffered output is with $stderr.puts '...'
53
+
54
+ ASYNC = 1
55
+ SYNC = -1
56
+
57
+ def initialize(thread_index)
58
+ protocol = API.getenv('CLOUDI_API_INIT_PROTOCOL')
59
+ buffer_size_str = API.getenv('CLOUDI_API_INIT_BUFFER_SIZE')
60
+ if protocol == 'tcp'
61
+ @s = IO.for_fd(thread_index + 3, File::RDWR, autoclose: false)
62
+ @s.sync = true
63
+ @use_header = true
64
+ elsif protocol == 'udp'
65
+ @s = IO.for_fd(thread_index + 3, File::RDWR, autoclose: false)
66
+ @s.sync = true
67
+ @use_header = false
68
+ elsif protocol == 'local'
69
+ @s = IO.for_fd(thread_index + 3, File::RDWR, autoclose: false)
70
+ @s.sync = true
71
+ @use_header = true
72
+ else
73
+ raise InvalidInputException
74
+ end
75
+ @initialization_complete = false
76
+ @size = buffer_size_str.to_i
77
+ @callbacks = Hash.new
78
+ send(term_to_binary(:init))
79
+ poll_request(false)
80
+ end
81
+
82
+ def self.thread_count
83
+ s = getenv('CLOUDI_API_INIT_THREAD_COUNT')
84
+ s.to_i
85
+ end
86
+
87
+ def subscribe(pattern, function)
88
+ key = @prefix + pattern
89
+ value = @callbacks.fetch(key, nil)
90
+ if value.nil?
91
+ @callbacks[key] = [function]
92
+ else
93
+ value.push(function)
94
+ end
95
+ send(term_to_binary([:subscribe, pattern]))
96
+ end
97
+
98
+ def unsubscribe(pattern)
99
+ key = @prefix + pattern
100
+ value = @callbacks.fetch(key, nil)
101
+ API.assert{value != nil}
102
+ value.shift
103
+ if value.empty?
104
+ @callbacks.delete(key)
105
+ end
106
+ send(term_to_binary([:unsubscribe, pattern]))
107
+ end
108
+
109
+ def send_async(name, request,
110
+ timeout=nil, request_info=nil, priority=nil)
111
+ if timeout.nil?
112
+ timeout = @timeoutAsync
113
+ end
114
+ if request_info.nil?
115
+ request_info = ''
116
+ end
117
+ if priority.nil?
118
+ priority = @priorityDefault
119
+ end
120
+ send(term_to_binary([:send_async, name,
121
+ OtpErlangBinary.new(request_info),
122
+ OtpErlangBinary.new(request),
123
+ timeout, priority]))
124
+ return poll_request(false)
125
+ end
126
+
127
+ def send_sync(name, request,
128
+ timeout=nil, request_info=nil, priority=nil)
129
+ if timeout.nil?
130
+ timeout = @timeoutSync
131
+ end
132
+ if request_info.nil?
133
+ request_info = ''
134
+ end
135
+ if priority.nil?
136
+ priority = @priorityDefault
137
+ end
138
+ send(term_to_binary([:send_sync, name,
139
+ OtpErlangBinary.new(request_info),
140
+ OtpErlangBinary.new(request),
141
+ timeout, priority]))
142
+ return poll_request(false)
143
+ end
144
+
145
+ def mcast_async(name, request,
146
+ timeout=nil, request_info=nil, priority=nil)
147
+ if timeout.nil?
148
+ timeout = @timeoutAsync
149
+ end
150
+ if request_info.nil?
151
+ request_info = ''
152
+ end
153
+ if priority.nil?
154
+ priority = @priorityDefault
155
+ end
156
+ send(term_to_binary([:mcast_async, name,
157
+ OtpErlangBinary.new(request_info),
158
+ OtpErlangBinary.new(request),
159
+ timeout, priority]))
160
+ return poll_request(false)
161
+ end
162
+
163
+ def forward_(command, name, request_info, request,
164
+ timeout, priority, trans_id, pid)
165
+ case command
166
+ when ASYNC
167
+ forward_async(name, request_info, request,
168
+ timeout, priority, trans_id, pid)
169
+ when SYNC
170
+ forward_sync(name, request_info, request,
171
+ timeout, priority, trans_id, pid)
172
+ end
173
+ end
174
+
175
+ def forward_async(name, request_info, request,
176
+ timeout, priority, trans_id, pid)
177
+ if @requestTimeoutAdjustment
178
+ if timeout == @request_timeout
179
+ elapsed = [0,
180
+ ((Time.now - @request_timer) * 1000.0).floor].max
181
+ if elapsed > timeout
182
+ timeout = 0
183
+ else
184
+ timeout -= elapsed
185
+ end
186
+ end
187
+ end
188
+ send(term_to_binary([:forward_async, name,
189
+ OtpErlangBinary.new(request_info),
190
+ OtpErlangBinary.new(request),
191
+ timeout, priority,
192
+ OtpErlangBinary.new(trans_id), pid]))
193
+ raise ForwardAsyncException.new()
194
+ end
195
+
196
+ def forward_sync(name, request_info, request,
197
+ timeout, priority, trans_id, pid)
198
+ if @requestTimeoutAdjustment
199
+ if timeout == @request_timeout
200
+ elapsed = [0,
201
+ ((Time.now - @request_timer) * 1000.0).floor].max
202
+ if elapsed > timeout
203
+ timeout = 0
204
+ else
205
+ timeout -= elapsed
206
+ end
207
+ end
208
+ end
209
+ send(term_to_binary([:forward_sync, name,
210
+ OtpErlangBinary.new(request_info),
211
+ OtpErlangBinary.new(request),
212
+ timeout, priority,
213
+ OtpErlangBinary.new(trans_id), pid]))
214
+ raise ForwardSyncException.new()
215
+ end
216
+
217
+ def return_(command, name, pattern, response_info, response,
218
+ timeout, trans_id, pid)
219
+ case command
220
+ when ASYNC
221
+ return_async(name, pattern, response_info, response,
222
+ timeout, trans_id, pid)
223
+ when SYNC
224
+ return_sync(name, pattern, response_info, response,
225
+ timeout, trans_id, pid)
226
+ end
227
+ end
228
+
229
+ def return_async(name, pattern, response_info, response,
230
+ timeout, trans_id, pid)
231
+ if @requestTimeoutAdjustment
232
+ if timeout == @request_timeout
233
+ elapsed = [0,
234
+ ((Time.now - @request_timer) * 1000.0).floor].max
235
+ if elapsed > timeout
236
+ response_info = ''
237
+ response = ''
238
+ timeout = 0
239
+ else
240
+ timeout -= elapsed
241
+ end
242
+ end
243
+ end
244
+ send(term_to_binary([:return_async, name, pattern,
245
+ OtpErlangBinary.new(response_info),
246
+ OtpErlangBinary.new(response),
247
+ timeout,
248
+ OtpErlangBinary.new(trans_id), pid]))
249
+ raise ReturnAsyncException.new()
250
+ end
251
+
252
+ def return_sync(name, pattern, response_info, response,
253
+ timeout, trans_id, pid)
254
+ if @requestTimeoutAdjustment
255
+ if timeout == @request_timeout
256
+ elapsed = [0,
257
+ ((Time.now - @request_timer) * 1000.0).floor].max
258
+ if elapsed > timeout
259
+ response_info = ''
260
+ response = ''
261
+ timeout = 0
262
+ else
263
+ timeout -= elapsed
264
+ end
265
+ end
266
+ end
267
+ send(term_to_binary([:return_sync, name, pattern,
268
+ OtpErlangBinary.new(response_info),
269
+ OtpErlangBinary.new(response),
270
+ timeout,
271
+ OtpErlangBinary.new(trans_id), pid]))
272
+ raise ReturnSyncException.new()
273
+ end
274
+
275
+ def recv_async(timeout=nil, trans_id=nil, consume=true)
276
+ if timeout.nil?
277
+ timeout = @timeoutSync
278
+ end
279
+ if trans_id.nil?
280
+ trans_id = 0.chr * 16
281
+ end
282
+ send(term_to_binary([:recv_async, timeout,
283
+ OtpErlangBinary.new(trans_id), consume]))
284
+ return poll_request(false)
285
+ end
286
+
287
+ def process_index
288
+ return @processIndex
289
+ end
290
+
291
+ def process_count
292
+ return @processCount
293
+ end
294
+
295
+ def process_count_max
296
+ return @processCountMax
297
+ end
298
+
299
+ def process_count_min
300
+ return @processCountMin
301
+ end
302
+
303
+ def prefix
304
+ return @prefix
305
+ end
306
+
307
+ def timeout_async
308
+ return @timeoutAsync
309
+ end
310
+
311
+ def timeout_sync
312
+ return @timeoutSync
313
+ end
314
+
315
+ def callback(command, name, pattern, request_info, request,
316
+ timeout, priority, trans_id, pid)
317
+ request_time_start = nil
318
+ if @requestTimeoutAdjustment
319
+ @request_timer = Time.now
320
+ @request_timeout = timeout
321
+ end
322
+ function_queue = @callbacks.fetch(pattern, nil)
323
+ API.assert{function_queue != nil}
324
+ function = function_queue.shift
325
+ function_queue.push(function)
326
+ case command
327
+ when MESSAGE_SEND_ASYNC
328
+ begin
329
+ response = function.call(ASYNC, name, pattern,
330
+ request_info, request,
331
+ timeout, priority, trans_id, pid)
332
+ if response.kind_of?(Array)
333
+ API.assert{response.length == 2}
334
+ response_info = response[0]
335
+ response = response[1]
336
+ if not response_info.kind_of?(String)
337
+ response_info = ''
338
+ end
339
+ else
340
+ response_info = ''
341
+ end
342
+ if not response.kind_of?(String)
343
+ response = ''
344
+ end
345
+ rescue ReturnAsyncException
346
+ return
347
+ rescue ForwardAsyncException
348
+ return
349
+ rescue ReturnSyncException => e
350
+ $stderr.puts e.message
351
+ $stderr.puts e.backtrace
352
+ API.assert{false}
353
+ return
354
+ rescue ForwardSyncException => e
355
+ $stderr.puts e.message
356
+ $stderr.puts e.backtrace
357
+ API.assert{false}
358
+ return
359
+ rescue
360
+ $stderr.puts $!.message
361
+ $stderr.puts $!.backtrace
362
+ response_info = ''
363
+ response = ''
364
+ end
365
+ begin
366
+ return_async(name, pattern, response_info, response,
367
+ timeout, trans_id, pid)
368
+ rescue ReturnAsyncException
369
+ end
370
+ when MESSAGE_SEND_SYNC
371
+ begin
372
+ response = function.call(SYNC, name, pattern,
373
+ request_info, request,
374
+ timeout, priority, trans_id, pid)
375
+ if response.kind_of?(Array)
376
+ API.assert{response.length == 2}
377
+ response_info = response[0]
378
+ response = response[1]
379
+ if not response_info.kind_of?(String)
380
+ response_info = ''
381
+ end
382
+ else
383
+ response_info = ''
384
+ end
385
+ if not response.kind_of?(String)
386
+ response = ''
387
+ end
388
+ rescue ReturnSyncException
389
+ return
390
+ rescue ForwardSyncException
391
+ return
392
+ rescue ReturnAsyncException => e
393
+ $stderr.puts e.message
394
+ $stderr.puts e.backtrace
395
+ API.assert{false}
396
+ return
397
+ rescue ForwardAsyncException => e
398
+ $stderr.puts e.message
399
+ $stderr.puts e.backtrace
400
+ API.assert{false}
401
+ return
402
+ rescue
403
+ $stderr.puts $!.message
404
+ $stderr.puts $!.backtrace
405
+ response_info = ''
406
+ response = ''
407
+ end
408
+ begin
409
+ return_sync(name, pattern, response_info, response,
410
+ timeout, trans_id, pid)
411
+ rescue ReturnSyncException
412
+ end
413
+ else
414
+ raise MessageDecodingException
415
+ end
416
+ end
417
+
418
+ def poll_request(external)
419
+ if external and not @initialization_complete
420
+ send(term_to_binary(:polling))
421
+ @initialization_complete = true
422
+ end
423
+
424
+ ready = false
425
+ while ready == false
426
+ result = IO.select([@s], nil, [@s])
427
+ if result[2].length > 0
428
+ return nil
429
+ end
430
+ if result[0].length > 0
431
+ ready = true
432
+ end
433
+ end
434
+
435
+ data = recv('')
436
+ if data.bytesize == 0
437
+ return nil
438
+ end
439
+
440
+ loop do
441
+ i = 0; j = 4
442
+ command = data[i, j].unpack('L')[0]
443
+ case command
444
+ when MESSAGE_INIT
445
+ i += j; j = 4 + 4 + 4 + 4 + 4
446
+ tmp = data[i, j].unpack('LLLLL')
447
+ @processIndex = tmp[0]
448
+ @processCount = tmp[1]
449
+ @processCountMax = tmp[2]
450
+ @processCountMin = tmp[3]
451
+ prefixSize = tmp[4]
452
+ i += j; j = prefixSize + 4 + 4 + 1 + 1
453
+ tmp = data[i, j].unpack("Z#{prefixSize}LLcC")
454
+ @prefix = tmp[0]
455
+ @timeoutAsync = tmp[1]
456
+ @timeoutSync = tmp[2]
457
+ @priorityDefault = tmp[3]
458
+ @requestTimeoutAdjustment = (tmp[4] != 0)
459
+ i += j
460
+ if i != data.length
461
+ raise MessageDecodingException
462
+ end
463
+ return
464
+ when MESSAGE_SEND_ASYNC, MESSAGE_SEND_SYNC
465
+ i += j; j = 4
466
+ nameSize = data[i, j].unpack('L')[0]
467
+ i += j; j = nameSize + 4
468
+ tmp = data[i, j].unpack("Z#{nameSize}L")
469
+ name = tmp[0]
470
+ patternSize = tmp[1]
471
+ i += j; j = patternSize + 4
472
+ tmp = data[i, j].unpack("Z#{patternSize}L")
473
+ pattern = tmp[0]
474
+ requestInfoSize = tmp[1]
475
+ i += j; j = requestInfoSize + 1 + 4
476
+ tmp = data[i, j].unpack("a#{requestInfoSize}xL")
477
+ request_info = tmp[0]
478
+ requestSize = tmp[1]
479
+ i += j; j = requestSize + 1 + 4 + 1 + 16 + 4
480
+ tmp = data[i, j].unpack("a#{requestSize}xLca16L")
481
+ request = tmp[0]
482
+ timeout = tmp[1]
483
+ priority = tmp[2]
484
+ trans_id = tmp[3]
485
+ pidSize = tmp[4]
486
+ i += j; j = pidSize
487
+ pid = data[i, j].unpack("a#{pidSize}")[0]
488
+ i += j
489
+ if i != data.length
490
+ raise MessageDecodingException
491
+ end
492
+ data.clear()
493
+ callback(command, name, pattern, request_info, request,
494
+ timeout, priority, trans_id, binary_to_term(pid))
495
+ when MESSAGE_RECV_ASYNC, MESSAGE_RETURN_SYNC
496
+ i += j; j = 4
497
+ responseInfoSize = data[i, j].unpack('L')[0]
498
+ i += j; j = responseInfoSize + 1 + 4
499
+ tmp = data[i, j].unpack("a#{responseInfoSize}xL")
500
+ response_info = tmp[0]
501
+ responseSize = tmp[1]
502
+ i += j; j = responseSize + 1 + 16
503
+ tmp = data[i, j].unpack("a#{responseSize}xa16")
504
+ response = tmp[0]
505
+ trans_id = tmp[1]
506
+ i += j
507
+ if i != data.length
508
+ raise MessageDecodingException
509
+ end
510
+ return [response_info, response, trans_id]
511
+ when MESSAGE_RETURN_ASYNC
512
+ i += j; j = 16
513
+ trans_id = data[i, j].unpack('a16')[0]
514
+ i += j
515
+ if i != data.length
516
+ raise MessageDecodingException
517
+ end
518
+ return trans_id
519
+ when MESSAGE_RETURNS_ASYNC
520
+ i += j; j = 4
521
+ transIdCount = data[i, j].unpack('L')[0]
522
+ i += j; j = 16 * transIdCount
523
+ transIdList = data[i, j].unpack('a16' * transIdCount)
524
+ i += j
525
+ if i != data.length
526
+ raise MessageDecodingException
527
+ end
528
+ return transIdList
529
+ when MESSAGE_KEEPALIVE
530
+ send(term_to_binary(:keepalive))
531
+ i += j
532
+ if i < data.length
533
+ raise MessageDecodingException
534
+ end
535
+ data.slice!(0, i)
536
+ if data.length > 0
537
+ if IO.select([@s], nil, nil, 0).nil?
538
+ next
539
+ end
540
+ end
541
+ else
542
+ raise MessageDecodingException
543
+ end
544
+
545
+ ready = false
546
+ while ready == false
547
+ result = IO.select([@s], nil, [@s])
548
+ if result[2].length > 0
549
+ return nil
550
+ end
551
+ if result[0].length > 0
552
+ ready = true
553
+ end
554
+ end
555
+
556
+ data = recv(data)
557
+ if data.bytesize == 0
558
+ return nil
559
+ end
560
+ end
561
+ end
562
+
563
+ def poll
564
+ poll_request(true)
565
+ end
566
+
567
+ def binary_key_value_parse(binary)
568
+ result = {}
569
+ data = binary.split(NULL.chr)
570
+ (0...(data.length)).step(2).each do |i|
571
+ value = result[data[i]]
572
+ if value == nil
573
+ result[data[i]] = data[i + 1]
574
+ elsif value.kind_of?(Array)
575
+ value << data[i + 1]
576
+ else
577
+ result[data[i]] = [value, data[i + 1]]
578
+ end
579
+ end
580
+ result
581
+ end
582
+
583
+ def request_http_qs_parse(request)
584
+ binary_key_value_parse(request)
585
+ end
586
+
587
+ def info_key_value_parse(message_info)
588
+ binary_key_value_parse(message_info)
589
+ end
590
+
591
+ def self.assert
592
+ raise 'Assertion failed !' unless yield # if $DEBUG
593
+ end
594
+
595
+ private :callback
596
+ private :poll_request
597
+ private :binary_key_value_parse
598
+ private
599
+
600
+ def send(data)
601
+ if @use_header
602
+ data = [data.length].pack('N') + data
603
+ end
604
+ @s.write(data)
605
+ end
606
+
607
+ def recv(data)
608
+ if @use_header
609
+ while data.length < 4
610
+ fragment = @s.readpartial(@size)
611
+ data += fragment
612
+ end
613
+ total = data[0,4].unpack('N')[0]
614
+ data.slice!(0..3)
615
+ while data.length < total
616
+ fragment = @s.readpartial(@size)
617
+ data += fragment
618
+ end
619
+ else
620
+ ready = true
621
+ while ready == true
622
+ fragment = @s.readpartial(@size)
623
+ data += fragment
624
+ ready = (fragment.bytesize == @size)
625
+
626
+ if ready
627
+ ready = ! IO.select([@s], nil, nil, 0).nil?
628
+ end
629
+ end
630
+ end
631
+ data
632
+ end
633
+
634
+ MESSAGE_INIT = 1
635
+ MESSAGE_SEND_ASYNC = 2
636
+ MESSAGE_SEND_SYNC = 3
637
+ MESSAGE_RECV_ASYNC = 4
638
+ MESSAGE_RETURN_ASYNC = 5
639
+ MESSAGE_RETURN_SYNC = 6
640
+ MESSAGE_RETURNS_ASYNC = 7
641
+ MESSAGE_KEEPALIVE = 8
642
+
643
+ NULL = 0
644
+
645
+ def self.getenv(key)
646
+ ENV[key] or raise InvalidInputException
647
+ end
648
+ end
649
+
650
+ class InvalidInputException < Exception
651
+ end
652
+
653
+ class ReturnSyncException < Exception
654
+ end
655
+
656
+ class ReturnAsyncException < Exception
657
+ end
658
+
659
+ class ForwardSyncException < Exception
660
+ end
661
+
662
+ class ForwardAsyncException < Exception
663
+ end
664
+
665
+ class MessageDecodingException < Exception
666
+ end
667
+ end
668
+
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cloudi
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Truog
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ - ! '-----BEGIN CERTIFICATE-----
13
+
14
+ MIIDMDCCAhigAwIBAgIBADANBgkqhkiG9w0BAQUFADA+MRAwDgYDVQQDDAdtanRy
15
+
16
+ dW9nMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
17
+
18
+ HhcNMTQwNjI0MjAzMDQ2WhcNMTUwNjI0MjAzMDQ2WjA+MRAwDgYDVQQDDAdtanRy
19
+
20
+ dW9nMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
21
+
22
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBOoI/CUuwOhXjks02cT58
23
+
24
+ jLxgsOQ412Xzu4eEKqzNsWMoj/3+qYdb5CR4+51EHtuJHZ8hndL5DTYIO8ylcG11
25
+
26
+ EvyxqOzU+gqC53gCEBhJLivlyMXvGqL8qHPuSKGEMc1Vpzh0WicwNnaT7z3X6aQP
27
+
28
+ UE6qWd1yE9jT7TX+GKcKayBJTufxcBMjtwvzMH4IiVaNjUBHBq2LbeNO1yDPYVzV
29
+
30
+ HWnZCv75vIXdUruFrSZcJgNRYRwzMfHEbf+BcvqqGVV6p3PJgJMrjI8FZ7roIJNf
31
+
32
+ D7ZO96x4ItjGazoTntAZe3EM9QB5Wjsd1cv2IEOISQ6jyvVX5E84Al+MEKhhhFuL
33
+
34
+ AgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFACw0UcBaNl2dQWwgg/Qzeyf
35
+
36
+ cKG7MAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAHjLn+8F8yeOFcKst
37
+
38
+ mKA3m28OIoICMefZOiJfTC9UkVkW+554IXNBu3vVxLc0nlCqmuf/aQGaFBUm9MLA
39
+
40
+ oD5CmlrU9OrEl2fPxqTHAwFgLNre8e2EWtm2OhBg73JTHRVVyBLpSK5GRUDzhJtZ
41
+
42
+ 7a2ocAE2AgFKpISNxIUe4Zz9O2thg3iryLh9prjETJTUfxDjBmHdx+YkNAblRa2w
43
+
44
+ k9A+nCZzZECcR5ZZYSeaK6MCugGmXUhAkDbuWumCzu/RAghlVC9RFFQt7o1SwGQp
45
+
46
+ LdvYOeJbviyiH1q1rC3NAJNC4P7Q41zx1OYa8S9M5qn+JpE0ZsomnZyGunWaya9Q
47
+
48
+ bTD/aw==
49
+
50
+ -----END CERTIFICATE-----
51
+
52
+ '
53
+ date: 2014-06-24 00:00:00.000000000 Z
54
+ dependencies:
55
+ - !ruby/object:Gem::Dependency
56
+ name: erlang_rb
57
+ requirement: &11610740 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: '1.3'
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 1.3.2
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *11610740
69
+ - !ruby/object:Gem::Dependency
70
+ name: erlang_rb
71
+ requirement: &11608600 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: '1.3'
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: 1.3.2
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: *11608600
83
+ description: Ruby CloudI API
84
+ email: mjtruog@gmail.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files:
88
+ - README.markdown
89
+ files:
90
+ - lib/cloudi.rb
91
+ - README.markdown
92
+ homepage: http://cloudi.org
93
+ licenses:
94
+ - BSD
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 1.8.11
114
+ signing_key:
115
+ specification_version: 3
116
+ summary: CloudI API
117
+ test_files: []
metadata.gz.sig ADDED
Binary file