Skip to content

Commit 7b6cf0e

Browse files
committed
BytesMessage shortcut functions
1 parent cbfa721 commit 7b6cf0e

File tree

8 files changed

+361
-17
lines changed

8 files changed

+361
-17
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ your own error handling or logging.
113113
* Creating a ConnectionFactory that uses a client connection to a remote queue manager - [connectionfactory_test.go](connectionfactory_test.go)
114114
* Creating a ConnectionFactory that uses a bindings connection to a local queue manager - [local_bindings_test.go](local_bindings_test.go)
115115
* Create a connection using anonymous (one-way) TLS encryption or mutual TLS authentication - [tls_connections_test.go](tls_connections_test.go)
116-
* Send/receive (with no wait) a text string - [sample_sendreceive_test.go](sample_sendreceive_test.go)
116+
* Send/receive (with no wait) a text string (TextMessage) - [sample_sendreceive_test.go](sample_sendreceive_test.go)
117+
* Send/receive a slice of bytes (BytesMessage) - [bytesmessage_test.go](bytesmessage_test.go)
117118
* Receive with wait [receivewithwait_test.go](receivewithwait_test.go)
118119
* Send a message as Persistent or NonPersistent - [deliverymode_test.go](deliverymode_test.go)
119120
* Get by CorrelationID - [getbycorrelid_test.go](getbycorrelid_test.go)

bytesmessage_test.go

Lines changed: 247 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ func TestBytesMessageNilBody(t *testing.T) {
8080
}
8181
assert.Nil(t, errCons)
8282

83-
rcvMsg, errRvc := consumer.ReceiveNoWait()
84-
assert.Nil(t, errRvc)
83+
rcvMsg, errRcv := consumer.ReceiveNoWait()
84+
assert.Nil(t, errRcv)
8585
assert.NotNil(t, rcvMsg)
8686

8787
switch msg2 := rcvMsg.(type) {
@@ -95,7 +95,7 @@ func TestBytesMessageNilBody(t *testing.T) {
9595
}
9696

9797
/*
98-
* Test send and receive of a bytes message with no content.
98+
* Test send and receive of a bytes message with some basic content.
9999
*/
100100
func TestBytesMessageWithBody(t *testing.T) {
101101

@@ -111,7 +111,7 @@ func TestBytesMessageWithBody(t *testing.T) {
111111
defer context.Close()
112112
}
113113

114-
// Create a BytesMessage, and check it has nil content.
114+
// Create a BytesMessage
115115
msgBody := []byte{'b', 'y', 't', 'e', 's', 'm', 'e', 's', 's', 'a', 'g', 'e'}
116116
msg := context.CreateBytesMessage()
117117
msg.WriteBytes(msgBody)
@@ -129,8 +129,56 @@ func TestBytesMessageWithBody(t *testing.T) {
129129
}
130130
assert.Nil(t, errCons)
131131

132-
rcvMsg, errRvc := consumer.ReceiveNoWait()
133-
assert.Nil(t, errRvc)
132+
rcvMsg, errRcv := consumer.ReceiveNoWait()
133+
assert.Nil(t, errRcv)
134+
assert.NotNil(t, rcvMsg)
135+
136+
switch msg2 := rcvMsg.(type) {
137+
case jms20subset.BytesMessage:
138+
assert.Equal(t, len(msgBody), msg2.GetBodyLength())
139+
assert.Equal(t, msgBody, *msg2.ReadBytes())
140+
default:
141+
assert.Fail(t, "Got something other than a text message")
142+
}
143+
144+
}
145+
146+
/*
147+
* Test send and receive of a bytes message with init'd at create time.
148+
*/
149+
func TestBytesMessageInitWithBytes(t *testing.T) {
150+
151+
// Loads CF parameters from connection_info.json and apiKey.json in the Downloads directory
152+
cf, cfErr := mqjms.CreateConnectionFactoryFromDefaultJSONFiles()
153+
assert.Nil(t, cfErr)
154+
155+
// Creates a connection to the queue manager, using defer to close it automatically
156+
// at the end of the function (if it was created successfully)
157+
context, ctxErr := cf.CreateContext()
158+
assert.Nil(t, ctxErr)
159+
if context != nil {
160+
defer context.Close()
161+
}
162+
163+
// Create a BytesMessage, and check it has nil content.
164+
msgBody := []byte{'b', 'y', 't', 'e', 's', 'm', 'e', 's', 's', 'a', 'g', 'e', 'A', 'B', 'C'}
165+
msg := context.CreateBytesMessageWithBytes(msgBody)
166+
assert.Equal(t, 15, msg.GetBodyLength())
167+
assert.Equal(t, msgBody, *msg.ReadBytes())
168+
169+
// Now send the message and get it back again, to check that it roundtripped.
170+
queue := context.CreateQueue("DEV.QUEUE.1")
171+
errSend := context.CreateProducer().SetTimeToLive(5000).Send(queue, msg)
172+
assert.Nil(t, errSend)
173+
174+
consumer, errCons := context.CreateConsumer(queue)
175+
if consumer != nil {
176+
defer consumer.Close()
177+
}
178+
assert.Nil(t, errCons)
179+
180+
rcvMsg, errRcv := consumer.Receive(2000) // also try receive with wait
181+
assert.Nil(t, errRcv)
134182
assert.NotNil(t, rcvMsg)
135183

136184
switch msg2 := rcvMsg.(type) {
@@ -142,3 +190,196 @@ func TestBytesMessageWithBody(t *testing.T) {
142190
}
143191

144192
}
193+
194+
/*
195+
* Test Producer SendBytes shortcut
196+
*/
197+
func TestBytesMessageProducerSendBytes(t *testing.T) {
198+
199+
// Loads CF parameters from connection_info.json and apiKey.json in the Downloads directory
200+
cf, cfErr := mqjms.CreateConnectionFactoryFromDefaultJSONFiles()
201+
assert.Nil(t, cfErr)
202+
203+
// Creates a connection to the queue manager, using defer to close it automatically
204+
// at the end of the function (if it was created successfully)
205+
context, ctxErr := cf.CreateContext()
206+
assert.Nil(t, ctxErr)
207+
if context != nil {
208+
defer context.Close()
209+
}
210+
211+
// Create a BytesMessage, and check it has nil content.
212+
msgBody := []byte{'b', 'y', 't', 'e', 's', 'p', 'r', 'o', 'd', 'u', 'c', 'e', 'r'}
213+
214+
// Now send the message and get it back again, to check that it roundtripped.
215+
queue := context.CreateQueue("DEV.QUEUE.1")
216+
errSend := context.CreateProducer().SetTimeToLive(5000).SendBytes(queue, msgBody)
217+
assert.Nil(t, errSend)
218+
219+
consumer, errCons := context.CreateConsumer(queue)
220+
if consumer != nil {
221+
defer consumer.Close()
222+
}
223+
assert.Nil(t, errCons)
224+
225+
rcvMsg, errRcv := consumer.ReceiveNoWait()
226+
assert.Nil(t, errRcv)
227+
assert.NotNil(t, rcvMsg)
228+
229+
switch msg2 := rcvMsg.(type) {
230+
case jms20subset.BytesMessage:
231+
assert.Equal(t, 13, msg2.GetBodyLength())
232+
assert.Equal(t, msgBody, *msg2.ReadBytes())
233+
default:
234+
assert.Fail(t, "Got something other than a text message")
235+
}
236+
237+
}
238+
239+
/*
240+
* Test Consumer ReceiveBytesBodyNoWait shortcut
241+
*/
242+
func TestBytesMessageConsumerReceiveBytesBodyNoWait(t *testing.T) {
243+
244+
// Loads CF parameters from connection_info.json and apiKey.json in the Downloads directory
245+
cf, cfErr := mqjms.CreateConnectionFactoryFromDefaultJSONFiles()
246+
assert.Nil(t, cfErr)
247+
248+
// Creates a connection to the queue manager, using defer to close it automatically
249+
// at the end of the function (if it was created successfully)
250+
context, ctxErr := cf.CreateContext()
251+
assert.Nil(t, ctxErr)
252+
if context != nil {
253+
defer context.Close()
254+
}
255+
256+
queue := context.CreateQueue("DEV.QUEUE.1")
257+
consumer, errCons := context.CreateConsumer(queue)
258+
if consumer != nil {
259+
defer consumer.Close()
260+
}
261+
assert.Nil(t, errCons)
262+
263+
// Check the behaviour if there is no message to receive.
264+
var expectedNil *[]byte // uninitialized
265+
rcvBytes, errRcv := consumer.ReceiveBytesBodyNoWait()
266+
assert.Nil(t, errRcv)
267+
assert.Equal(t, expectedNil, rcvBytes)
268+
269+
// Create a BytesMessage, and check it has nil content.
270+
msgBody := []byte{'b', 'y', 't', 'e', 's', 'n', 'o', 'w', 'a', 'i', 't'}
271+
272+
// Now send the message and get it back again, to check that it roundtripped.
273+
errSend := context.CreateProducer().SetTimeToLive(5000).SendBytes(queue, msgBody)
274+
assert.Nil(t, errSend)
275+
276+
rcvBytes, errRcv = consumer.ReceiveBytesBodyNoWait()
277+
assert.Nil(t, errRcv)
278+
assert.Equal(t, msgBody, *rcvBytes)
279+
280+
}
281+
282+
/*
283+
* Test Consumer ReceiveBytesBody shortcut
284+
*/
285+
func TestBytesMessageConsumerReceiveBytesBody(t *testing.T) {
286+
287+
// Loads CF parameters from connection_info.json and apiKey.json in the Downloads directory
288+
cf, cfErr := mqjms.CreateConnectionFactoryFromDefaultJSONFiles()
289+
assert.Nil(t, cfErr)
290+
291+
// Creates a connection to the queue manager, using defer to close it automatically
292+
// at the end of the function (if it was created successfully)
293+
context, ctxErr := cf.CreateContext()
294+
assert.Nil(t, ctxErr)
295+
if context != nil {
296+
defer context.Close()
297+
}
298+
299+
queue := context.CreateQueue("DEV.QUEUE.1")
300+
consumer, errCons := context.CreateConsumer(queue)
301+
if consumer != nil {
302+
defer consumer.Close()
303+
}
304+
assert.Nil(t, errCons)
305+
306+
// Check the behaviour if there is no message to receive.
307+
var expectedNil *[]byte // uninitialized
308+
rcvBytes, errRcv := consumer.ReceiveBytesBody(250)
309+
assert.Nil(t, errRcv)
310+
assert.Equal(t, expectedNil, rcvBytes)
311+
312+
// Create a BytesMessage, and check it has nil content.
313+
msgBody := []byte{'b', 'y', 't', 'e', 's', 'w', 'a', 'i', 't'}
314+
315+
// Now send the message and get it back again, to check that it roundtripped.
316+
errSend := context.CreateProducer().SetTimeToLive(5000).SendBytes(queue, msgBody)
317+
assert.Nil(t, errSend)
318+
319+
rcvBytes, errRcv = consumer.ReceiveBytesBody(500)
320+
assert.Nil(t, errRcv)
321+
assert.Equal(t, msgBody, *rcvBytes)
322+
323+
}
324+
325+
/*
326+
* Test Consumer ReceiveBytesBody/ReceiveStringBody shortcuts when unexpected
327+
* types of messages are received.
328+
*/
329+
func TestBytesMessageConsumerMixedMessageErrors(t *testing.T) {
330+
331+
// Loads CF parameters from connection_info.json and apiKey.json in the Downloads directory
332+
cf, cfErr := mqjms.CreateConnectionFactoryFromDefaultJSONFiles()
333+
assert.Nil(t, cfErr)
334+
335+
// Creates a connection to the queue manager, using defer to close it automatically
336+
// at the end of the function (if it was created successfully)
337+
context, ctxErr := cf.CreateContext()
338+
assert.Nil(t, ctxErr)
339+
if context != nil {
340+
defer context.Close()
341+
}
342+
343+
queue := context.CreateQueue("DEV.QUEUE.1")
344+
consumer, errCons := context.CreateConsumer(queue)
345+
if consumer != nil {
346+
defer consumer.Close()
347+
}
348+
assert.Nil(t, errCons)
349+
350+
// Send a BytesMessage, try to receive as text with no wait.
351+
msgBodyBytes := []byte{'b', 'y', 't', 'e', 's', '1', '2', '3', '4'}
352+
errSend := context.CreateProducer().SetTimeToLive(5000).SendBytes(queue, msgBodyBytes)
353+
assert.Nil(t, errSend)
354+
rcvStr, errRcv := consumer.ReceiveStringBodyNoWait()
355+
assert.Nil(t, rcvStr)
356+
assert.Equal(t, "MQJMS6068", errRcv.GetErrorCode())
357+
assert.Equal(t, "MQJMS_DIR_MIN_NOTTEXT", errRcv.GetReason())
358+
359+
// Send a BytesMessage, try to receive as text with wait.
360+
errSend = context.CreateProducer().SetTimeToLive(5000).SendBytes(queue, msgBodyBytes)
361+
assert.Nil(t, errSend)
362+
rcvStr, errRcv = consumer.ReceiveStringBody(200)
363+
assert.Nil(t, rcvStr)
364+
assert.Equal(t, "MQJMS6068", errRcv.GetErrorCode())
365+
assert.Equal(t, "MQJMS_DIR_MIN_NOTTEXT", errRcv.GetReason())
366+
367+
// Send a TextMessage, try to receive as bytes with no wait.
368+
msgBodyStr := "TextMessage is not Bytes"
369+
errSend = context.CreateProducer().SetTimeToLive(5000).SendString(queue, msgBodyStr)
370+
assert.Nil(t, errSend)
371+
rcvBytes, errRcv := consumer.ReceiveBytesBodyNoWait()
372+
var expectedNil *[]byte // uninitialized
373+
assert.Equal(t, expectedNil, rcvBytes)
374+
assert.Equal(t, "MQJMS6068", errRcv.GetErrorCode())
375+
assert.Equal(t, "MQJMS_DIR_MIN_NOTBYTES", errRcv.GetReason())
376+
377+
// Send a TextMessage, try to receive as bytes with wait.
378+
errSend = context.CreateProducer().SetTimeToLive(5000).SendString(queue, msgBodyStr)
379+
assert.Nil(t, errSend)
380+
rcvBytes, errRcv = consumer.ReceiveBytesBody(200)
381+
assert.Equal(t, expectedNil, rcvBytes)
382+
assert.Equal(t, "MQJMS6068", errRcv.GetErrorCode())
383+
assert.Equal(t, "MQJMS_DIR_MIN_NOTBYTES", errRcv.GetReason())
384+
385+
}

jms20subset/JMSConsumer.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,35 @@ type JMSConsumer interface {
2222
// there is no message immediately available
2323
ReceiveNoWait() (Message, JMSException)
2424

25-
// ReceiveStringBodyNoWait receives the next message for this JMSConsumer
26-
// and returns its body as a string. If a message is not immediately
27-
// available a nil is returned.
28-
ReceiveStringBodyNoWait() (*string, JMSException)
29-
3025
// Receive(waitMillis) returns a message if one is available, or otherwise
3126
// waits for up to the specified number of milliseconds for one to become
3227
// available. A value of zero or less indicates to wait indefinitely.
3328
Receive(waitMillis int32) (Message, JMSException)
3429

30+
// ReceiveStringBodyNoWait receives the next message for this JMSConsumer
31+
// and returns its body as a string. If a message is not immediately
32+
// available a nil is returned.
33+
ReceiveStringBodyNoWait() (*string, JMSException)
34+
3535
// ReceiveStringBody returns the body of a message as a string if one is
3636
// available. If a message is not immediately available the method will
3737
// block for up to the specified number of milliseconds to wait for one
3838
// to become available. A value of zero or less indicates to wait
3939
// indefinitely.
4040
ReceiveStringBody(waitMillis int32) (*string, JMSException)
4141

42+
// ReceiveBytesBodyNoWait receives the next message for this JMSConsumer
43+
// and returns its body as a slice of bytes. If a message is not immediately
44+
// available an uninitialized *[]byte is returned.
45+
ReceiveBytesBodyNoWait() (*[]byte, JMSException)
46+
47+
// ReceiveBytesBody returns the body of a message as a slice of bytes if one is
48+
// available. If a message is not immediately available the method will
49+
// block for up to the specified number of milliseconds to wait for one
50+
// to become available. A value of zero or less indicates to wait
51+
// indefinitely.
52+
ReceiveBytesBody(waitMillis int32) (*[]byte, JMSException)
53+
4254
// Closes the JMSConsumer in order to free up any resources that were
4355
// allocated by the provider on behalf of this consumer.
4456
Close()

jms20subset/JMSContext.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ type JMSContext interface {
6464
// of bytes from one application to another.
6565
CreateBytesMessage() BytesMessage
6666

67+
// CreateBytesMessageWithBytes creates a message object that is used to send a slice
68+
// of bytes from one application to another.
69+
CreateBytesMessageWithBytes(bytes []byte) BytesMessage
70+
6771
// Commit confirms all messages sent/received during this transaction.
6872
Commit()
6973

jms20subset/JMSProducer.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ type JMSProducer interface {
2727
// name and different parameters we must use a different function name.
2828
SendString(dest Destination, body string) JMSException
2929

30+
// Send a BytesMessage with the specified body to the specified Destination
31+
// using any message options that are defined on this JMSProducer.
32+
//
33+
// Note that since Golang does not allow multiple functions with the same
34+
// name and different parameters we must use a different function name.
35+
SendBytes(dest Destination, body []byte) JMSException
36+
3037
// SetDeliveryMode sets the delivery mode of messages sent using this
3138
// JMSProducer - for example whether a message is persistent or non-persistent.
3239
//

0 commit comments

Comments
 (0)