ruby_rabbitmq_janus 0.3.0 → 1.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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +64 -7
  3. data/.reek +7 -0
  4. data/.rubocop.yml +0 -3
  5. data/README.md +40 -2
  6. data/config/default.md +22 -6
  7. data/config/default.yml +24 -6
  8. data/config/requests/{test.json → admin/handle_info.json} +2 -4
  9. data/config/requests/admin/handles.json +6 -0
  10. data/config/requests/admin/log_level.json +6 -0
  11. data/config/requests/admin/sessions.json +5 -0
  12. data/config/requests/{attach.json → base/attach.json} +0 -0
  13. data/config/requests/{create.json → base/create.json} +0 -0
  14. data/config/requests/{destroy.json → base/destroy.json} +0 -0
  15. data/config/requests/{detach.json → base/detach.json} +0 -0
  16. data/config/requests/{info.json → base/info.json} +0 -0
  17. data/config/requests/base/keepalive.json +5 -0
  18. data/lib/generators/ruby_rabbitmq_janus/configuration_generator.rb +23 -0
  19. data/lib/generators/ruby_rabbitmq_janus/create_request_generator.rb +90 -0
  20. data/lib/generators/ruby_rabbitmq_janus/default_request_generator.rb +21 -0
  21. data/lib/generators/ruby_rabbitmq_janus/initializer_generator.rb +17 -0
  22. data/lib/rrj/errors/config.rb +21 -0
  23. data/lib/rrj/errors/error.rb +56 -0
  24. data/lib/rrj/errors/janus.rb +14 -0
  25. data/lib/rrj/errors/janus_message.rb +45 -0
  26. data/lib/rrj/errors/janus_response.rb +78 -0
  27. data/lib/rrj/errors/janus_transaction.rb +31 -0
  28. data/lib/rrj/errors/rabbit.rb +21 -0
  29. data/lib/rrj/errors/request.rb +21 -0
  30. data/lib/rrj/info.rb +40 -0
  31. data/lib/rrj/init.rb +113 -44
  32. data/lib/rrj/janus/admin.rb +27 -0
  33. data/lib/rrj/janus/janus.rb +10 -33
  34. data/lib/rrj/janus/keepalive.rb +69 -0
  35. data/lib/rrj/janus/message.rb +77 -22
  36. data/lib/rrj/janus/response.rb +79 -41
  37. data/lib/rrj/janus/transaction.rb +53 -0
  38. data/lib/rrj/janus/transaction_admin.rb +43 -0
  39. data/lib/rrj/janus/transaction_handle.rb +40 -0
  40. data/lib/rrj/janus/transaction_session.rb +17 -0
  41. data/lib/rrj/rabbit/connect.rb +75 -0
  42. data/lib/rrj/rabbit/propertie.rb +37 -0
  43. data/lib/rrj/rabbit/publish.rb +100 -0
  44. data/lib/rrj/rabbit/rabbit.rb +11 -0
  45. data/lib/rrj/tools/config.rb +63 -0
  46. data/lib/rrj/tools/env.rb +21 -0
  47. data/lib/rrj/tools/log.rb +106 -0
  48. data/lib/rrj/tools/replaces.rb +115 -0
  49. data/lib/rrj/tools/replaces_admin.rb +44 -0
  50. data/lib/rrj/tools/requests.rb +57 -0
  51. data/lib/rrj/tools/tools.rb +14 -0
  52. data/lib/ruby_rabbitmq_janus.rb +8 -13
  53. data/rrj.gemspec +7 -3
  54. metadata +108 -28
  55. data/config.reek +0 -3
  56. data/lib/rrj/config.rb +0 -57
  57. data/lib/rrj/janus/error.rb +0 -8
  58. data/lib/rrj/janus/message_async.rb +0 -54
  59. data/lib/rrj/janus/message_sync.rb +0 -34
  60. data/lib/rrj/log.rb +0 -63
  61. data/lib/rrj/rabbitmq/rabbitmq.rb +0 -82
  62. data/lib/rrj/request/path.rb +0 -21
  63. data/lib/rrj/request/replaces.rb +0 -109
  64. data/lib/rrj/request/requests.rb +0 -55
  65. data/lib/rrj/request/type_data.rb +0 -30
  66. data/lib/rrj/version.rb +0 -17
@@ -1,55 +1,93 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
-
5
3
  module RubyRabbitmqJanus
6
- # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
7
- # Response Janus received to RabbitMQ server
8
- class ResponseJanus
9
- # Initialiaze a response reading in RabbitMQ queue
10
- def initialize(channel, connection, opts = {})
11
- @channel = channel
12
- @connection = connection
13
- @opts = opts
14
- @response = nil
15
- end
4
+ module Janus
5
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
6
+ # Read and decryt a response to janus
7
+ class Response
8
+ # Instanciate a response
9
+ def initialize(response_janus)
10
+ @request = response_janus
11
+ rescue => error
12
+ Tools::Log.instance.debug "Request error : #{@request}"
13
+ raise Errors::JanusResponseInit, error
14
+ else
15
+ Tools::Log.instance.debug "Response return : #{to_json}"
16
+ end
16
17
 
17
- # Read a response to janus (in RabbitMQ queue)
18
- # @return [Hash] resultat to request
19
- def read
20
- Log.instance.debug 'Read a response'
21
- the_queue = @channel.queue(Config.instance.options['queues']['queue_from'])
22
- the_queue.subscribe(block: true) do |info, prop, pay|
23
- listen(info, prop, pay)
18
+ # Return request to json format
19
+ def to_json
20
+ analysis
21
+ @request.to_json
22
+ rescue => error
23
+ Tools::Log.instance.debug "Request error : #{@request}"
24
+ raise Errors::JanusResponseJson, error
25
+ end
26
+
27
+ # Return request to json format with nice format
28
+ def to_nice_json
29
+ JSON.pretty_generate to_hash
30
+ rescue => error
31
+ Tools::Log.instance.debug "Request error : #{@request}"
32
+ raise Errors::JanusResponsePrettyJson, error
24
33
  end
25
- return_response_json
26
- end
27
34
 
28
- private
35
+ # Return request to hash format
36
+ def to_hash
37
+ analysis
38
+ @request
39
+ rescue => error
40
+ Tools::Log.instance.debug "Request error : #{@request}"
41
+ raise Errors::JanusResponseHash, error
42
+ end
29
43
 
30
- # Listen a response to queue
31
- def listen(_delivery_info, properties, payload)
32
- if @opts['properties']['correlation'] == properties[:correlation_id]
33
- @response = payload
34
- @connection.close
44
+ # Return a response simple for client
45
+ def for_plugin
46
+ case @request['janus']
47
+ when 'success' then @request['plugindata']['data']
48
+ when 'ack' then {}
49
+ end
50
+ rescue => error
51
+ Tools::Log.instance.debug "Request error : #{@request}"
52
+ raise Errors::JanusResponsePluginData, error
35
53
  end
36
- end
37
54
 
38
- # Format the response returning
39
- def return_response_json
40
- @response = JSON.parse(@response)
41
- case @opts['janus']
42
- when 'create'
43
- merge('session_id')
44
- when 'attach'
45
- merge('handle_id')
55
+ # Return a integer to session
56
+ def session
57
+ data_id
46
58
  end
47
- @response
48
- end
49
59
 
50
- # Update value to element in Hash
51
- def merge(key)
52
- @response[key] = @response['data']['id']
60
+ # Return a integer to handle
61
+ def sender
62
+ data_id
63
+ end
64
+
65
+ private
66
+
67
+ # Read a hash and return an identifier
68
+ def data_id
69
+ analysis
70
+ @request['data']['id'].to_i
71
+ rescue => error
72
+ raise Errors::JanusResponseDataId, error
73
+ end
74
+
75
+ # Analysis response and send exception if janus return an error
76
+ # :reek:DuplicateMethodCall
77
+ def analysis
78
+ raise Errors::JanusResponseSimple, @request['error'] if error_simple?
79
+ raise Errors::JanusResponsePlugin, @request['plugindata']['data'] if error_plugin?
80
+ end
81
+
82
+ # Test if message response contains an simple error
83
+ def error_simple?
84
+ @request['janus'].equal? 'error'
85
+ end
86
+
87
+ # Test if message response contains an error in plugin
88
+ def error_plugin?
89
+ @request.key?('plugindata') && @request['plugindata']['data'].key?('error_code')
90
+ end
53
91
  end
54
92
  end
55
93
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ module Janus
5
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
6
+ # This class work with janus and send a series of message
7
+ # :reek:TooManyInstanceVariables
8
+ class Transaction
9
+ # Initialize an transaction
10
+ def initialize(session)
11
+ @rabbit = Rabbit::Connect.new
12
+ @session = session
13
+ @response = @handle = @publish = nil
14
+ rescue => error
15
+ raise Errors::JanusTransaction, error
16
+ end
17
+
18
+ # Opening a short transaction with rabbitmq and close when is ending
19
+ def connect(exclusive)
20
+ @rabbit.transaction_short do
21
+ choose_queue(exclusive)
22
+ send_a_message { yield }
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :rabbit, :session, :response, :handle, :publish
29
+
30
+ # determine queue used
31
+ # :reek:ControlParameter and :reek:BooleanParameter
32
+ def choose_queue(exclusive = false)
33
+ chan = @rabbit.channel
34
+ @publish = if exclusive
35
+ Rabbit::PublishNonExclusive.new(chan)
36
+ else
37
+ Rabbit::PublishExclusive.new(chan, '')
38
+ end
39
+ end
40
+
41
+ # Send a message to queue
42
+ def send_a_message
43
+ Janus::Response.new(@publish.send_a_message(yield))
44
+ end
45
+
46
+ # Associate handle to transaction
47
+ def create_handle
48
+ msg = Janus::Message.new('base::attach', 'session_id' => @session)
49
+ @handle = send_a_message { msg }.sender
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ module Janus
5
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
6
+ # This class work with janus and send a series of message
7
+ class TransactionAdmin < TransactionHandle
8
+ # Initialize conncetion to Rabbit and Janus
9
+ def connect
10
+ rabbit.transaction_short do
11
+ choose_queue
12
+ send_a_message { yield }
13
+ end
14
+ end
15
+
16
+ def handle_connect
17
+ rabbit.transaction_long do
18
+ choose_queue
19
+ create_handle
20
+ yield
21
+ end
22
+ end
23
+
24
+ # Publish an message in handle
25
+ def publish_message_handle(type, options = {})
26
+ opts = { 'session_id' => session, 'handle_id' => handle }
27
+ msg = Janus::MessageAdmin.new(type, opts.merge!(options))
28
+ Janus::Response.new(publish.send_a_message(msg))
29
+ end
30
+
31
+ # Stop an handle running
32
+ def handle_running_stop
33
+ secret = Tools::Config.instance.options['rabbit']['admin_pass']
34
+ publish_message_handle('base::detach', admin_secret: secret)
35
+ end
36
+
37
+ # Define queue used for admin message
38
+ def choose_queue
39
+ @publish = Rabbit::PublishAdmin.new(rabbit.channel)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ module Janus
5
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
6
+ # This class work with janus and send a series of message
7
+ class TransactionHandle < TransactionSession
8
+ # Initialize connection to Rabbit and Janus
9
+ def handle_connect(exclusive)
10
+ rabbit.transaction_long do
11
+ choose_queue(exclusive)
12
+ create_handle
13
+ yield
14
+ end
15
+ end
16
+
17
+ # Initialize connection to Rabbit and Janus and close after sending an received
18
+ # a response
19
+ def handle_connect_and_stop(exclusive)
20
+ rabbit.transaction_short do
21
+ choose_queue(exclusive)
22
+ create_handle
23
+ yield
24
+ end
25
+ end
26
+
27
+ # Stop an handle running
28
+ def handle_running_stop
29
+ publish_message_handle('base::detach')
30
+ end
31
+
32
+ # Publish an message in handle
33
+ def publish_message_handle(type, options = {})
34
+ opts = { 'session_id' => session, 'handle_id' => handle }
35
+ msg = Janus::Message.new(type, opts.merge!(options))
36
+ Janus::Response.new(publish.send_a_message(msg))
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ module Janus
5
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
6
+ # This class work with janus and send a series of message for session level
7
+ class TransactionSession < Transaction
8
+ # Connect to session and post an message
9
+ def session_connect(exclusive)
10
+ rabbit.transaction_short do
11
+ choose_queue(exclusive)
12
+ send_a_message { yield }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ module Rabbit
5
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
6
+ # Class for manage connection with rabbitmq
7
+ class Connect
8
+ # Initialize connection to server RabbitMQ
9
+ def initialize
10
+ Tools::Log.instance.debug 'Initialize connection with RabbitMQ'
11
+ @rabbit = Bunny.new(read_options_server)
12
+ end
13
+
14
+ # Create an transaction with rabbitmq and close after response is received
15
+ def transaction_short
16
+ response = transaction_long { yield }
17
+ close
18
+ response
19
+ end
20
+
21
+ # Create an transaction with rabbitmq and not close
22
+ def transaction_long
23
+ start
24
+ yield
25
+ end
26
+
27
+ # Openning a connection with Rabbitmq
28
+ def start
29
+ Tools::Log.instance.debug 'Connection to rabbitmq START'
30
+ @rabbit.start
31
+ rescue => message
32
+ raise Errors::ConnectionRabbitmqFailed, message
33
+ end
34
+
35
+ # Close connection to server RabbitMQ
36
+ def close
37
+ Tools::Log.instance.debug 'Connection to rabbitmq STOP'
38
+ @rabbit.close
39
+ rescue
40
+ raise Bunny::ConnectionClosedError
41
+ end
42
+
43
+ # Create an channel
44
+ def channel
45
+ Tools::Log.instance.debug 'Create an channel'
46
+ @rabbit.create_channel
47
+ end
48
+
49
+ private
50
+
51
+ # Read option for bunny instance (connection with rabbitmq)
52
+ # :reek:FeatureEnvy
53
+ def read_options_server
54
+ cfg = Tools::Config.instance.options['rabbit']
55
+ opts = {}
56
+ %w(host port pass user vhost).each do |val|
57
+ opts.merge!(val.to_sym => Tools::Env.instance.test_env_var(cfg, val))
58
+ end
59
+ opts.merge!(option_log_rabbit)
60
+ end
61
+
62
+ # Define option logs for bunny
63
+ def option_log_rabbit
64
+ if Tools::Log.instance.level.zero?
65
+ {
66
+ log_level: Tools::Log.instance.level,
67
+ log_file: Tools::Log.instance.logdev
68
+ }
69
+ else
70
+ {}
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ module Rabbit
5
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
6
+ # Manage properties to message sending in rabbitmq queue
7
+ class Propertie
8
+ attr_reader :correlation
9
+
10
+ # Initialize a message sending to rabbitmq
11
+ def initialize
12
+ Tools::Log.instance.debug 'initalize a propertie to message'
13
+ @correlation = SecureRandom.uuid
14
+ end
15
+
16
+ # Define options sending to rabbitmq
17
+ def options
18
+ Tools::Log.instance.debug 'Add options to propertie to message'
19
+ {
20
+ routing_key: Tools::Config.instance.options['queues']['queue_to'],
21
+ correlation_id: @correlation,
22
+ content_type: 'application/json'
23
+ }
24
+ end
25
+
26
+ # Define option sending to rabbitmq for janus admin message
27
+ def options_admin
28
+ Tools::Log.instance.debug 'Add options to propertie to message'
29
+ {
30
+ routing_key: Tools::Config.instance.options['queues']['admin']['queue_to'],
31
+ correlation_id: @correlation,
32
+ content_type: 'application/json'
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :reek:FeatureEnvy and :reek:InstanceVariableAssumption
4
+ module RubyRabbitmqJanus
5
+ module Rabbit
6
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
7
+ # @abstract Publish message in RabbitMQ
8
+ class Publish
9
+ # Define Exchange operation
10
+ def initialize(exchange)
11
+ Tools::Log.instance.debug 'Create/Connect to queue'
12
+ @exchange = exchange.default_exchange
13
+ @message = nil
14
+ end
15
+
16
+ # Send a message in queue
17
+ def send_a_message(request)
18
+ Tools::Log.instance.info "Send request type : #{request.type}"
19
+ @message = request
20
+ @exchange.publish(@message.to_json, request.options)
21
+ end
22
+ end
23
+
24
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
25
+ # @abstract Publish an message in RabbitMQ and waiting a response
26
+ class PublishReply < Publish
27
+ # Initialize a queue
28
+ def initialize(exchange)
29
+ @condition = ConditionVariable.new
30
+ @lock = Mutex.new
31
+ @response = nil
32
+ subscribe_to_queue
33
+ super
34
+ end
35
+
36
+ # Publish an message in rabbitmq
37
+ def send_a_message(request)
38
+ Tools::Log.instance.info "Send request type : #{request.type}"
39
+ @exchange.publish(read_message(request),
40
+ request.options.merge!(reply_to: @reply.name))
41
+ @lock.synchronize { @condition.wait(@lock) }
42
+ @response
43
+ end
44
+
45
+ private
46
+
47
+ # Read message and return to JSON format
48
+ def read_message(request)
49
+ @message = request
50
+ @message.to_json
51
+ end
52
+
53
+ # Subscribe to queue in Rabbitmq
54
+ def subscribe_to_queue
55
+ @reply.subscribe do |_delivery_info, properties, payload|
56
+ if @message.correlation.eql?(properties.correlation_id)
57
+ @response = JSON.parse payload
58
+ @lock.synchronize { @condition.signal }
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
65
+ # Publish message in non exclusive queue
66
+ class PublishNonExclusive < PublishReply
67
+ # Initialize an queue non exclusive
68
+ def initialize(exchange)
69
+ @reply = exchange.queue(Tools::Config.instance.options['queues']['queue_from'])
70
+ super(exchange)
71
+ end
72
+ end
73
+
74
+ # Publish for admin Janus
75
+ class PublishAdmin < PublishReply
76
+ # Initialize an queue non exclusive
77
+ def initialize(exchange)
78
+ name = Tools::Config.instance.options['queues']['admin']['queue_from']
79
+ @reply = exchange.queue(name)
80
+ super(exchange)
81
+ end
82
+ end
83
+
84
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
85
+ # Publish message in exclusive queue
86
+ class PublishExclusive < PublishReply
87
+ # Initialize an queue exclusive
88
+ def initialize(exchange, name_queue = '')
89
+ @reply = exchange.queue(name_queue, exclusive: true)
90
+ super(exchange)
91
+ end
92
+
93
+ # Name to queue
94
+ # @return [String] Name to queue used
95
+ def queue_name
96
+ @reply.name
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rrj/rabbit/connect'
4
+ require 'rrj/rabbit/publish'
5
+ require 'rrj/rabbit/propertie'
6
+
7
+ module RubyRabbitmqJanus
8
+ # Module rabbit interaction
9
+ module Rabbit
10
+ end
11
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ module Tools
5
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
6
+ # Loading a yaml file for apply a configuration to gem.
7
+ class Config
8
+ include Singleton
9
+
10
+ attr_reader :options
11
+
12
+ # Define a default path to file configuration
13
+ DEFAULT_PATH = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
14
+
15
+ # Define a default name to file configuration
16
+ DEFAULT_CONF = 'config/default.yml'
17
+
18
+ # Define a default override file configuration
19
+ CUSTOMIZE_CONF = 'config/ruby-rabbitmq-janus.yml'
20
+
21
+ # Initialize configuration file default or customize if exist
22
+ def initialize
23
+ @options = nil
24
+ conf_customize
25
+ conf_default
26
+ define_log_level_used
27
+ end
28
+
29
+ private
30
+
31
+ # Load configuration file yaml
32
+ # @return [Yaml] Configuration file
33
+ # @param file [String] Path to configuration file (with name)
34
+ # :reek:UtilityFunction { public_methods_only: true }
35
+ def load_configuration(file)
36
+ Tools::Log.instance.info("Loading configuration file : #{file}")
37
+ YAML.load(File.read(file))
38
+ rescue
39
+ raise Errors::ConfigFileNotFound, file
40
+ end
41
+
42
+ # Load customize configuration file if exist
43
+ def conf_customize
44
+ file = File.join(Dir.pwd, CUSTOMIZE_CONF)
45
+ @options = load_configuration(file) if File.exist?(file)
46
+ end
47
+
48
+ # Load default configuration if customize configuration doesn't exist
49
+ def conf_default
50
+ file = File.join(DEFAULT_PATH, DEFAULT_CONF)
51
+ @options ||= load_configuration(file)
52
+ end
53
+
54
+ # Define log lvel used in this gem
55
+ def define_log_level_used
56
+ Tools::Log.instance.level = \
57
+ Tools::Log::LEVELS[@options['gem']['log']['level'].to_sym]
58
+ rescue
59
+ raise Errors::LevelNotDefine
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ # Contains all tools necessary in this gem
5
+ module Tools
6
+ # Class for tools used in gem
7
+ # :reek:UtilityFunction
8
+ class Env
9
+ include Singleton
10
+
11
+ def test_env_var(configuration, key)
12
+ test = configuration[key.to_s]
13
+ if test.is_a?(String)
14
+ test.include?('ENV') ? ENV[test.gsub("ENV['", '').gsub("']", '')] : test
15
+ else
16
+ test
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end