azure-sdk-for-java icon indicating copy to clipboard operation
azure-sdk-for-java copied to clipboard

[FEATURE REQ] ServiceBusReceivedMessage support for JSON Messages (VALUE)

Open dkellenb opened this issue 2 years ago • 3 comments

Is your feature request related to a problem? Please describe.

Sending to Azure Service Bus using Spring JMS, but receiving messages using azure-messaging-servicebus library, JSON messages gets decoded as AmqpMessageBody of type VALUE instead of DATA. This results in following exception:

com.azure.messaging.servicebus.ServiceBusException: This body type not is supported: VALUE

The payload being sent looks ok: image

And also the headers seems to be fine:

image

Describe the solution you'd like

  • It should be able to send simple json string messages and to be able to decode them, without need to send them as binary.
  • Either support VALUE or decode JSON String messages to byte[] so it can be handled as AmqpMessageBodyType.DATA
  • Or: Allow forcing to decode all messages to AmqpMessageBodyType.DATA

Describe alternatives you've considered

Alternative: Forcing the json to be sent as binary.

dkellenb avatar Aug 24 '23 14:08 dkellenb

@anuchandy could you please follow up?

joshfree avatar Aug 30 '23 17:08 joshfree

Hi @dkellenb thank you, we'll evaluate this feature request.

anuchandy avatar Aug 30 '23 17:08 anuchandy

For those who face the same issue with the latest version (5.4.0) is throwing com.azure.messaging.servicebus.ServiceBusException: This body type not is supported: VALUE when a message was sent to a topic using spring-cloud-azure-starter-servicebus-jms, but consumed from the topic by spring-cloud-azure-stream-binder-servicebus, they have following alternatives:

Alternative 1:

Use spring-cloud-azure-starter-servicebus-jms, which supports also AMQP messages of type VALUE

Alternative 2:

If you can influence the sender, then ask that messages are sent with MessageType.BYTES:

  @Bean
  MessageConverter jacksonMessageConverter(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
    MappingJackson2MessageConverter messageConverter = new MappingJackson2MessageConverter();
    messageConverter.setObjectMapper(jacksonObjectMapperBuilder.createXmlMapper(false).build());
    messageConverter.setTargetType(MessageType.BYTES);
    return messageConverter;
  }

Nevertheless, I would expect that spring-cloud-azure-stream-binder-servicebus should also support AMQP Messages of type VALUE.

dkellenb avatar Sep 06 '23 13:09 dkellenb

We’ve discussed this feature request within the cross-language team. Unfortunately, there is no formal plan for additional body types, the higher-level SDK across languages will support only data body type. For any other use cases, the application is required to encode the content as binary (byte[]) before sending, then have the application decode the binary (byte[]) to the suitable format upon receive. Closing this.

anuchandy avatar May 30 '24 14:05 anuchandy

Another option is, the application can obtain the raw value from the message and decode them appropriately, for example -

final AmqpAnnotatedMessage message = message.getRawAmqpMessage();
final AmqpMessageBody rBody = message.getBody();
if (rBody.getBodyType() == AmqpMessageBodyType.VALUE) {
    final Object value = rBody.getValue();
    System.out.println(value); // {"address": {"lane": "123", "city": "redmond"}}
    if (value instanceof String) {
      // Decode the value appropriately. For example, if you're expecting JSON 
      // then use a JSON parser (E.g. Jackson, Gson, Azure-Json) to parse and 
      // deserialize to a POJO.
    }
}

anuchandy avatar Jul 15 '24 23:07 anuchandy