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,269 @@
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
+ # Sender events handler for sender client
23
+ class SenderHandler < Handlers::SRCommonHandler
24
+
25
+ # Count of messages to be send
26
+ attr_accessor :count
27
+ # Message properties
28
+ attr_accessor :msg_properties
29
+ # Message content
30
+ attr_accessor :msg_content
31
+ # Message content type
32
+ attr_accessor :msg_content_type
33
+ # Message durability
34
+ attr_accessor :msg_durable
35
+ # Message TTL (ms)
36
+ attr_accessor :msg_ttl
37
+ # Message correlation ID
38
+ attr_accessor :msg_correlation_id
39
+ # Reply to address
40
+ attr_accessor :msg_reply_to
41
+ # Message group ID
42
+ attr_accessor :msg_group_id
43
+ # Message destination
44
+ attr_accessor :msg_to
45
+ # Message priority
46
+ attr_accessor :msg_priority
47
+ # Message ID
48
+ attr_accessor :msg_id
49
+ # Message user ID
50
+ attr_accessor :msg_user_id
51
+ # Message subject
52
+ attr_accessor :msg_subject
53
+ # Anonymous
54
+ attr_accessor :anonymous
55
+
56
+ # Initialization of sender events handler
57
+ # ==== Sender events handler arguments
58
+ # broker:: URI of broker
59
+ # log_msgs:: format of message(s) log
60
+ # count:: number of messages to send
61
+ # msg_content:: message content
62
+ # msg_durable:: message durability
63
+ # msg_ttl:: message TTL (ms)
64
+ # msg_correlation_id:: message correlation ID
65
+ # msg_reply_to:: address to send reply to
66
+ # msg_group_id:: message group ID
67
+ # msg_to:: message destination
68
+ # sasl_mechs:: allowed SASL mechanisms
69
+ def initialize(
70
+ broker,
71
+ log_msgs,
72
+ msg_content_hashed,
73
+ count,
74
+ msg_properties,
75
+ msg_content,
76
+ msg_content_type,
77
+ msg_durable,
78
+ msg_ttl,
79
+ msg_correlation_id,
80
+ msg_reply_to,
81
+ msg_group_id,
82
+ msg_to,
83
+ msg_priority,
84
+ msg_id,
85
+ msg_user_id,
86
+ msg_subject,
87
+ anonymous,
88
+ sasl_mechs,
89
+ idle_timeout,
90
+ max_frame_size,
91
+ sasl_enabled,
92
+ log_lib,
93
+ auto_settle_off,
94
+ exit_timer,
95
+ duration,
96
+ duration_mode
97
+ )
98
+ super(
99
+ broker,
100
+ log_msgs,
101
+ msg_content_hashed,
102
+ sasl_mechs,
103
+ idle_timeout,
104
+ max_frame_size,
105
+ sasl_enabled,
106
+ log_lib,
107
+ auto_settle_off,
108
+ exit_timer
109
+ )
110
+ # Save count of messages to be send
111
+ @count = count
112
+ # Save message properties
113
+ @msg_properties = msg_properties
114
+ # Save message content
115
+ @msg_content = msg_content
116
+ # Save message content type
117
+ @msg_content_type = msg_content_type
118
+ # Save message durability
119
+ @msg_durable = msg_durable
120
+ # Save message TTL (ms)
121
+ @msg_ttl = msg_ttl
122
+ # Save message correlation ID
123
+ @msg_correlation_id = msg_correlation_id
124
+ # Save reply to address
125
+ @msg_reply_to = msg_reply_to
126
+ # Save message group ID
127
+ @msg_group_id = msg_group_id
128
+ # Save message destination
129
+ @msg_to = msg_to
130
+ # Save message priority
131
+ @msg_priority = msg_priority
132
+ # Save message ID
133
+ @msg_id = msg_id
134
+ # Save user ID
135
+ @msg_user_id = msg_user_id
136
+ # Save message subject
137
+ @msg_subject = msg_subject
138
+ # Save anonymous
139
+ @anonymous = anonymous
140
+ # Number of sent messages
141
+ @sent = 0
142
+ # Number of accepted messages
143
+ @accepted = 0
144
+ # Duration
145
+ @duration = Duration.new(duration, count, duration_mode)
146
+ # True if a send has been scheduled
147
+ @scheduled = false
148
+ end
149
+
150
+ # Called when the event loop starts,
151
+ # connects sender client to SRCommonHandler#broker
152
+ # and creates sender
153
+ def on_container_start(container)
154
+ # Connecting to broker and creating sender
155
+ container.connect(
156
+ # Set broker URI
157
+ @broker,
158
+ # Enable SASL authentication
159
+ sasl_enabled: @sasl_enabled,
160
+ # Enable insecure SASL mechanisms
161
+ sasl_allow_insecure_mechs: true,
162
+ # Set allowed SASL mechanisms
163
+ sasl_allowed_mechs: @sasl_mechs,
164
+ # Set idle timeout
165
+ idle_timeout: @idle_timeout,
166
+ # Set max frame size
167
+ max_frame_size: @max_frame_size,
168
+ ).open_sender({
169
+ # Set target address
170
+ :target => anonymous ? nil : @broker.amqp_address,
171
+ # Set auto settle
172
+ :auto_settle => @auto_settle_off ? false : true,
173
+ })
174
+ end
175
+
176
+ def delay
177
+ before = @duration.delay("before-send")
178
+ after = @duration.delay("after-send") if @sent > 0 # No after-delay on first send
179
+ [before, after].compact.inject(:+)
180
+ end
181
+
182
+ # Called when the sender link has credit
183
+ # and messages can therefore be transferred,
184
+ # sending SenderHandler#count messages
185
+ def on_sendable(sender)
186
+ if @duration.zero? # Send immediately
187
+ send(sender) while (sender.credit > 0) && (@sent < @count)
188
+ elsif (sender.credit > 0) && (@sent < @count) && !@scheduled # Schedule to send after delay
189
+ @scheduled = true
190
+ c = sender.connection.container
191
+ c.schedule(delay) do
192
+ send(sender)
193
+ @scheduled = false # Need to re-schedule for another send
194
+ end
195
+ end
196
+ end
197
+
198
+ def send(sender)
199
+ exit_timer.reset if exit_timer
200
+ # Create new message
201
+ msg = Qpid::Proton::Message.new
202
+ # Set message destination
203
+ msg.address = @msg_to
204
+ # If message destination is not set
205
+ unless msg.address
206
+ # Set message destination if anonymous mode
207
+ msg.address = @broker.amqp_address if @anonymous
208
+ end
209
+ # Set message properties
210
+ if @msg_properties
211
+ @msg_properties.each { |k, v| msg[k] = v }
212
+ end
213
+ # If message content is set
214
+ if @msg_content
215
+ # If message content is string and contains formatting part
216
+ if @msg_content.is_a? String and @msg_content =~ /%[0-9]*d/
217
+ # Format message content with number of sent messages
218
+ msg.body = sprintf(@msg_content, @sent)
219
+ else
220
+ # Set message content as it is
221
+ msg.body = @msg_content
222
+ end
223
+ end # if
224
+ # Set message content type if specified
225
+ msg.content_type = @msg_content_type if @msg_content_type
226
+ # Set message durability
227
+ msg.durable = @msg_durable
228
+ # Set message TTL (ms)
229
+ msg.ttl = @msg_ttl
230
+ # If message correlation ID is set
231
+ if @msg_correlation_id
232
+ msg.correlation_id = @msg_correlation_id
233
+ end # if
234
+ # Set reply to address
235
+ msg.reply_to = @msg_reply_to
236
+ # If message group ID is set
237
+ if @msg_group_id
238
+ msg.group_id = @msg_group_id
239
+ end
240
+ msg.priority = @msg_priority if @msg_priority
241
+ msg.id = @msg_id if @msg_id
242
+ msg.user_id = @msg_user_id if @msg_user_id
243
+ msg.subject = @msg_subject if @msg_subject
244
+ # Send message
245
+ sender.send(msg)
246
+ # Increase number of sent messages
247
+ @sent = @sent + 1
248
+ print_message(msg)
249
+ end
250
+
251
+ # Called when the remote peer accepts an outgoing message,
252
+ # accepting SenderHandler#count messages
253
+ def on_tracker_accept(tracker)
254
+ # Increase number of accepted messages
255
+ @accepted = @accepted + 1
256
+ # If all messages to be send are sent and accepted
257
+ if @accepted == @count
258
+ # Close sender
259
+ tracker.sender.close
260
+ # Close connection
261
+ tracker.sender.connection.close
262
+ end # if
263
+ end
264
+
265
+ end # class SenderHandler
266
+
267
+ end # module Handlers
268
+
269
+ # eof
@@ -0,0 +1,100 @@
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
+ require_relative '../formatters/basic_formatter'
20
+ require_relative '../formatters/dict_formatter'
21
+ require_relative '../formatters/interop_formatter'
22
+
23
+ module Handlers
24
+
25
+ # Common events handler for sender and receiver client
26
+ class SRCommonHandler < Handlers::BasicHandler
27
+
28
+ # Format of log
29
+ attr_accessor :log_msgs
30
+ # Content hashed
31
+ attr_accessor :msg_content_hashed
32
+ # Idle timeout
33
+ attr_accessor :idle_timeout
34
+ # Max frame size
35
+ attr_accessor :max_frame_size
36
+ # SASL enabled
37
+ attr_accessor :sasl_enabled
38
+ # Client library logging
39
+ attr_accessor :log_lib
40
+ # Auto settle off
41
+ attr_accessor :auto_settle_off
42
+
43
+ # Initialization of common events handler for sender and receiver client
44
+ # ==== Common events handler arguments
45
+ # broker:: URI of broker
46
+ # log_msgs:: format of message(s) log
47
+ # sasl_mechs:: allowed SASL mechanisms
48
+ def initialize(
49
+ broker,
50
+ log_msgs,
51
+ msg_content_hashed,
52
+ sasl_mechs,
53
+ idle_timeout,
54
+ max_frame_size,
55
+ sasl_enabled,
56
+ log_lib,
57
+ auto_settle_off,
58
+ exit_timer
59
+ )
60
+ super(
61
+ broker,
62
+ sasl_mechs,
63
+ idle_timeout,
64
+ max_frame_size,
65
+ sasl_enabled,
66
+ log_lib,
67
+ exit_timer
68
+ )
69
+ # Save message(s) log format
70
+ @log_msgs = log_msgs
71
+ # Save message(s) content hashed
72
+ @msg_content_hashed = msg_content_hashed
73
+ # Save auto settle off
74
+ @auto_settle_off = auto_settle_off
75
+ end
76
+
77
+ # Print of sent/received message
78
+ # ==== Arguments
79
+ # msg:: message to print
80
+ def print_message(msg)
81
+ case @log_msgs
82
+ when "body"
83
+ Formatters::BasicFormatter.new(msg, @msg_content_hashed).print
84
+ when "dict"
85
+ Formatters::DictFormatter.new(msg, @msg_content_hashed).print
86
+ when "interop"
87
+ Formatters::InteropFormatter.new(msg, @msg_content_hashed).print
88
+ end
89
+ end
90
+
91
+ # Default for un-handled errors is to raise an exception
92
+ def on_error(condition)
93
+ raise condition
94
+ end
95
+
96
+ end # class SRCommonHandler
97
+
98
+ end # module Handlers
99
+
100
+ # eof
data/lib/options.rb ADDED
@@ -0,0 +1,38 @@
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 'options/basic_option_parser'
18
+ require 'options/connector_option_parser'
19
+ require 'options/sr_common_option_parser'
20
+ require 'options/sender_option_parser'
21
+ require 'options/receiver_option_parser'
22
+
23
+ # Module containing option parsers for cli-proton-ruby clients
24
+ # ==== Option parsers
25
+ # * Options::BasicOptionParser of basic options for all clients
26
+ # * Options::ConnectorOptionParser of basic and specific options for connector
27
+ # client
28
+ # * Options::SRCommonOptionParser of basic and common options for sender and
29
+ # receiver client
30
+ # * Options::SenderOptionParser of basic, common and specific options
31
+ # for sender client
32
+ # * Options::ReceiverOptionParser of basic, common and specific options
33
+ # for receiver client
34
+ module Options
35
+
36
+ end # module Options
37
+
38
+ # eof
@@ -0,0 +1,169 @@
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 'optparse'
18
+ require 'ostruct'
19
+
20
+ require_relative '../defaults'
21
+ require_relative '../utils/exit_timer'
22
+
23
+ module Options
24
+
25
+ BOOLEAN_STRINGS = %w(true True yes false False no)
26
+ LOG_LIB_STRINGS = %w(NONE TRANSPORT_RAW TRANSPORT_FRM TRANSPORT_DRV)
27
+
28
+ # Option parser of basic options for all clients
29
+ # ==== Basic client options
30
+ # broker:: URI of broker in format IP:PORT (default: DEFAULT_BROKER,
31
+ # see Defaults)
32
+ # conn-allowed-mechs:: allowed SASL mechanisms for authentication
33
+ # help:: show help message and exit
34
+ class BasicOptionParser
35
+
36
+ # Client options
37
+ attr_accessor :options
38
+
39
+ # Initialization of basic client options
40
+ def initialize()
41
+ @options = OpenStruct.new
42
+ # Basic client's options with default values
43
+
44
+ # Broker in format IP:PORT option
45
+ @options.broker = Defaults::DEFAULT_BROKER
46
+ # Exit timer
47
+ @options.exit_timer = Defaults::DEFAULT_EXIT_TIMER
48
+ # Allowed SASL mechanisms
49
+ @options.sasl_mechs = Defaults::DEFAULT_SASL_MECHS
50
+ # Idle timeout
51
+ @options.idle_timeout = Defaults::DEFAULT_IDLE_TIMEOUT
52
+ # Max frame size
53
+ @options.max_frame_size = Defaults::DEFAULT_MAX_FRAME_SIZE
54
+ # SASL enabled
55
+ @options.sasl_enabled = Defaults::DEFAULT_SASL_ENABLED
56
+ # Client library logging
57
+ @options.log_lib = Defaults::DEFAULT_LOG_LIB
58
+
59
+ @opt_parser = OptionParser.new
60
+ # Basic usage
61
+ @opt_parser.banner = "Usage: <basic_program> [OPTIONS]"
62
+
63
+ @opt_parser.separator ""
64
+ # Broker
65
+ @opt_parser.on(
66
+ "-b",
67
+ "--broker BROKER",
68
+ String,
69
+ "URI of broker in format IP:PORT "+
70
+ "(default: #{Defaults::DEFAULT_BROKER})"
71
+ ) do |broker|
72
+ @options.broker = broker
73
+ end
74
+
75
+ # Client exits after this timeout.
76
+ # Handlers can restart the timer
77
+ # (e.g. on receiving messages, making connections etc.)
78
+ @opt_parser.on(
79
+ "-t",
80
+ "--timeout TIMEOUT",
81
+ Float,
82
+ "timeout in seconds to wait before exiting, 0 unlimited (default: 0)"
83
+ ) do |timeout|
84
+ @options.exit_timer = ExitTimer.new(timeout) if timeout > 0
85
+ end
86
+
87
+ # Allowed SASL mechanisms
88
+ @opt_parser.on(
89
+ "--conn-allowed-mechs MECHS",
90
+ String,
91
+ "space separated list of SASL mechanisms allowed by client "+
92
+ "for authentication (ANONYMOUS/PLAIN/EXTERNAL, default: "+
93
+ "'#{Defaults::DEFAULT_SASL_MECHS}')"
94
+ ) do |sasl_mechs|
95
+ @options.sasl_mechs = sasl_mechs
96
+ end
97
+
98
+ # Max frame size
99
+ @opt_parser.on(
100
+ "--conn-max-frame-size SIZE",
101
+ Integer,
102
+ "define custom maximum frame size in bytes " +
103
+ "(range: #{Defaults::DEFAULT_MIN_MAX_FRAME_SIZE}-" +
104
+ "#{Defaults::DEFAULT_MAX_MAX_FRAME_SIZE}, " +
105
+ "default: #{Defaults::DEFAULT_MAX_FRAME_SIZE})",
106
+ ) do |max_frame_size|
107
+ if max_frame_size < Defaults::DEFAULT_MIN_MAX_FRAME_SIZE \
108
+ or max_frame_size > Defaults::DEFAULT_MAX_MAX_FRAME_SIZE
109
+ raise OptionParser::InvalidArgument, "#{max_frame_size} " +
110
+ "(out of range: #{Defaults::DEFAULT_MIN_MAX_FRAME_SIZE}-" +
111
+ "#{Defaults::DEFAULT_MAX_MAX_FRAME_SIZE})"
112
+ end
113
+ @options.max_frame_size = max_frame_size
114
+ end
115
+
116
+ # Heartbeats configuration
117
+ @opt_parser.on(
118
+ "--conn-heartbeat HEARTBEAT",
119
+ Integer,
120
+ "enable and set connection heartbeat, " +
121
+ "default: #{Defaults::DEFAULT_IDLE_TIMEOUT})"
122
+ ) do |idle_timeout|
123
+ @options.idle_timeout = idle_timeout
124
+ end
125
+
126
+ # Connection SASL enabled
127
+ @opt_parser.on(
128
+ "--conn-sasl-enabled [ENABLED]",
129
+ Options::BOOLEAN_STRINGS,
130
+ "enable connection SASL (#{Options::BOOLEAN_STRINGS.join("/")}, "+
131
+ "default: #{Defaults::DEFAULT_SASL_ENABLED})"
132
+ ) do |sasl_enabled|
133
+ @options.sasl_enabled = true
134
+ @options.sasl_enabled = StringUtils.str_to_bool(sasl_enabled) if sasl_enabled
135
+ end
136
+
137
+ # Client library logging
138
+ @opt_parser.on(
139
+ "--log-lib LEVEL",
140
+ LOG_LIB_STRINGS,
141
+ "enable client library logging (#{LOG_LIB_STRINGS.join("/")}, " +
142
+ "default: #{Defaults::DEFAULT_LOG_LIB})"
143
+ ) do |log_lib|
144
+ @options.log_lib = log_lib
145
+ end
146
+
147
+ # Help
148
+ @opt_parser.on_tail(
149
+ "-h",
150
+ "--help",
151
+ "show help message and exit"
152
+ ) do
153
+ puts @opt_parser
154
+ exit
155
+ end
156
+ end
157
+
158
+ # Parsing of basic options for all clients
159
+ # ==== Parameters
160
+ # args:: arguments to parse
161
+ def parse(args)
162
+ @opt_parser.parse(args)
163
+ end
164
+
165
+ end # class BasicOptionParser
166
+
167
+ end # module Options
168
+
169
+ # eof