2

I have a Springboot application using Apache Camel AMQP component to comsume messages from a Solace Queue. To send a message to the Queue I use Postman and the Solace REST API. In order to differentiate the message type I add Content-Type to the header of the Http request in Postman. I used SDKPerf to check the message header consumed from solace and the message header is found under "HTTP Content Type" along with other headers.

However, I can't seem to find a way to get this Content-Type from Camel Side. In the documentation it says

String header = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class);

However this always produces null. Any Ideas how to get the message properties in Camel?

MostafaBakr
  • 107
  • 11
  • 1
    Did you check you really have the header set using SDKPerf for example : HOST=tcp://host:port USER=user@messageVPN PASS=password CC=1 cd ../../pubSubTools/ ./sdkperf_c -cip=$HOST -cu=$USER -cp=$PASS -stl="your/topic/address" -cc=$CC -asw=255 -md cd - the -md flag would dump payload and headers to the command line output – Thomas Jan 18 '23 at 09:33
  • Yes, I checked using SDKPerf like you suggested and found the header set. HTTP Content Type has the header value, but how to get that in apache Camel – MostafaBakr Jan 18 '23 at 13:34

2 Answers2

2

EDIT: I think it's actually due to the fact that Camel is using QPid JMS, and there is no JMS API way of getting the Content Type, it's not in the spec. Even though AMQP 1.0 does support content-type as a property. But yeah, my suggestion of a custom property below is still probably the way I would go.


Edited for clarity & corrections. TL/DR: use a custom user property header.

The SMF Content Type header in the original (REST) message is passed through to the consumed AMQP message as a property content-type, however the JMS API spec does not expose this; there is no way in standard JMS to retrieve this value. It is, however, used by the broker to set the type of message (e.g. TextMessage). Check "Content-Type Mapping to Solace Message Types" in the Solace docs.

Using Solace's SDKPerf AMQP JMS edition to dump the received message to console (note this uses QPid libraries):

./sdkperf_jmsamqp.sh -cip=amqp://localhost:5672 -stl=a/b/c
 -md -q

curl http://localhost:9000/TOPIC/a/b/c -d 'hello' -H 'Content-Type: text'

^^^^^^^^^^^^^^^^^^ Start Message ^^^^^^^^^^^^^^^^^^^^^^^^^^^
JMSDeliveryMode:                        PERSISTENT
JMSDestination:                         a/b/c
JMSExpiration:                          0
JMSPriority:                            4
JMSTimestamp:                           0
JMSRedelivered:                         false
JMSCorrelationID:                       null
JMSMessageID:                           null
JMSReplyTo:                             null
JMSType:                                null
JMSProperties:                          {JMSXDeliveryCount:1;}
Object Type:                            TextMessage
Text:                                   len=5
  hello

The header does not get mapped through, but does get used to set the message type. If I remove that HTTP header, the received AMQP message is binary. But since other types of Content-Types also map to TextMessages (e.g. application/json, application/xml, etc.), the fact you're receiving a TextMessage is not enough to infer exactly what Content-Type you published your REST message with.

For completeness, I used WireShark with an AMQP decoder, and you can see the header present on the received AMQP message:

Frame 3: 218 bytes on wire (1744 bits), 218 bytes captured (1744 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 5672, Dst Port: 60662, Seq: 2, Ack: 1, Len: 174
Advanced Message Queueing Protocol
    Length: 174
    Doff: 2
    Type: AMQP (0)
    Channel: 2
    Performative: transfer (20)
    Arguments (5)
    Message-Header
        Durable: True
    Message-Annotations (map of 1 element)
        x-opt-jms-dest (byte): 1
    Message-Properties
        To: a/b/c
        Content-Type: text                       <----------
    Application-Properties (map of 1 element)
        AaronEncoding (str8-utf8): CustomText
    AMQP-Value (str32-utf8): hello

So my suggestion is this:

Set an additional custom header, a User Property, which will get passed through to the AMQP message:

curl http://localhost:9000/TOPIC/a/b/c -d 'hello' -H 'Solace-User-Property-AaronEncoding: CustomText' -H 'Content-Type: text'

JMSDestination:                         a/b/c
JMSProperties:                          {AaronEncoding:CustomText;JMSXDeliveryCount:1;}
Object Type:                            TextMessage
Text:                                   len=5
  hello

My always-goto guide for Solace REST interactions: https://docs.solace.com/API/RESTMessagingPrtl/Solace-REST-Message-Encoding.htm

Hope that helps!

Aaron
  • 551
  • 2
  • 10
1

It may have a different name in Camel. Try either printing all the headers or stop it in the debugger and examine the incoming message.

Steve Huston
  • 1,432
  • 13
  • 20