Skip to content

Commit bcf9c99

Browse files
committed
Selected header properties part 2 - #51
1 parent 5d0d8da commit bcf9c99

File tree

3 files changed

+239
-15
lines changed

3 files changed

+239
-15
lines changed

README.md

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -139,18 +139,29 @@ go test -run TestSampleSendReceiveWithErrorHandling
139139
The following special header properties are supported for Get, Put or both as listed below.
140140

141141
```
142-
Field name Example Notes
142+
Field name Example Notes
143143
---------------------------------------------------------------------------------------------------------------------------------------------------------
144-
JMS_IBM_PutDate msg.GetStringProperty("JMS_IBM_PutDate") YYYYMMDD
145-
JMS_IBM_PutTime msg.GetStringProperty("JMS_IBM_PutTime") HHMMSSTH
146-
JMS_IBM_Format msg.GetStringProperty("JMS_IBM_Format") MQSTR
147-
msg.SetStringProperty("JMS_IBM_Format", "MYFMT")
148-
JMS_IBM_MQMD_Format msg.GetStringProperty("JMS_IBM_MQMD_Format") MQSTR
149-
msg.SetStringProperty("JMS_IBM_MQMD_Format", "MYFMT")
150-
JMS_IBM_MQMD_MsgId msg.GetJMSMessageID()
151-
JMS_IBM_MQMD_ApplOriginData msg.GetStringProperty("JMS_IBM_MQMD_ApplOriginData")
152-
JMSExpiration msg.GetJMSExpiration()
153-
JMSXAppID msg.GetStringProperty("JMSXAppID") JMSXAppID / PutApplName is set using ConnectionFactory.ApplName
144+
JMS_IBM_PutDate msg.GetStringProperty("JMS_IBM_PutDate") YYYYMMDD
145+
JMS_IBM_PutTime msg.GetStringProperty("JMS_IBM_PutTime") HHMMSSTH
146+
JMS_IBM_Format msg.GetStringProperty("JMS_IBM_Format") MQSTR
147+
msg.SetStringProperty("JMS_IBM_Format", "MYFMT")
148+
JMS_IBM_MQMD_Format msg.GetStringProperty("JMS_IBM_MQMD_Format") MQSTR
149+
msg.SetStringProperty("JMS_IBM_MQMD_Format", "MYFMT")
150+
JMS_IBM_PutApplType msg.GetIntProperty("JMS_IBM_PutApplType")
151+
JMS_IBM_Encoding msg.GetIntProperty("JMS_IBM_Encoding")
152+
msg.SetIntProperty("JMS_IBM_Encoding", 273)
153+
JMS_IBM_Character_Set msg.GetIntProperty("JMS_IBM_Character_Set")
154+
msg.SetIntProperty("JMS_IBM_Character_Set", 1208)
155+
JMS_IBM_MQMD_CodedCharSetId msg.GetIntProperty("JMS_IBM_MQMD_CodedCharSetId")
156+
msg.SetIntProperty("JMS_IBM_MQMD_CodedCharSetId", 1208)
157+
JMS_IBM_MsgType msg.GetIntProperty("JMS_IBM_MsgType")
158+
msg.SetIntProperty("JMS_IBM_MsgType", 8)
159+
JMS_IBM_MQMD_MsgType msg.GetIntProperty("JMS_IBM_MQMD_MsgType")
160+
msg.SetIntProperty("JMS_IBM_MQMD_MsgType", 8)
161+
JMS_IBM_MQMD_MsgId msg.GetJMSMessageID()
162+
JMS_IBM_MQMD_ApplOriginData msg.GetStringProperty("JMS_IBM_MQMD_ApplOriginData")
163+
JMSExpiration msg.GetJMSExpiration()
164+
JMSXAppID msg.GetStringProperty("JMSXAppID") JMSXAppID / PutApplName is set using ConnectionFactory.ApplName
154165
```
155166

156167

mqjms/MessageImpl.go

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,7 @@ func (msg *MessageImpl) SetStringProperty(name string, value *string) jms20subse
318318
return retErr
319319
}
320320

321-
// getSpecialPropertyValue returns the value of special header properties such as
322-
// values from the MQMD that are mapped to JMS properties.
321+
// setSpecialStringPropertyValue sets the special header properties that are of type String
323322
func (msg *MessageImpl) setSpecialStringPropertyValue(name string, value *string) (bool, error) {
324323

325324
// Special properties always start with a known prefix.
@@ -361,6 +360,52 @@ func (msg *MessageImpl) setSpecialStringPropertyValue(name string, value *string
361360
return isSpecial, err
362361
}
363362

363+
// setSpecialIntPropertyValue sets the special header properties of type int
364+
func (msg *MessageImpl) setSpecialIntPropertyValue(name string, value int) (bool, error) {
365+
366+
// Special properties always start with a known prefix.
367+
if !strings.HasPrefix(name, "JMS") {
368+
return false, nil
369+
}
370+
371+
// Check first that there is an MQMD to write to
372+
if msg.mqmd == nil {
373+
msg.mqmd = ibmmq.NewMQMD()
374+
}
375+
376+
// Assume for now that this property is special as it has passed the basic
377+
// checks, and this value will be set back to false if it doesn't match any
378+
// of the specific fields.
379+
isSpecial := true
380+
381+
var err error
382+
383+
switch name {
384+
case "JMS_IBM_PutApplType":
385+
msg.mqmd.PutApplType = int32(value)
386+
387+
case "JMS_IBM_Encoding":
388+
msg.mqmd.Encoding = int32(value)
389+
390+
case "JMS_IBM_Character_Set":
391+
msg.mqmd.CodedCharSetId = int32(value)
392+
393+
case "JMS_IBM_MQMD_CodedCharSetId":
394+
msg.mqmd.CodedCharSetId = int32(value)
395+
396+
case "JMS_IBM_MsgType":
397+
msg.mqmd.MsgType = int32(value)
398+
399+
case "JMS_IBM_MQMD_MsgType":
400+
msg.mqmd.MsgType = int32(value)
401+
402+
default:
403+
isSpecial = false
404+
}
405+
406+
return isSpecial, err
407+
}
408+
364409
// getSpecialPropertyValue returns the value of special header properties such as
365410
// values from the MQMD that are mapped to JMS properties.
366411
func (msg *MessageImpl) getSpecialPropertyValue(name string) (bool, interface{}, error) {
@@ -409,6 +454,36 @@ func (msg *MessageImpl) getSpecialPropertyValue(name string) (bool, interface{},
409454
value = msg.mqmd.ApplOriginData
410455
}
411456

457+
case "JMS_IBM_PutApplType":
458+
if msg.mqmd != nil {
459+
value = msg.mqmd.PutApplType
460+
}
461+
462+
case "JMS_IBM_Encoding":
463+
if msg.mqmd != nil {
464+
value = msg.mqmd.Encoding
465+
}
466+
467+
case "JMS_IBM_Character_Set":
468+
if msg.mqmd != nil {
469+
value = msg.mqmd.CodedCharSetId
470+
}
471+
472+
case "JMS_IBM_MQMD_CodedCharSetId":
473+
if msg.mqmd != nil {
474+
value = msg.mqmd.CodedCharSetId
475+
}
476+
477+
case "JMS_IBM_MsgType":
478+
if msg.mqmd != nil {
479+
value = msg.mqmd.MsgType
480+
}
481+
482+
case "JMS_IBM_MQMD_MsgType":
483+
if msg.mqmd != nil {
484+
value = msg.mqmd.MsgType
485+
}
486+
412487
default:
413488
isSpecial = false
414489
}
@@ -489,6 +564,12 @@ func (msg *MessageImpl) SetIntProperty(name string, value int) jms20subset.JMSEx
489564

490565
var linkedErr error
491566

567+
// Different code path and shortcut for special header properties
568+
isSpecial, _ := msg.setSpecialIntPropertyValue(name, value)
569+
if isSpecial {
570+
return nil
571+
}
572+
492573
smpo := ibmmq.NewMQSMPO()
493574
pd := ibmmq.NewMQPD()
494575

@@ -514,13 +595,23 @@ func (msg *MessageImpl) GetIntProperty(name string) (int, jms20subset.JMSExcepti
514595
impo := ibmmq.NewMQIMPO()
515596
pd := ibmmq.NewMQPD()
516597

517-
_, value, err := msg.msgHandle.InqMP(impo, pd, name)
598+
// Check first if this is a special property
599+
isSpecialProp, value, err := msg.getSpecialPropertyValue(name)
600+
601+
if !isSpecialProp {
602+
// If not then look for a user property
603+
_, value, err = msg.msgHandle.InqMP(impo, pd, name)
604+
}
518605

519606
if err == nil {
520607

521608
var parseErr error
522609

523610
switch valueTyped := value.(type) {
611+
case int:
612+
valueRet = valueTyped
613+
case int32:
614+
valueRet = int(valueTyped)
524615
case int64:
525616
valueRet = int(valueTyped)
526617
case string:

specialproperties_test.go

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
/*
2323
* Test the retrieval of special header properties
2424
*/
25-
func TestPropertySpecialGet(t *testing.T) {
25+
func TestPropertySpecialStringGet(t *testing.T) {
2626

2727
// Loads CF parameters from connection_info.json and applicationApiKey.json in the Downloads directory
2828
cf, cfErr := mqjms.CreateConnectionFactoryFromDefaultJSONFiles()
@@ -302,3 +302,125 @@ func TestPropertyApplData(t *testing.T) {
302302
assert.Nil(t, gotPropValue)
303303

304304
}
305+
306+
/*
307+
* Test the retrieval of special header properties that are Integers
308+
*/
309+
func TestPropertySpecialIntGet(t *testing.T) {
310+
311+
// Loads CF parameters from connection_info.json and applicationApiKey.json in the Downloads directory
312+
cf, cfErr := mqjms.CreateConnectionFactoryFromDefaultJSONFiles()
313+
assert.Nil(t, cfErr)
314+
315+
// Creates a connection to the queue manager, using defer to close it automatically
316+
// at the end of the function (if it was created successfully)
317+
context, ctxErr := cf.CreateContext()
318+
assert.Nil(t, ctxErr)
319+
if context != nil {
320+
defer context.Close()
321+
}
322+
323+
// Create a BytesMessage and check that we can populate it
324+
sendMsg := context.CreateBytesMessage()
325+
326+
// Set the special properties.
327+
putApplType := 6 // MQAT_DEFAULT. (seems to get written by queue manager, not application)
328+
sendMsg.SetIntProperty("JMS_IBM_PutApplType", putApplType)
329+
encoding := 273
330+
sendMsg.SetIntProperty("JMS_IBM_Encoding", encoding)
331+
ccsid := 1208
332+
sendMsg.SetIntProperty("JMS_IBM_Character_Set", ccsid)
333+
msgType := 8 // MQMT_DATAGRAM
334+
sendMsg.SetIntProperty("JMS_IBM_MsgType", msgType)
335+
336+
// Set up objects for send/receive
337+
queue := context.CreateQueue("DEV.QUEUE.1")
338+
consumer, errCons := context.CreateConsumer(queue)
339+
if consumer != nil {
340+
defer consumer.Close()
341+
}
342+
assert.Nil(t, errCons)
343+
344+
// Now send the message and get it back again, to check that it roundtripped.
345+
ttlMillis := 20000
346+
errSend := context.CreateProducer().SetTimeToLive(ttlMillis).Send(queue, sendMsg)
347+
assert.Nil(t, errSend)
348+
349+
rcvMsg, errRvc := consumer.ReceiveNoWait()
350+
assert.Nil(t, errRvc)
351+
assert.NotNil(t, rcvMsg)
352+
353+
switch msg := rcvMsg.(type) {
354+
case jms20subset.BytesMessage:
355+
assert.Equal(t, 0, msg.GetBodyLength())
356+
default:
357+
assert.Fail(t, "Got something other than a bytes message")
358+
}
359+
360+
// Check the properties came back as expected.
361+
gotPropValue, propErr := rcvMsg.GetIntProperty("JMS_IBM_PutApplType")
362+
assert.Nil(t, propErr)
363+
assert.Equal(t, putApplType, gotPropValue)
364+
365+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_Encoding")
366+
assert.Nil(t, propErr)
367+
assert.Equal(t, encoding, gotPropValue)
368+
369+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_Character_Set")
370+
assert.Nil(t, propErr)
371+
assert.Equal(t, ccsid, gotPropValue)
372+
373+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_MQMD_CodedCharSetId")
374+
assert.Nil(t, propErr)
375+
assert.Equal(t, ccsid, gotPropValue)
376+
377+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_MsgType")
378+
assert.Nil(t, propErr)
379+
assert.Equal(t, msgType, gotPropValue)
380+
381+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_MQMD_MsgType")
382+
assert.Nil(t, propErr)
383+
assert.Equal(t, msgType, gotPropValue)
384+
385+
// Create a BytesMessage and check that we can populate it
386+
sendMsg2 := context.CreateBytesMessage()
387+
388+
// Set the special properties, using the MQMD property name variants
389+
ccsid2 := 850
390+
sendMsg2.SetIntProperty("JMS_IBM_MQMD_CodedCharSetId", ccsid2)
391+
msgType2 := 2 // MQMT_REPLY
392+
sendMsg2.SetIntProperty("JMS_IBM_MQMD_MsgType", msgType2)
393+
394+
// Now send the message and get it back again, to check that it roundtripped.
395+
errSend = context.CreateProducer().SetTimeToLive(ttlMillis).Send(queue, sendMsg2)
396+
assert.Nil(t, errSend)
397+
398+
rcvMsg, errRvc = consumer.ReceiveNoWait()
399+
assert.Nil(t, errRvc)
400+
assert.NotNil(t, rcvMsg)
401+
402+
switch msg := rcvMsg.(type) {
403+
case jms20subset.BytesMessage:
404+
assert.Equal(t, 0, msg.GetBodyLength())
405+
default:
406+
assert.Fail(t, "Got something other than a bytes message")
407+
}
408+
409+
// Check the properties came back as expected.
410+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_Character_Set")
411+
assert.Nil(t, propErr)
412+
assert.Equal(t, ccsid2, gotPropValue)
413+
414+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_MQMD_CodedCharSetId")
415+
assert.Nil(t, propErr)
416+
assert.Equal(t, ccsid2, gotPropValue)
417+
418+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_MsgType")
419+
assert.Nil(t, propErr)
420+
assert.Equal(t, msgType2, gotPropValue)
421+
422+
gotPropValue, propErr = rcvMsg.GetIntProperty("JMS_IBM_MQMD_MsgType")
423+
assert.Nil(t, propErr)
424+
assert.Equal(t, msgType2, gotPropValue)
425+
426+
}

0 commit comments

Comments
 (0)