rmq 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rmq.rb CHANGED
@@ -8,5 +8,6 @@ require "rmq/message_descriptor"
8
8
  require "rmq/put_message_options"
9
9
  require "rmq/get_message_options"
10
10
  require "rmq/object_descriptor"
11
+ require "rmq/message"
11
12
  require "rmq/queue"
12
13
 
data/lib/rmq/constants.rb CHANGED
@@ -773,6 +773,8 @@ module RMQ
773
773
  completion_codes[completion_code]
774
774
  end
775
775
 
776
+ MQRC_TRUNCATED_MSG_FAILED = 2080
777
+
776
778
  def decode_reason_code(reason_code)
777
779
  reason_codes = {
778
780
  0 => :MQRC_NONE,
@@ -781,7 +783,7 @@ module RMQ
781
783
  2033 => :MQRC_NO_MSG_AVAILABLE,
782
784
  2037 => :MQRC_NOT_OPEN_FOR_INPUT,
783
785
  2079 => :MQRC_TRUNCATED_MSG_ACCEPTED,
784
- 2080 => :MQRC_TRUNCATED_MSG_FAILED,
786
+ MQRC_TRUNCATED_MSG_FAILED => :MQRC_TRUNCATED_MSG_FAILED,
785
787
  2186 => :MQRC_GMO_ERROR,
786
788
  2309 => :MQRC_SELECTOR_NOT_PRESENT,
787
789
  2320 => :MQRC_HBAG_ERROR,
@@ -14,4 +14,8 @@ module RMQ
14
14
  "#{to_s}. Reason code = #{decode_reason_code(reason_code)} (#{reason_code}), completion code = #{decode_completion_code(completion_code)}"
15
15
  end
16
16
  end
17
+
18
+ class RMQTimeOutError < RuntimeError
19
+ end
20
+
17
21
  end
@@ -0,0 +1,14 @@
1
+ module RMQ
2
+ class Message
3
+ attr_reader :payload
4
+
5
+ def initialize(payload, message_descriptor)
6
+ @payload = payload
7
+ @message_descriptor = message_descriptor
8
+ end
9
+
10
+ def reply_queue_name
11
+ @message_descriptor[:ReplyToQ].to_s.strip
12
+ end
13
+ end
14
+ end
@@ -9,6 +9,8 @@ module RMQ
9
9
  MQMT_DATAGRAM = 8
10
10
  MQPER_PERSISTENT = 1
11
11
 
12
+ MSG_ID_LENGTH = 24
13
+
12
14
  layout :StrucId, [:char, 4],
13
15
  :Version, :long,
14
16
  :Report, :long,
@@ -20,7 +22,7 @@ module RMQ
20
22
  :Format, [:char, 8],
21
23
  :Priority, :long,
22
24
  :Persistence, :long,
23
- :MsgId, [:char, 24],
25
+ :MsgId, [:char, MSG_ID_LENGTH],
24
26
  :CorrelId, [:char, 24],
25
27
  :BackoutCount, :long,
26
28
  :ReplyToQ, [:char, 48],
data/lib/rmq/mqclient.rb CHANGED
@@ -251,31 +251,73 @@ module RMQ
251
251
  queue_depth
252
252
  end
253
253
 
254
- def get_message_from_queue(connection_handle, queue_handle)
254
+ def get_message_from_queue(connection_handle, queue_handle, timeout)
255
+ puts "--- get message from queue"
255
256
  completion_code_ptr = FFI::MemoryPointer.new :long
256
257
  reason_code_ptr = FFI::MemoryPointer.new :long
257
258
  data_length_ptr = FFI::MemoryPointer.new :long
258
259
 
260
+ message_options = prepare_get_message_options(timeout, false)
261
+ message_descriptor = prepare_get_message_descriptor
262
+
263
+ data_length = 8 * 1024
264
+ buffer_ptr = FFI::MemoryPointer.new :char, data_length
265
+
266
+ mqget(connection_handle, queue_handle, message_descriptor, message_options, data_length, buffer_ptr, data_length_ptr, completion_code_ptr, reason_code_ptr)
267
+
268
+ if (completion_code_ptr.read_long == MQCC_WARNING && reason_code_ptr.read_long == MQRC_TRUNCATED_MSG_FAILED)
269
+ msg_id = message_descriptor[:MsgId]
270
+ data_length = data_length_ptr.read_long
271
+ buffer_ptr = FFI::MemoryPointer.new :char, data_length
272
+ message_descriptor = prepare_get_message_descriptor(msg_id)
273
+ mqget(connection_handle, queue_handle, message_descriptor, message_options, data_length, buffer_ptr, data_length_ptr, completion_code_ptr, reason_code_ptr)
274
+ raise RMQException.new(completion_code_ptr.read_long, reason_code_ptr.read_long), "Cannot read message again after learning message length" if completion_code_ptr.read_long == MQCC_FAILED
275
+ else
276
+ raise RMQException.new(completion_code_ptr.read_long, reason_code_ptr.read_long), "Cannot learn message length" unless completion_code_ptr.read_long == MQCC_OK
277
+ end
278
+
279
+ Message.new(buffer_ptr.read_string, message_descriptor)
280
+ end
281
+
282
+ private
283
+
284
+ def prepare_get_message_options(timeout, accept_truncated_msg)
259
285
  message_options = GetMessageOptions.new
260
286
  message_options[:StrucId] = GetMessageOptions::MQGMO_STRUC_ID
261
287
  message_options[:Version] = GetMessageOptions::MQGMO_VERSION_1
262
- message_options[:Options] = GetMessageOptions::MQGMO_ACCEPT_TRUNCATED_MSG
288
+ message_options[:Options] = 0
289
+
290
+ if accept_truncated_msg
291
+ message_options[:Options] = GetMessageOptions::MQGMO_ACCEPT_TRUNCATED_MSG | message_options[:Options]
292
+ end
263
293
 
294
+ if timeout > 0
295
+ message_options[:Options] = GetMessageOptions::MQGMO_WAIT | message_options[:Options]
296
+ message_options[:WaitInterval] = timeout * 1000
297
+ end
298
+
299
+ message_options
300
+ end
301
+
302
+ def print_msg_id(msg_id)
303
+ puts "printing msg id"
304
+ for i in (0..MQClient::MessageDescriptor::MSG_ID_LENGTH-1) do
305
+ puts "#{i} = #{msg_id[i]}"
306
+ end
307
+ end
308
+
309
+ def prepare_get_message_descriptor(msg_id = nil)
264
310
  message_descriptor = MQClient::MessageDescriptor.new
265
311
  message_descriptor[:StrucId] = MQClient::MessageDescriptor::MQMD_STRUC_ID
266
312
  message_descriptor[:Version] = MQClient::MessageDescriptor::MQMD_VERSION_1
267
313
 
268
- # TODO determine message length and then reissue call
269
- # mqget(connection_handle, queue_handle, message_descriptor, message_options, 0, nil, data_length_ptr, completion_code_ptr, reason_code_ptr)
270
- # raise RMQException.new(completion_code_ptr.read_long, reason_code_ptr.read_long), "Cannot learn message length" if completion_code_ptr.read_long == MQCC_FAILED
271
-
272
- # data_length = data_length_ptr.read_long
273
- data_length = 8192
274
- buffer_ptr = FFI::MemoryPointer.new :char, data_length
275
- mqget(connection_handle, queue_handle, message_descriptor, message_options, data_length, buffer_ptr, data_length_ptr, completion_code_ptr, reason_code_ptr)
276
- raise RMQException.new(completion_code_ptr.read_long, reason_code_ptr.read_long), "Cannot learn message length" if completion_code_ptr.read_long == MQCC_FAILED
314
+ if !msg_id.nil?
315
+ for i in (0..MQClient::MessageDescriptor::MSG_ID_LENGTH-1) do
316
+ message_descriptor[:MsgId][i] = msg_id[i]
317
+ end
318
+ end
277
319
 
278
- buffer_ptr.read_string
320
+ message_descriptor
279
321
  end
280
322
 
281
323
  end
data/lib/rmq/queue.rb CHANGED
@@ -9,6 +9,7 @@ module RMQ
9
9
  @queue_name = name
10
10
  end
11
11
 
12
+ # Puts a message onto the queue. A reply to queue name can be specified.
12
13
  def put_message(payload, reply_queue_name = "")
13
14
  @queue_handle = open_queue(@queue_manager.connection_handle, @queue_name, Constants::MQOO_OUTPUT) if @queue_handle.nil?
14
15
 
@@ -22,15 +23,33 @@ module RMQ
22
23
  queue_depth(@queue_manager.connection_handle, @queue_name)
23
24
  end
24
25
 
25
- def get_message
26
+ # Gets a message from the queue. A timeout period can be specified in seconds.
27
+ def get_message(timeout = 0)
26
28
  @queue_handle = open_queue(@queue_manager.connection_handle, @queue_name, Constants::MQOO_INPUT_SHARED) if @queue_handle.nil?
27
29
 
28
- payload = get_message_from_queue(@queue_manager.connection_handle, @queue_handle)
30
+ if (timeout > 0)
31
+ begin_time = Time.now.to_i
32
+ begin
33
+ message = get_message_from_queue(@queue_manager.connection_handle, @queue_handle, timeout)
34
+ rescue RMQException
35
+ end_time = Time.now.to_i
36
+ raise RMQTimeOutError.new if end_time - begin_time >= timeout
37
+ end
38
+ else
39
+ message = get_message_from_queue(@queue_manager.connection_handle, @queue_handle, 0)
40
+ end
29
41
 
30
42
  close_queue(@queue_manager.connection_handle, @queue_handle, Constants::MQCO_NONE)
31
43
  @queue_handle = nil
32
44
 
33
- payload
45
+ message
46
+ end
47
+
48
+ # Gets a message from the queue and returns the payload only. A timeout period can be specified
49
+ # in seconds.
50
+ def get_message_payload(timeout = 0)
51
+ message = get_message(timeout)
52
+ message.payload
34
53
  end
35
54
  end
36
55
  end
data/lib/rmq/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RMQ
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -1,8 +1,14 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe RMQ::QueueManager do
4
+ SAMPLE_QUEUE = SpecHelper::DATA[:sample_queue]
4
5
 
5
6
  after(:each) do
7
+ begin
8
+ @qm.delete_queue(SAMPLE_QUEUE) if !@qm.find_queue(SAMPLE_QUEUE).nil?
9
+ rescue
10
+ puts "Cannot delete #{SAMPLE_QUEUE}"
11
+ end
6
12
  @qm.disconnect if !@qm.nil?
7
13
  end
8
14
 
@@ -27,17 +33,17 @@ describe RMQ::QueueManager do
27
33
 
28
34
  it "should create a new queue" do
29
35
  @qm = RMQ::QueueManager::connect(SpecHelper::DATA[:queue_manager])
30
- queue = @qm.create_queue("RMQ.SAMPLE")
36
+ queue = @qm.create_queue(SAMPLE_QUEUE)
31
37
  queue.should_not be_nil
32
38
 
33
- @qm.find_queue("RMQ.SAMPLE").should_not be_nil
39
+ @qm.find_queue(SAMPLE_QUEUE).should_not be_nil
34
40
 
35
- @qm.delete_queue("RMQ.SAMPLE")
41
+ @qm.delete_queue(SAMPLE_QUEUE)
36
42
  end
37
43
 
38
44
  it "should find an existing queue" do
39
45
  @qm = RMQ::QueueManager::connect(SpecHelper::DATA[:queue_manager])
40
- @qm.find_queue("SYSTEM.ADMIN.COMMAND.QUEUE").should_not be_nil # SAMPLE_IN needs to be changed to one that always exists
46
+ @qm.find_queue("SYSTEM.ADMIN.COMMAND.QUEUE").should_not be_nil
41
47
  end
42
48
 
43
49
  it "should not find a non-existing queue" do
@@ -47,11 +53,11 @@ describe RMQ::QueueManager do
47
53
 
48
54
  it "should delete a queue" do
49
55
  @qm = RMQ::QueueManager::connect(SpecHelper::DATA[:queue_manager])
50
- @qm.create_queue("RMQ.SAMPLE")
51
- @qm.find_queue("RMQ.SAMPLE").should_not be_nil
56
+ @qm.create_queue(SAMPLE_QUEUE)
57
+ @qm.find_queue(SAMPLE_QUEUE).should_not be_nil
52
58
 
53
- @qm.delete_queue("RMQ.SAMPLE")
54
- @qm.find_queue("RMQ.SAMPLE").should be_nil
59
+ @qm.delete_queue(SAMPLE_QUEUE)
60
+ @qm.find_queue(SAMPLE_QUEUE).should be_nil
55
61
  end
56
62
 
57
63
  end
@@ -1,16 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe RMQ::Queue do
4
+ SAMPLE_QUEUE = SpecHelper::DATA[:sample_queue]
4
5
 
5
6
  before(:each) do
6
7
  @qm = RMQ::QueueManager::connect(SpecHelper::DATA[:queue_manager])
7
8
 
8
- @qm.delete_queue("RMQ.SAMPLE") unless @qm.find_queue("RMQ.SAMPLE").nil?
9
- @queue = @qm.create_queue("RMQ.SAMPLE")
9
+ @qm.delete_queue(SAMPLE_QUEUE) unless @qm.find_queue(SAMPLE_QUEUE).nil?
10
+ @queue = @qm.create_queue(SAMPLE_QUEUE)
10
11
  end
11
12
 
12
13
  after(:each) do
13
- @qm.delete_queue("RMQ.SAMPLE")
14
+ begin
15
+ @qm.delete_queue(SAMPLE_QUEUE)
16
+ rescue
17
+ puts "Cannot delete #{SAMPLE_QUEUE}"
18
+ end
14
19
  @qm.disconnect if !@qm.nil?
15
20
  end
16
21
 
@@ -21,11 +26,22 @@ describe RMQ::Queue do
21
26
 
22
27
  it "should read a message from a queue" do
23
28
  @queue.put_message("I want to read this back")
24
- @queue.get_message.should == "I want to read this back"
29
+ @queue.get_message_payload.should == "I want to read this back"
25
30
  end
26
31
 
27
32
  it "should put a message on a queue and use a reply queue name" do
33
+ @queue.put_message("I want to read this back", "REPLY_QUEUE")
34
+ message = @queue.get_message
35
+ message.should_not be_nil
36
+ message.reply_queue_name.should == "REPLY_QUEUE"
37
+ end
38
+
39
+ it "should time out waiting for a message" do
40
+ lambda { @queue.get_message(2) }.should raise_error(RMQ::RMQTimeOutError)
41
+ end
28
42
 
43
+ it "should time out waiting for a message and not return any payload" do
44
+ lambda { @queue.get_message_payload(2) }.should raise_error(RMQ::RMQTimeOutError)
29
45
  end
30
46
 
31
47
  end
data/spec/spec_helper.rb CHANGED
@@ -5,7 +5,8 @@ MQSERVER = "SYSTEM.DEF.SVRCONN/TCP/127.0.0.1(1414)"
5
5
 
6
6
  module SpecHelper
7
7
  DATA = {
8
- :queue_manager => "BKR_QMGR"
8
+ :queue_manager => "BKR_QMGR",
9
+ :sample_queue => "RMQ.SAMPLE"
9
10
  }
10
11
  end
11
12
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rmq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-02-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &21388056 !ruby/object:Gem::Requirement
16
+ requirement: &22131996 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '2.7'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *21388056
24
+ version_requirements: *22131996
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: ffi
27
- requirement: &21387768 !ruby/object:Gem::Requirement
27
+ requirement: &22131528 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *21387768
35
+ version_requirements: *22131528
36
36
  description: Ruby wrapper around MQ series client library
37
37
  email: sns@caimito.net
38
38
  executables: []
@@ -42,6 +42,7 @@ files:
42
42
  - lib/rmq/constants.rb
43
43
  - lib/rmq/exceptions.rb
44
44
  - lib/rmq/get_message_options.rb
45
+ - lib/rmq/message.rb
45
46
  - lib/rmq/message_descriptor.rb
46
47
  - lib/rmq/mqclient.rb
47
48
  - lib/rmq/object_descriptor.rb