Skip to content

Commit b349e76

Browse files
authored
Merge pull request #71 from matrober-uk/coa-cod-report
Add support for Feedback, COA, COD - #70
2 parents eb8eac5 + ed6afe3 commit b349e76

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ JMSXAppID msg.GetStringProperty("JMSXAppID")
166166
JMSXGroupID msg.GetStringProperty("JMSXGroupID")
167167
JMSXGroupSeq msg.GetIntProperty("JMSXGroupSeq")
168168
JMS_IBM_Last_Msg_In_Group msg.GetBooleanProperty("JMS_IBM_Last_Msg_In_Group")
169+
JMS_IBM_Feedback msg.SetIntProperty("JMS_IBM_Encoding", 65600)
170+
msg.GetIntProperty("JMS_IBM_Encoding")
171+
JMS_IBM_Report_COA msg.SetIntProperty("JMS_IBM_Report_COA", ibmmq.MQRO_COA_WITH_DATA)
172+
msg.GetIntProperty("JMS_IBM_Report_COA")
173+
JMS_IBM_Report_COD msg.SetIntProperty("JMS_IBM_Report_COD", ibmmq.MQRO_COD_WITH_DATA)
174+
msg.GetIntProperty("JMS_IBM_Report_COD")
169175
```
170176

171177

mqjms/MessageImpl.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,15 @@ func (msg *MessageImpl) setSpecialIntPropertyValue(name string, value int) (bool
422422
case "JMS_IBM_Encoding":
423423
msg.mqmd.Encoding = int32(value)
424424

425+
case "JMS_IBM_Feedback":
426+
msg.mqmd.Feedback = int32(value)
427+
428+
case "JMS_IBM_Report_COA":
429+
msg.mqmd.Report |= int32(value) // bitwise merge (OR) the COA value
430+
431+
case "JMS_IBM_Report_COD":
432+
msg.mqmd.Report |= int32(value) // bitwise merge (OR) the COD value
433+
425434
case "JMS_IBM_Character_Set":
426435
msg.mqmd.CodedCharSetId = int32(value)
427436

@@ -483,6 +492,21 @@ func (msg *MessageImpl) getSpecialPropertyValue(name string) (bool, interface{},
483492
value = msg.mqmd.Format
484493
}
485494

495+
case "JMS_IBM_Feedback":
496+
if msg.mqmd != nil && msg.mqmd.Feedback != ibmmq.MQFB_NONE {
497+
value = msg.mqmd.Feedback
498+
}
499+
500+
case "JMS_IBM_Report_COA":
501+
if msg.mqmd != nil && msg.mqmd.Report != ibmmq.MQRO_NONE {
502+
value = msg.mqmd.Report & ibmmq.MQRO_COA_WITH_FULL_DATA // bitwise retrieve just the COA data
503+
}
504+
505+
case "JMS_IBM_Report_COD":
506+
if msg.mqmd != nil && msg.mqmd.Report != ibmmq.MQRO_NONE {
507+
value = msg.mqmd.Report & ibmmq.MQRO_COD_WITH_FULL_DATA // bitwise retrieve just the COD data
508+
}
509+
486510
case "JMSXAppID":
487511
if msg.mqmd != nil {
488512
value = msg.mqmd.PutApplName

specialproperties_test.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"github.com/ibm-messaging/mq-golang-jms20/jms20subset"
1818
"github.com/ibm-messaging/mq-golang-jms20/mqjms"
19+
"github.com/ibm-messaging/mq-golang/v5/ibmmq"
1920
"github.com/stretchr/testify/assert"
2021
)
2122

@@ -425,3 +426,126 @@ func TestPropertySpecialIntGet(t *testing.T) {
425426
assert.Equal(t, msgType2, gotPropValue)
426427

427428
}
429+
430+
/*
431+
* Test the retrieval of the JMS_IBM_Feedback, JMS_IBM_Report_COA and JMS_IBM_Report_COD properties.
432+
*/
433+
func TestPropertyReportCOACOD(t *testing.T) {
434+
435+
// Loads CF parameters from connection_info.json and applicationApiKey.json in the Downloads directory
436+
cf, cfErr := mqjms.CreateConnectionFactoryFromDefaultJSONFiles()
437+
assert.Nil(t, cfErr)
438+
439+
// Creates a connection to the queue manager, using defer to close it automatically
440+
// at the end of the function (if it was created successfully)
441+
context, ctxErr := cf.CreateContext()
442+
assert.Nil(t, ctxErr)
443+
if context != nil {
444+
defer context.Close()
445+
}
446+
447+
// Create a BytesMessage and check that we can populate it
448+
sendMsg := context.CreateBytesMessage()
449+
450+
// Set the special properties.
451+
feedbackVal := int(ibmmq.MQFB_APPL_FIRST + 20) // after the MQFB_APPL_FIRST range
452+
sendMsg.SetIntProperty("JMS_IBM_Feedback", feedbackVal)
453+
reportCOAVal := int(ibmmq.MQRO_COA_WITH_DATA)
454+
sendMsg.SetIntProperty("JMS_IBM_Report_COA", reportCOAVal)
455+
reportCODVal := int(ibmmq.MQRO_COD_WITH_DATA)
456+
sendMsg.SetIntProperty("JMS_IBM_Report_COD", reportCODVal)
457+
458+
// Set up objects for send/receive
459+
queue := context.CreateQueue("DEV.QUEUE.1")
460+
consumer, errCons := context.CreateConsumer(queue)
461+
if consumer != nil {
462+
defer consumer.Close()
463+
}
464+
assert.Nil(t, errCons)
465+
466+
replyQueue := context.CreateQueue("DEV.QUEUE.2")
467+
replyConsumer, errCons := context.CreateConsumer(replyQueue)
468+
if replyConsumer != nil {
469+
defer replyConsumer.Close()
470+
}
471+
assert.Nil(t, errCons)
472+
473+
// Check no messages on the reply queue to before we start.
474+
rcvMsg, errRvc := replyConsumer.ReceiveNoWait()
475+
assert.Nil(t, errRvc)
476+
assert.Nil(t, rcvMsg) // no message should be present (haven't started the test yet)
477+
478+
sendMsg.SetJMSReplyTo(replyQueue)
479+
480+
// Now send the message and get it back again, to check that it roundtripped.
481+
ttlMillis := 20000
482+
errSend := context.CreateProducer().SetTimeToLive(ttlMillis).Send(queue, sendMsg)
483+
assert.Nil(t, errSend)
484+
485+
// Check the COA notification has been created (but not COD)
486+
coaMsg, errRvc := replyConsumer.ReceiveNoWait()
487+
assert.Nil(t, errRvc)
488+
assert.NotNil(t, coaMsg) // COA message should have been created. When this check fails, see below.
489+
// When the COA message is not received it's quite likely because the COA message has ended up on the DEAD.LETTER.QUEUE
490+
// because the sending application does not have permissions to copy the messageID.
491+
//
492+
// Look in the queue manager logs for an error like this (and then add that permission to the user record)
493+
//
494+
// AMQ8077W: Entity 'myapp2' has insufficient authority to access object DEV.QUEUE.2 [queue].
495+
// EXPLANATION:
496+
// The specified entity is not authorized to access the required object. The
497+
// following requested permissions are unauthorized: passid
498+
//
499+
assert.Equal(t, sendMsg.GetJMSMessageID(), coaMsg.GetJMSCorrelationID())
500+
coaFeedback, coaFeedbackErr := coaMsg.GetIntProperty("JMS_IBM_Feedback")
501+
assert.Nil(t, coaFeedbackErr)
502+
assert.Equal(t, int(ibmmq.MQFB_COA), coaFeedback)
503+
504+
// Check no more report messages yet.
505+
secondReportMsg, errRvc := replyConsumer.ReceiveNoWait()
506+
assert.Nil(t, errRvc)
507+
assert.Nil(t, secondReportMsg)
508+
509+
// -------
510+
// Now receive the original message back from the queue.
511+
rcvMsg, errRvc = consumer.ReceiveNoWait()
512+
assert.Nil(t, errRvc)
513+
assert.NotNil(t, rcvMsg)
514+
515+
switch msg := rcvMsg.(type) {
516+
case jms20subset.BytesMessage:
517+
assert.Equal(t, 0, msg.GetBodyLength())
518+
default:
519+
assert.Fail(t, "Got something other than a bytes message")
520+
}
521+
522+
// Check the properties came back as expected (on the normal message that was received back)
523+
gotPropValue, propErr := rcvMsg.GetIntProperty("JMS_IBM_Feedback")
524+
assert.Nil(t, propErr)
525+
assert.Equal(t, feedbackVal, gotPropValue)
526+
527+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_Report_COA")
528+
assert.Nil(t, propErr)
529+
assert.Equal(t, reportCOAVal, gotPropValue)
530+
531+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_Report_COD")
532+
assert.Nil(t, propErr)
533+
assert.Equal(t, reportCODVal, gotPropValue)
534+
535+
// ------
536+
537+
// COD notification should now have been created, since the request message has been consumed.
538+
codMsg, errRvc := replyConsumer.ReceiveNoWait()
539+
assert.Nil(t, errRvc)
540+
assert.NotNil(t, codMsg) // COD message should have been created.
541+
assert.Equal(t, sendMsg.GetJMSMessageID(), codMsg.GetJMSCorrelationID())
542+
codFeedback, codFeedbackErr := codMsg.GetIntProperty("JMS_IBM_Feedback")
543+
assert.Nil(t, codFeedbackErr)
544+
assert.Equal(t, int(ibmmq.MQFB_COD), codFeedback)
545+
546+
// Check no more report messages.
547+
thirdReportMsg, errRvc := replyConsumer.ReceiveNoWait()
548+
assert.Nil(t, errRvc)
549+
assert.Nil(t, thirdReportMsg)
550+
551+
}

0 commit comments

Comments
 (0)