Skip to content

Commit 7973594

Browse files
committed
Support for double (float64) message properties - #39
1 parent a7141af commit 7973594

File tree

3 files changed

+180
-0
lines changed

3 files changed

+180
-0
lines changed

jms20subset/Message.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ type Message interface {
6565
// Returns 0 if the named property is not set.
6666
GetIntProperty(name string) (int, JMSException)
6767

68+
// SetDoubleProperty enables an application to set a double-type (float64) message property.
69+
SetDoubleProperty(name string, value float64) JMSException
70+
71+
// GetDoubleProperty returns the double (float64) value of a named message property.
72+
// Returns 0 if the named property is not set.
73+
GetDoubleProperty(name string) (float64, JMSException)
74+
6875
// PropertyExists returns true if the named message property exists on this message.
6976
PropertyExists(name string) (bool, JMSException)
7077

messageproperties_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,3 +712,117 @@ func TestIntProperty(t *testing.T) {
712712
assert.True(t, propExists) // exists, even though it is set to zero
713713

714714
}
715+
716+
/*
717+
* Test the creation of a text message with an int property.
718+
*/
719+
func TestDoubleProperty(t *testing.T) {
720+
721+
// Loads CF parameters from connection_info.json and applicationApiKey.json in the Downloads directory
722+
cf, cfErr := mqjms.CreateConnectionFactoryFromDefaultJSONFiles()
723+
assert.Nil(t, cfErr)
724+
725+
// Creates a connection to the queue manager, using defer to close it automatically
726+
// at the end of the function (if it was created successfully)
727+
context, ctxErr := cf.CreateContext()
728+
assert.Nil(t, ctxErr)
729+
if context != nil {
730+
defer context.Close()
731+
}
732+
733+
// Create a TextMessage and check that we can populate it
734+
msgBody := "DoublePropertyRequestMsg"
735+
txtMsg := context.CreateTextMessage()
736+
txtMsg.SetText(msgBody)
737+
738+
propName := "myProperty"
739+
propValue := float64(15867494.43857438)
740+
741+
// Test the empty value before the property is set.
742+
gotPropValue, propErr := txtMsg.GetDoubleProperty(propName)
743+
assert.Nil(t, propErr)
744+
assert.Equal(t, float64(0), gotPropValue)
745+
propExists, propErr := txtMsg.PropertyExists(propName)
746+
assert.Nil(t, propErr)
747+
assert.False(t, propExists)
748+
749+
// Test the ability to set properties before the message is sent.
750+
retErr := txtMsg.SetDoubleProperty(propName, propValue)
751+
assert.Nil(t, retErr)
752+
gotPropValue, propErr = txtMsg.GetDoubleProperty(propName)
753+
assert.Nil(t, propErr)
754+
assert.Equal(t, propValue, gotPropValue)
755+
assert.Equal(t, msgBody, *txtMsg.GetText())
756+
propExists, propErr = txtMsg.PropertyExists(propName)
757+
assert.Nil(t, propErr)
758+
assert.True(t, propExists) // now exists
759+
760+
propName2 := "myProperty2"
761+
propValue2 := float64(-246810.2255343676)
762+
retErr = txtMsg.SetDoubleProperty(propName2, propValue2)
763+
assert.Nil(t, retErr)
764+
gotPropValue, propErr = txtMsg.GetDoubleProperty(propName2)
765+
assert.Nil(t, propErr)
766+
assert.Equal(t, propValue2, gotPropValue)
767+
768+
// Set a property then try to "unset" it by setting to 0
769+
unsetPropName := "mySendThenRemovedString"
770+
unsetPropValue := float64(12345.123456)
771+
retErr = txtMsg.SetDoubleProperty(unsetPropName, unsetPropValue)
772+
assert.Nil(t, retErr)
773+
gotPropValue, propErr = txtMsg.GetDoubleProperty(unsetPropName)
774+
assert.Nil(t, propErr)
775+
assert.Equal(t, unsetPropValue, gotPropValue)
776+
retErr = txtMsg.SetDoubleProperty(unsetPropName, 0)
777+
assert.Nil(t, retErr)
778+
gotPropValue, propErr = txtMsg.GetDoubleProperty(unsetPropName)
779+
assert.Nil(t, propErr)
780+
assert.Equal(t, float64(0), gotPropValue)
781+
782+
// Set up objects for send/receive
783+
queue := context.CreateQueue("DEV.QUEUE.1")
784+
consumer, errCons := context.CreateConsumer(queue)
785+
if consumer != nil {
786+
defer consumer.Close()
787+
}
788+
assert.Nil(t, errCons)
789+
790+
// Now send the message and get it back again, to check that it roundtripped.
791+
errSend := context.CreateProducer().SetTimeToLive(10000).Send(queue, txtMsg)
792+
assert.Nil(t, errSend)
793+
794+
rcvMsg, errRvc := consumer.ReceiveNoWait()
795+
assert.Nil(t, errRvc)
796+
assert.NotNil(t, rcvMsg)
797+
798+
switch msg := rcvMsg.(type) {
799+
case jms20subset.TextMessage:
800+
assert.Equal(t, msgBody, *msg.GetText())
801+
default:
802+
assert.Fail(t, "Got something other than a text message")
803+
}
804+
805+
// Check property is available on received message.
806+
gotPropValue, propErr = rcvMsg.GetDoubleProperty(propName)
807+
assert.Nil(t, propErr)
808+
assert.Equal(t, propValue, gotPropValue)
809+
propExists, propErr = txtMsg.PropertyExists(propName)
810+
assert.Nil(t, propErr)
811+
assert.True(t, propExists) // now exists
812+
813+
gotPropValue, propErr = rcvMsg.GetDoubleProperty(propName2)
814+
assert.Nil(t, propErr)
815+
assert.Equal(t, propValue2, gotPropValue)
816+
817+
// Properties that are not set should return nil
818+
gotPropValue, propErr = rcvMsg.GetDoubleProperty("nonExistentProperty")
819+
assert.Nil(t, propErr)
820+
assert.Equal(t, float64(0), gotPropValue)
821+
gotPropValue, propErr = rcvMsg.GetDoubleProperty(unsetPropName)
822+
assert.Nil(t, propErr)
823+
assert.Equal(t, float64(0), gotPropValue)
824+
propExists, propErr = txtMsg.PropertyExists(unsetPropName)
825+
assert.Nil(t, propErr)
826+
assert.True(t, propExists) // exists, even though it is set to zero
827+
828+
}

mqjms/MessageImpl.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,65 @@ func (msg *MessageImpl) GetIntProperty(name string) (int, jms20subset.JMSExcepti
405405
return valueRet, retErr
406406
}
407407

408+
// SetDoubleProperty enables an application to set a double-type (float64) message property.
409+
func (msg *MessageImpl) SetDoubleProperty(name string, value float64) jms20subset.JMSException {
410+
var retErr jms20subset.JMSException
411+
412+
var linkedErr error
413+
414+
smpo := ibmmq.NewMQSMPO()
415+
pd := ibmmq.NewMQPD()
416+
417+
linkedErr = msg.msgHandle.SetMP(smpo, name, pd, value)
418+
419+
if linkedErr != nil {
420+
rcInt := int(linkedErr.(*ibmmq.MQReturn).MQRC)
421+
errCode := strconv.Itoa(rcInt)
422+
reason := ibmmq.MQItoString("RC", rcInt)
423+
retErr = jms20subset.CreateJMSException(reason, errCode, linkedErr)
424+
}
425+
426+
return retErr
427+
}
428+
429+
// GetDoubleProperty returns the double (float64) value of a named message property.
430+
// Returns 0 if the named property is not set.
431+
func (msg *MessageImpl) GetDoubleProperty(name string) (float64, jms20subset.JMSException) {
432+
433+
var valueRet float64
434+
var retErr jms20subset.JMSException
435+
436+
impo := ibmmq.NewMQIMPO()
437+
pd := ibmmq.NewMQPD()
438+
439+
_, value, err := msg.msgHandle.InqMP(impo, pd, name)
440+
441+
if err == nil {
442+
switch valueTyped := value.(type) {
443+
case float64:
444+
valueRet = valueTyped
445+
default:
446+
// TODO - other conversions
447+
//fmt.Println("Other type", value, reflect.TypeOf(value))
448+
}
449+
} else {
450+
451+
mqret := err.(*ibmmq.MQReturn)
452+
if mqret.MQRC == ibmmq.MQRC_PROPERTY_NOT_AVAILABLE {
453+
// This indicates that the requested property does not exist.
454+
// valueRet will remain with its default value of nil
455+
return 0, nil
456+
} else {
457+
// Err was not nil
458+
rcInt := int(mqret.MQRC)
459+
errCode := strconv.Itoa(rcInt)
460+
reason := ibmmq.MQItoString("RC", rcInt)
461+
retErr = jms20subset.CreateJMSException(reason, errCode, mqret)
462+
}
463+
}
464+
return valueRet, retErr
465+
}
466+
408467
// PropertyExists returns true if the named message property exists on this message.
409468
func (msg *MessageImpl) PropertyExists(name string) (bool, jms20subset.JMSException) {
410469

0 commit comments

Comments
 (0)