rbkubemq 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1465b9f1b680dbfed9cd00005a31d0f41744cdb9054e25a9d173b1a8a90e9e3c
4
+ data.tar.gz: ef45fd425d388d4147f6d16d03f078e8ca32840b7e0f0eaae108170cdc96ab0b
5
+ SHA512:
6
+ metadata.gz: 1f906a81a3a80b0f6df9f9c3801c0e9ebcb31828352c14d642ed27fd48ba684f65823eee0cf6f32a3b3795e5f3b806f9d80370b218c51f379929091b5a965c43
7
+ data.tar.gz: 8de80c39260cf3a81487d73e5c99ef9f667815feef7722bcdc4f4fffd689504c2c2d5325639fe32ce0ba9c63cba52fa803820de6b5846b0a64b75a1b9b9d90e3
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+
2
+ source "https://rubygems.org"
3
+
4
+ gem "httparty", "~>0.16.4"
5
+ gem "oj", "~>3.7.11"
6
+ gem "faye-websocket", "~>0.10.7"
7
+
8
+ group :development, :test do
9
+ gem "rspec"
10
+ gem "pry-byebug"
11
+ gem "eventmachine"
12
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Seluxit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/RBKubeMQ.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # lib = File.expand_path('../lib', __FILE__)
2
+ # $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "rake"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'rbkubemq'
7
+ s.version = '0.0.1'
8
+ s.authors = ['Stefano Martin']
9
+ s.email = ['stefano@seluxit.com']
10
+ s.homepage = 'https://github.com/StefanoMartin/RBKubeMQ'
11
+ s.license = 'MIT'
12
+ s.summary = 'A simple gem for KubeMQ'
13
+ s.description = "Ruby driver for RBKubeMQ"
14
+ s.platform = Gem::Platform::RUBY
15
+ s.require_paths = ['lib']
16
+ s.files = FileList['lib/**/*', 'RBKubeMQ.gemspec', 'Gemfile', 'LICENSE', 'README.md'].to_a
17
+ s.add_dependency 'httparty', '~> 0.14', '>= 0.14.0'
18
+ s.add_dependency 'oj', '~> 3.6.11', '>= 3.6.11'
19
+ s.add_dependency 'faye-websocket', '~> 0.10.7', '>= 0.10.7'
20
+ end
data/README.md ADDED
@@ -0,0 +1,131 @@
1
+ This is a quick gem created for manage [KubeMQ](https://kubemq.io/) with Ruby.
2
+
3
+ It requires the gems "HTTParty", "Oj" and "faye-websocket".
4
+
5
+ To install ArangoRB: `gem install RBKubeMQ`.
6
+
7
+ To use it in your application: `require rbkubemq`.
8
+
9
+ For examples, look the tests in "/spec/lib/spec_helper"
10
+
11
+ ## Classes used
12
+
13
+ * [RBKubeMQ::Client](#RKMQCLient): to manage a general client
14
+ * [RBKubeMQ::Sender](#RKMQSender): to manage a sender
15
+ * [RBKubeMQ::Streamer](#RKMQStreamer): to create a websocket to send data
16
+ * [RBKubeMQ::Subscriber](#RKMQsubscriber): to create a websocket to receive data
17
+ * [RBKubeMQ::Utility](#RKMQutility): to parse and load easier the data
18
+ * [RBKubeMQ::Error](#RKMQerror): to manage generic error
19
+
20
+ <a name="RKMQCLient"></a>
21
+ ## RBKubeMQ::Client
22
+
23
+ Arango::Server is used to manage a connection with KubeMQ.
24
+
25
+ ``` ruby
26
+ client = RBKubeMQ::Client.new host: "YOUR_HOST", port: "8080", tls: false # tls is true then it will make your requests with https and wss instead of http or ws
27
+ ```
28
+
29
+ <a name="RKMQSender"></a>
30
+ ## RBKubeMQ::Sender
31
+
32
+ Sender it is used to do HTTP requests to KubeMQ. It manage event, request, query and response requests.
33
+
34
+ ``` ruby
35
+ sender = client.sender client_id: "YOUR_CLIENT", channel: "YOUR_CHANNEL",
36
+ meta: nil, store: false, timeout: 1000, cache_key: nil, cache_ttl: nil
37
+ ```
38
+
39
+ The possible request that you can do are the following:
40
+
41
+ ``` ruby
42
+ sender.event("YOUR MESSAGE") # send an event
43
+ sender.request("YOUR MESSAGE") # send a request (we do not expect a body)
44
+ sender.query("YOUR MESSAGE") # send a query (we expect a body)
45
+ sender.response(received_request, message: "YOUR MESSAGE") # send a response to a request (the received request is the one received with a subscriber)
46
+ ```
47
+
48
+ You can overwrite the default values by inserting them as attributes, like this:
49
+
50
+ ``` ruby
51
+ sender.event("YOUR MESSAGE", client_id: "client_id")
52
+ ```
53
+
54
+ Note that client_id, channel are mandatory values that need to be insert either at the initialization or during the request.
55
+
56
+ <a name="RKMQStreamer"></a>
57
+ ## RBKubeMQ::Streamer
58
+
59
+ Streamer it is used to create a stream websocket that it will be used to communicate with the KubeMQ. By using an eventmachine the structure of a streamer can be similar to one of a websocket.
60
+
61
+ ```ruby
62
+ i = 0
63
+ EM.run do
64
+ streamer = client.streamer(client_id: "YOUR_CLIENT", channel: "YOUR_CHANNEL",
65
+ meta: nil, store: false)
66
+ ws = streamer.start # Create a websocket by starting it
67
+
68
+ ws.on :open do |event|
69
+ p [:open]
70
+ end
71
+
72
+ ws.on :message do |event|
73
+ p [:message, RBKubeMQ::Utility.load(event.data)]
74
+ end
75
+
76
+ ws.on :close do |event|
77
+ p [:close]
78
+ ws = nil; EM.stop
79
+ end
80
+
81
+ # Send a message every second
82
+ timer = EM::PeriodicTimer.new(1) do
83
+ i += 1
84
+ puts "SENDING #{i}"
85
+ streamer.send(i, meta: "Stream") # Note that we use streamer and not ws to send the stream
86
+ end
87
+ end
88
+ ```
89
+
90
+ <a name="RKMQSubscriber"></a>
91
+ ## RBKubeMQ::Subscriber
92
+
93
+ Subscriber is liked the streamer but it is used only to subscribe to a client_id and a channel. You can use groups to subdivide the queue between different machines.
94
+ It cannot be use to send data.
95
+
96
+ ```ruby
97
+ EM.run do
98
+ subscriber = client.subscriber(client_id: "YOUR_CLIENT", channel: "YOUR_CHANNEL",
99
+ group: "YOUR_GROUP")
100
+ ws = subscriber.events
101
+
102
+ ws.on :open do |event|
103
+ p [:open]
104
+ end
105
+
106
+ ws.on :message do |event|
107
+ p [:message, RBKubeMQ::Utility.load(event.data)]
108
+ end
109
+
110
+ ws.on :close do |event|
111
+ p [:close]
112
+ ws = nil; EM.stop
113
+ end
114
+ end
115
+ ```
116
+
117
+ In the example the subscriber is for events.
118
+ You can subscribe to "events_store", "requests", and "queries".
119
+
120
+ <a name="RKMQUtility"></a>
121
+ ## RBKubeMQ::Utility
122
+
123
+ ```ruby
124
+ RBKubeMQ::Utility.dump(hash) # Convert hash in correct format for KubeMQ
125
+ RBKubeMQ::Utility.load(string) # Parse hash in human format from KubeMQ
126
+ ```
127
+
128
+ <a name="RKMQerror"></a>
129
+ ## RBKubeMQ::Error
130
+
131
+ RBKubeMQ::Error is used to manage generic errors inside of the gem.
data/lib/client.rb ADDED
@@ -0,0 +1,35 @@
1
+ module RBKubeMQ
2
+ class Client
3
+ include Check
4
+
5
+ def initialize(host:, port: "9090", tls: false)
6
+ @host = host
7
+ @port = port
8
+ is_class?(tls, [FalseClass, TrueClass], "tls")
9
+ @tls = tls
10
+ @uri = "http"
11
+ @uri += "s" if @tls
12
+ @uri += "://#{host}:#{port}"
13
+ @ws = "ws"
14
+ @ws += "s" if @tls
15
+ @ws += "://#{host}:#{port}"
16
+ end
17
+
18
+ attr_reader :host, :port, :uri, :tls, :ws
19
+
20
+ def sender(*args)
21
+ args[0][:client] = self if args[0].is_a?(Hash)
22
+ RBKubeMQ::Sender.new(args[0])
23
+ end
24
+
25
+ def streamer(*args)
26
+ args[0][:client] = self if args[0].is_a?(Hash)
27
+ RBKubeMQ::Streamer.new(args[0])
28
+ end
29
+
30
+ def subscriber(*args)
31
+ args[0][:client] = self if args[0].is_a?(Hash)
32
+ RBKubeMQ::Subscriber.new(args[0])
33
+ end
34
+ end
35
+ end
data/lib/errors.rb ADDED
@@ -0,0 +1,4 @@
1
+ module RBKubeMQ
2
+ class Error < StandardError
3
+ end
4
+ end
@@ -0,0 +1,8 @@
1
+ module RBKubeMQ
2
+ module Check
3
+ def is_class?(object, classes, name)
4
+ return if classes.include?(object.class)
5
+ raise RBKubeMQ::Error.new("#{name} should be #{classes.map(&:to_s).join(", ")}")
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ module RBKubeMQ
2
+ class Utility
3
+ def self.dump(hash)
4
+ hash.compact!
5
+ hash["Body"] = Base64.encode64(hash["Body"].to_s)
6
+ Oj.dump(hash, mode: :json)
7
+ end
8
+
9
+ def self.load(hash)
10
+ hash = Oj.load(hash) if hash.is_a?(String)
11
+ unless hash["Body"].nil?
12
+ hash["Body"] = Base64.decode64(hash["Body"].to_s)
13
+ end
14
+ if hash["data"].is_a?(Hash) && !hash["data"]["Body"].nil?
15
+ hash["data"]["Body"] = Base64.decode64(hash["data"]["Body"].to_s)
16
+ end
17
+ hash
18
+ end
19
+ end
20
+ end
data/lib/rbkubemq.rb ADDED
@@ -0,0 +1,13 @@
1
+ require "httparty"
2
+ require "oj"
3
+ require "faye/websocket"
4
+ require "base64"
5
+ require 'ostruct'
6
+
7
+ require_relative "helpers/check"
8
+ require_relative "helpers/utility"
9
+ require_relative "client"
10
+ require_relative "errors"
11
+ require_relative "sender"
12
+ require_relative "streamer"
13
+ require_relative "subscriber"
data/lib/sender.rb ADDED
@@ -0,0 +1,102 @@
1
+ module RBKubeMQ
2
+ class Sender
3
+ include Check
4
+ @@response = Struct.new(:code, :body)
5
+
6
+ HEADER = {"Content-Type" => "application/json"}
7
+
8
+ def initialize(client:, client_id: nil, channel: nil, meta: nil, store: false,
9
+ timeout: 5000, cache_key: nil, cache_ttl: nil)
10
+ is_class?(client, [RBKubeMQ::Client], "client")
11
+ @client = client
12
+ @client_id = client_id
13
+ @channel = channel
14
+ @meta = meta.nil? ? meta : meta.to_s
15
+ @store = store
16
+ @timeout = timeout
17
+ @cache_key = cache_key
18
+ @cache_ttl = cache_ttl
19
+ end
20
+
21
+ def event(message, meta: @meta, store: @store, client_id: @client_id,
22
+ channel: @channel, id: nil)
23
+ body = {
24
+ "EventID" => id,
25
+ "ClientID" => client_id,
26
+ "Channel" => channel,
27
+ "Metadata" => meta,
28
+ "Body" => message,
29
+ "Store" => store
30
+ }
31
+ http = HTTParty.post("#{@client.uri}/send/event", headers: HEADER,
32
+ body: RBKubeMQ::Utility.dump(body))
33
+ @@response.new(http.code, RBKubeMQ::Utility.load(http.parsed_response))
34
+ rescue StandardError => e
35
+ raise RBKubeMQ::Error.new(e.message)
36
+ end
37
+
38
+ def request(message, meta: @meta, store: @store, client_id: @client_id,
39
+ channel: @channel, id: nil, timeout: @timeout)
40
+ body = {
41
+ "RequestID" => id,
42
+ "RequestTypeData" => 1,
43
+ "ClientID" => client_id,
44
+ "Channel" => channel,
45
+ "Metadata" => meta,
46
+ "Body" => message,
47
+ "Timeout" => timeout
48
+ }
49
+ http = HTTParty.post("#{@client.uri}/send/request", headers: HEADER,
50
+ body: RBKubeMQ::Utility.dump(body))
51
+ @@response.new(http.code, RBKubeMQ::Utility.load(http.parsed_response))
52
+ rescue StandardError => e
53
+ raise RBKubeMQ::Error.new(e.message)
54
+ end
55
+
56
+ def query(message, meta: @meta, store: @store, client_id: @client_id,
57
+ channel: @channel, id: nil, timeout: @timeout, cache_key: @cache_key,
58
+ cache_ttl: @cache_ttl)
59
+ body = {
60
+ "RequestID" => id,
61
+ "RequestTypeData" => 2,
62
+ "ClientID" => client_id,
63
+ "Channel" => channel,
64
+ "Metadata" => meta,
65
+ "Body" => message,
66
+ "Timeout" => timeout,
67
+ "CacheKey" => cache_key,
68
+ "CacheTTL" => cache_ttl
69
+ }
70
+ http = HTTParty.post("#{@client.uri}/send/request", headers: HEADER,
71
+ body: RBKubeMQ::Utility.dump(body))
72
+ @@response.new(http.code, RBKubeMQ::Utility.load(http.parsed_response))
73
+ rescue StandardError => e
74
+ raise RBKubeMQ::Error.new(e.message)
75
+ end
76
+
77
+ def response(request, message: nil, executed: true, error: nil, meta: @meta,
78
+ client_id: @client_id)
79
+ unless request.is_a?(Hash)
80
+ request = RBKubeMQ::Utility.load(request)
81
+ end
82
+
83
+ body = {
84
+ "RequestID" => request["RequestID"],
85
+ "ClientID" => client_id,
86
+ "ReplyChannel" => request["ReplyChannel"],
87
+ "Executed" => executed,
88
+ "Error" => error
89
+ }
90
+ if request["RequestTypeData"] == 2
91
+ body["Metadata"] = meta
92
+ body["Body"] = message
93
+ end
94
+
95
+ http = HTTParty.post("#{@client.uri}/send/response", headers: HEADER,
96
+ body: RBKubeMQ::Utility.dump(body))
97
+ @@response.new(http.code, RBKubeMQ::Utility.load(http.parsed_response))
98
+ rescue StandardError => e
99
+ raise RBKubeMQ::Error.new(e.message)
100
+ end
101
+ end
102
+ end
data/lib/streamer.rb ADDED
@@ -0,0 +1,36 @@
1
+ module RBKubeMQ
2
+ class Streamer
3
+ include Check
4
+
5
+ def initialize(client:, client_id: nil, channel: nil, meta: nil, store: false)
6
+ is_class?(client, [RBKubeMQ::Client], "client")
7
+ @client = client
8
+ @client_id = client_id
9
+ @channel = channel
10
+ @meta = meta.nil? ? meta.to_s : meta
11
+ @store = store
12
+ end
13
+
14
+ attr_accessor :client_id, :channel, :meta, :store
15
+
16
+ def start
17
+ @ws = Faye::WebSocket::Client.new("#{@client.ws}/send/stream")
18
+ @ws
19
+ end
20
+
21
+ def send(message, meta: @meta, store: @store, client_id: @client_id,
22
+ channel: @channel, id: nil)
23
+ body = {
24
+ "EventID" => id,
25
+ "ClientID" => client_id,
26
+ "Channel" => channel,
27
+ "Metadata" => meta,
28
+ "Body" => message,
29
+ "Store" => store
30
+ }
31
+ @ws.send(RBKubeMQ::Utility.dump(body))
32
+ rescue StandardError => e
33
+ raise RBKubeMQ::Error.new(e.message)
34
+ end
35
+ end
36
+ end
data/lib/subscriber.rb ADDED
@@ -0,0 +1,53 @@
1
+ module RBKubeMQ
2
+ class Subscriber
3
+ include Check
4
+
5
+ def initialize(client:, client_id: nil, channel: nil, group: nil,
6
+ events_store_type_data: 1, events_store_type_value: nil)
7
+ is_class?(client, [RBKubeMQ::Client], "client")
8
+ @client = client
9
+ @client_id = client_id
10
+ @channel = channel
11
+ @group = group
12
+ @events_store_type_data = events_store_type_data
13
+ @events_store_type_value = events_store_type_value
14
+ end
15
+
16
+ attr_accessor :client_id, :channel, :meta, :store, :group,
17
+ :events_store_type_data, :events_store_type_value
18
+
19
+ def events
20
+ url = "#{@client.ws}/subscribe/events?client_id=#{@client_id}&channel=#{@channel}"
21
+ url += "&group=#{@group}" unless @group.nil?
22
+ url += "&subscribe_type=events"
23
+ @ws = Faye::WebSocket::Client.new(url)
24
+ @ws
25
+ end
26
+
27
+ def events_store
28
+ url = "#{@client.ws}/subscribe/events?client_id=#{@client_id}&channel=#{@channel}"
29
+ url += "&group=#{@group}" unless @group.nil?
30
+ url += "&events_store_type_data=#{@events_store_type_data}"
31
+ url += "&events_store_type_value=#{@events_store_type_value}" unless @events_store_type_value.nil?
32
+ url += "&subscribe_type=events_store"
33
+ @ws = Faye::WebSocket::Client.new(url)
34
+ @ws
35
+ end
36
+
37
+ def requests
38
+ url = "#{@client.ws}/subscribe/requests?client_id=#{@client_id}&channel=#{@channel}"
39
+ url += "&group=#{@group}" unless @group.nil?
40
+ url += "&subscribe_type=commands"
41
+ @ws = Faye::WebSocket::Client.new(url)
42
+ @ws
43
+ end
44
+
45
+ def queries
46
+ url = "#{@client.ws}/subscribe/requests?client_id=#{@client_id}&channel=#{@channel}"
47
+ url += "&group=#{@group}" unless @group.nil?
48
+ url += "&subscribe_type=queries"
49
+ @ws = Faye::WebSocket::Client.new(url)
50
+ @ws
51
+ end
52
+ end
53
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbkubemq
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Stefano Martin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-04-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.14'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.14.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.14'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.14.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: oj
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 3.6.11
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 3.6.11
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 3.6.11
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 3.6.11
53
+ - !ruby/object:Gem::Dependency
54
+ name: faye-websocket
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: 0.10.7
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.10.7
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 0.10.7
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.10.7
73
+ description: Ruby driver for RBKubeMQ
74
+ email:
75
+ - stefano@seluxit.com
76
+ executables: []
77
+ extensions: []
78
+ extra_rdoc_files: []
79
+ files:
80
+ - Gemfile
81
+ - LICENSE
82
+ - RBKubeMQ.gemspec
83
+ - README.md
84
+ - lib/client.rb
85
+ - lib/errors.rb
86
+ - lib/helpers/check.rb
87
+ - lib/helpers/utility.rb
88
+ - lib/rbkubemq.rb
89
+ - lib/sender.rb
90
+ - lib/streamer.rb
91
+ - lib/subscriber.rb
92
+ homepage: https://github.com/StefanoMartin/RBKubeMQ
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.7.7
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: A simple gem for KubeMQ
116
+ test_files: []