cli-proton-ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,88 @@
1
+ #--
2
+ # Copyright 2018 Red Hat Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #++
16
+
17
+ require_relative 'dict_formatter'
18
+
19
+ module Formatters
20
+
21
+ # Formatter of message into interop dictionary format
22
+ class InteropFormatter < Formatters::DictFormatter
23
+
24
+ # Initialization of interop dictionary formatter
25
+ # ==== Interop dictionary formatter arguments
26
+ # message:: message to format
27
+ def initialize(message, msg_content_hashed=false)
28
+ super(message, msg_content_hashed)
29
+ end # initialize(message)
30
+
31
+ # Format value according to type
32
+ # ==== Parameters
33
+ # value:: value to format
34
+ # ==== Returns
35
+ # value formatted as string
36
+ def format_value(value)
37
+ case value
38
+ when Float
39
+ # ab_diff = [{'content': [[-1.3, -1.2999999523162842]]}]
40
+ value.round(5)
41
+ else
42
+ super
43
+ end
44
+ end
45
+
46
+ # Format message as interop dictionary
47
+ # ==== Returns
48
+ # message formatted as interop dictionary
49
+ def get_as_interop_dictionary()
50
+ dict_to_return = "" \
51
+ + "'redelivered': #{format_value(
52
+ @message.delivery_count == 0 ? false : true
53
+ )}, "\
54
+ + "'reply-to': #{format_value(@message.reply_to)}, "\
55
+ + "'subject': #{format_value(@message.subject)}, "\
56
+ + "'content-type': #{format_value(@message.content_type)}, "\
57
+ + "'id': #{format_value(@message.id)}, "\
58
+ + "'group-id': #{format_value(@message.group_id)}, "\
59
+ + "'user-id': #{format_value(@message.user_id)}, "\
60
+ + "'correlation-id': #{format_value(@message.correlation_id)}, "\
61
+ + "'priority': #{format_value(@message.priority)}, "\
62
+ + "'durable': #{format_value(@message.durable)}, "\
63
+ + "'ttl': #{format_value(@message.ttl)}, "\
64
+ + "'absolute-expiry-time': #{format_value(@message.expires)}, "\
65
+ + "'address': #{format_value(@message.address.nil? ? nil : @message.address.sub(%r{^topic://}, ''))}, "\
66
+ + "'content-encoding': #{format_value(@message.content_encoding)}, "\
67
+ + "'delivery-count': #{format_value(@message.delivery_count)}, "\
68
+ + "'first-acquirer': #{format_value(@message.first_acquirer?)}, "\
69
+ + "'group-sequence': #{format_value(@message.group_sequence)}, "\
70
+ + "'reply-to-group-id': #{format_value(@message.reply_to_group_id)}, "\
71
+ + "'to': #{format_value(@message.to)}, "\
72
+ + "'properties': #{format_value(@message.properties)}, "\
73
+ + "'content': #{
74
+ format_value(@msg_content_hashed ? StringUtils.sha1_hash(@message.body) : @message.body)
75
+ }"
76
+ return self.class.escape_chars("{#{dict_to_return}}")
77
+ end # get_as_interop_dictionary()
78
+
79
+ # Prints message formatted as interop dictionary to stdout
80
+ def print()
81
+ # Print formatted message to stdout
82
+ puts get_as_interop_dictionary()
83
+ end # print()
84
+
85
+ end # class InteropFormatter
86
+
87
+ end # module Formatters
88
+
data/lib/handlers.rb ADDED
@@ -0,0 +1,34 @@
1
+ #--
2
+ # Copyright 2017 Red Hat Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #++
16
+
17
+ require 'handlers/basic_handler'
18
+ require 'handlers/connector_handler'
19
+ require 'handlers/sr_common_handler'
20
+ require 'handlers/sender_handler'
21
+ require 'handlers/receiver_handler'
22
+
23
+ # Module containing event handlers for cli-proton-ruby clients
24
+ # ==== Handlers
25
+ # * Handlers::BasicHandler for all clients
26
+ # * Handlers::ConnectorHandler for connector client
27
+ # * Handlers::SRCommonHandler for sender and receiver client
28
+ # * Handlers::SenderHandler for sender client
29
+ # * Handlers::ReceiverHandler for receiver client
30
+ module Handlers
31
+
32
+ end # module Handlers
33
+
34
+ # eof
@@ -0,0 +1,79 @@
1
+ #--
2
+ # Copyright 2017 Red Hat Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #++
16
+
17
+ require 'qpid_proton'
18
+ require_relative '../utils/env_utils'
19
+
20
+ module Handlers
21
+
22
+ # Basic events handler for all clients
23
+ class BasicHandler < Qpid::Proton::MessagingHandler
24
+
25
+ # Exit timer limits the run-time of the application
26
+ attr_accessor :exit_timer
27
+ # URI of broker
28
+ attr_accessor :broker
29
+ # Allowed SASL mechs
30
+ attr_accessor :sasl_mechs
31
+ # Idle timeout
32
+ attr_accessor :idle_timeout
33
+ # Max frame size
34
+ attr_accessor :max_frame_size
35
+ # SASL enabled
36
+ attr_accessor :sasl_enabled
37
+ # Client library logging
38
+ attr_accessor :log_lib
39
+
40
+ # Initialization of basic events handler for all clients
41
+ # ==== Basic events handler arguments
42
+ # broker:: URI of broker
43
+ # sasl_mechs: allowed SASL mechanisms
44
+ def initialize(
45
+ broker,
46
+ sasl_mechs,
47
+ idle_timeout,
48
+ max_frame_size,
49
+ sasl_enabled,
50
+ log_lib,
51
+ exit_timer
52
+ )
53
+ super()
54
+ @exit_timer = exit_timer
55
+ # Save URI of broker
56
+ if broker.is_a? URI::AMQP or broker.is_a? URI::AMQPS
57
+ @broker = broker
58
+ else
59
+ @broker = Qpid::Proton.uri(broker)
60
+ end
61
+ # Save allowed SASL mechanisms
62
+ @sasl_mechs = sasl_mechs
63
+ # Save idle timeout
64
+ @idle_timeout = idle_timeout
65
+ # Save max frame size
66
+ @max_frame_size = max_frame_size
67
+ # Save SASL enabled
68
+ @sasl_enabled = sasl_enabled
69
+ # Save client library logging
70
+ @log_lib = log_lib
71
+ # Set environment variable for client library logging
72
+ EnvUtils.set_log_lib_env(@log_lib)
73
+ end
74
+
75
+ end # class BasicHandler
76
+
77
+ end # module Handlers
78
+
79
+ # eof
@@ -0,0 +1,90 @@
1
+ #--
2
+ # Copyright 2017 Red Hat Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #++
16
+
17
+ require_relative 'basic_handler'
18
+
19
+ module Handlers
20
+
21
+ # Connector events handler for connector client
22
+ class ConnectorHandler < Handlers::BasicHandler
23
+
24
+ # Count of connections
25
+ attr_accessor :count
26
+ # Array of connections
27
+ attr_accessor :connections
28
+
29
+ # Initialization of events handler for connector client
30
+ # ==== Connector events handler arguments
31
+ # broker:: URI of broker
32
+ # count:: Number of connections to create
33
+ # sasl_mechs:: Allowed SASL mechanisms
34
+ def initialize(
35
+ broker,
36
+ count,
37
+ sasl_mechs,
38
+ idle_timeout,
39
+ max_frame_size,
40
+ sasl_enabled,
41
+ log_lib,
42
+ exit_timer
43
+ )
44
+ super(
45
+ broker,
46
+ sasl_mechs,
47
+ idle_timeout,
48
+ max_frame_size,
49
+ sasl_enabled,
50
+ log_lib,
51
+ exit_timer
52
+ )
53
+ # Save count of connections
54
+ @count = count
55
+ # Initialize array of connections
56
+ @connections = []
57
+ end
58
+
59
+ # Called when the event loop starts,
60
+ # connecting ConnectorHandler#count number of connections
61
+ def on_container_start(container)
62
+ # Connecting count number of connections
63
+ @count.times do
64
+ # Save created connection(s) into array
65
+ @connections.push(container.connect(
66
+ # Set broker URI
67
+ @broker,
68
+ # Enable SASL authentication
69
+ sasl_enabled: @sasl_enabled,
70
+ # Enable insecure SASL mechanisms
71
+ sasl_allow_insecure_mechs: true,
72
+ # Set allowed SASL mechanisms
73
+ sasl_allowed_mechs: @sasl_mechs,
74
+ # Set idle timeout
75
+ idle_timeout: @idle_timeout,
76
+ # Set max frame size
77
+ max_frame_size: @max_frame_size,
78
+ ))
79
+ end
80
+ end
81
+
82
+ def on_connection_open(_c)
83
+ exit_timer.reset if exit_timer
84
+ end
85
+
86
+ end # class ConnectorHandler
87
+
88
+ end # module Handlers
89
+
90
+ # eof
@@ -0,0 +1,230 @@
1
+ #--
2
+ # Copyright 2017 Red Hat Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #++
16
+
17
+ require_relative '../utils/duration'
18
+ require_relative 'sr_common_handler'
19
+
20
+ module Handlers
21
+
22
+ # Receiver events handler for receiver client
23
+ class ReceiverHandler < Handlers::SRCommonHandler
24
+
25
+ # Count of expected messages to be received
26
+ attr_accessor :count
27
+ # Credit for messages to be pre-fetched
28
+ attr_accessor :prefetch
29
+ # Process reply to
30
+ attr_accessor :process_reply_to
31
+ # Browse
32
+ attr_accessor :browse
33
+ # Selector
34
+ attr_accessor :selector
35
+ # Receiver listen
36
+ attr_accessor :recv_listen
37
+ # Receiver listen port
38
+ attr_accessor :recv_listen_port
39
+
40
+ # Initialization of receiver events handler
41
+ # ==== Receiver events handler arguments
42
+ # broker:: URI of broker
43
+ # log_msgs:: format of message(s) log
44
+ # count:: number of messages to receive
45
+ # process-reply-to:: send message to reply-to address if enabled
46
+ # and message got reply-to address
47
+ # browse:: browse messages instead of reading
48
+ # sasl_mechs:: allowed SASL mechanisms
49
+ def initialize(
50
+ broker,
51
+ log_msgs,
52
+ msg_content_hashed,
53
+ count,
54
+ prefetch,
55
+ process_reply_to,
56
+ browse,
57
+ selector,
58
+ sasl_mechs,
59
+ idle_timeout,
60
+ max_frame_size,
61
+ sasl_enabled,
62
+ log_lib,
63
+ recv_listen,
64
+ recv_listen_port,
65
+ auto_settle_off,
66
+ exit_timer,
67
+ duration,
68
+ duration_mode
69
+ )
70
+ super(
71
+ broker,
72
+ log_msgs,
73
+ msg_content_hashed,
74
+ sasl_mechs,
75
+ idle_timeout,
76
+ max_frame_size,
77
+ sasl_enabled,
78
+ log_lib,
79
+ auto_settle_off,
80
+ exit_timer
81
+ )
82
+ # Save count of expected messages to be received
83
+ @count = count
84
+ # Save credit for messages to be pre-fetched
85
+ @prefetch = prefetch
86
+ # Save process reply to
87
+ @process_reply_to = process_reply_to
88
+ # Save browse
89
+ @browse = browse
90
+ # Save selector
91
+ @selector = selector
92
+ # Save recv-listen value
93
+ @recv_listen = recv_listen
94
+ # Save recv-listen port value
95
+ @recv_listen_port = recv_listen_port
96
+ # Number of received messages
97
+ @received = 0
98
+ # Flag indicating that all expected messages were received
99
+ @all_received = false
100
+ # Hash with senders for replying
101
+ @senders = {}
102
+ # Counter of sent messages when processing reply-to
103
+ @sent = 0
104
+ # Counter of accepted messages
105
+ @accepted = 0
106
+ # Duration
107
+ @duration = Duration.new(duration, count, duration_mode)
108
+ end
109
+
110
+ # Called when the event loop starts,
111
+ # connects receiver client to SRCommonHandler#broker
112
+ # and creates receiver
113
+ def on_container_start(container)
114
+ if @recv_listen # P2P
115
+ @listener = container.listen("0.0.0.0:#{@recv_listen_port}")
116
+ else # Broker
117
+ # Prepare source options
118
+ source = {}
119
+ source[:address] = @broker.amqp_address
120
+ source[:filter] = { :selector => make_apache_selector(@selector)} if @selector
121
+ # Connecting to broker and creating receiver
122
+ @receiver = container.connect(
123
+ # Set broker URI
124
+ @broker,
125
+ # Enabled SASL authentication
126
+ sasl_enabled: @sasl_enabled,
127
+ # Enabled insecure SASL mechanisms
128
+ sasl_allow_insecure_mechs: true,
129
+ # Set allowed SASL mechanisms
130
+ sasl_allowed_mechs: @sasl_mechs,
131
+ # Set idle timeout
132
+ idle_timeout: @idle_timeout,
133
+ # Set max frame size
134
+ max_frame_size: @max_frame_size,
135
+ ).open_receiver(
136
+ # Set source options
137
+ :source => source,
138
+ # Set prefetch
139
+ :credit_window => @prefetch,
140
+ )
141
+ # If browse messages instead of reading
142
+ if browse
143
+ # Set browsing mode
144
+ @receiver.source.distribution_mode = \
145
+ Qpid::Proton::Terminus::DIST_MODE_COPY
146
+ end
147
+ end
148
+ end
149
+
150
+ # Called when a message is received,
151
+ # receiving ReceiverHandler#count messages
152
+ def on_message(delivery, message)
153
+ @duration.delay("before-receive") { |d| sleep d }
154
+ exit_timer.reset if exit_timer
155
+ # Print received message
156
+ print_message(message)
157
+ # If process reply to
158
+ if @process_reply_to and !message.reply_to.nil?
159
+ self.do_process_reply_to(message)
160
+ end
161
+ # Increase number of received messages
162
+ @received = @received + 1
163
+ # If expected count of messages to be received is not zero
164
+ # and all expected messages are received
165
+ if @count > 0 and @received == @count
166
+ # Set flag indicating that all expected messages were received to true
167
+ @all_received = true
168
+ # Close listener when listening
169
+ if recv_listen
170
+ # Close listener if not processing reply-to
171
+ @listener.close unless process_reply_to
172
+ # Close receiver when not listening, but receiving
173
+ else
174
+ # Close receiver
175
+ delivery.receiver.close
176
+ # Close connection if not processing reply-to
177
+ delivery.receiver.connection.close unless process_reply_to
178
+ end
179
+ end # if
180
+ @duration.delay("after-receive") { |d| sleep d }
181
+ end
182
+
183
+ # Processing reply to reply-to address of message
184
+ def do_process_reply_to(message)
185
+ # If sender for actual reply-to address does not exist
186
+ unless @senders.include?(message.reply_to)
187
+ # Create new sender for reply-to address
188
+ @senders[message.reply_to] = @receiver.connection.open_sender({
189
+ # Set target address
190
+ :target => message.reply_to,
191
+ # Set auto settle
192
+ :auto_settle => @auto_settle_off ? false : true,
193
+ })
194
+ end
195
+ # Set target address of message to be send to reply-to address
196
+ message.address = message.reply_to
197
+ # Increase number of sent messages
198
+ @sent = @sent + 1
199
+ # Send message to reply-to address
200
+ @senders[message.reply_to].send(message)
201
+ end
202
+
203
+ # Called when the remote peer accepts an outgoing message,
204
+ # accepting ReceiverHandler#sent messages
205
+ def on_tracker_accept(_tracker)
206
+ # Increase number of accepted messages
207
+ @accepted = @accepted + 1
208
+ # If all expected messages were received
209
+ # and all sent messages were accepted
210
+ if @all_received and @accepted == @sent
211
+ # Close all senders and their connections
212
+ @senders.each do |_, i_sender|
213
+ # Close sender
214
+ i_sender.close
215
+ # Close connection of sender
216
+ i_sender.connection.close
217
+ end
218
+ end # if
219
+ end
220
+
221
+ private
222
+ def make_apache_selector(selector)
223
+ Qpid::Proton::Types::Described.new(:"apache.org:selector-filter:string", selector)
224
+ end
225
+
226
+ end # class ReceiverHandler
227
+
228
+ end # module Handlers
229
+
230
+ # eof