cli-proton-ruby 1.0.0

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.
@@ -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