Spring Boot JmsConfig for Azure Service Bus

850 Views Asked by At

I am developing a Spring Boot producer that sends data to Azure Service Bus. The project is currently running on version 2.2.11.RELEASE. However, I encountered a roadblock when I realized that there is no Azure Service Bus library support for this version. Azure Service Bus support begins from version 2.5.0 and above. Since upgrading to a newer Spring Boot version poses significant challenges, I decided to implement the producer using JMS to send data to Azure Service Bus.

I have successfully implemented a similar exercise in our new project using ServiceBusSenderClient, which works flawlessly with the latest Spring Boot versions. Unfortunately, achieving the same functionality with Spring Boot 2.2.11-RELEASE has proven to be a challenge. This is why I turned to JMS as an alternative.

Below is what I have done and tried so far

application.yml

spring
  jms:
    servicebus:
      connection-string: ${AZURE_ENDPOINT}
      topic: ${TOPIC}
      topic-client-id: ${TOPIC_CLIENT_ID}
      pricing-tier: standard

below are new dependencies I added in my build.gradle

implementation 'com.azure.spring:spring-cloud-azure-starter-servicebus-jms:5.5.0'
implementation 'com.microsoft.azure:azure-servicebus-jms:2.0.6'
implementation 'org.springframework.boot:spring-boot-starter-activemq'

Part of code implementation

    @Autowired
    private JmsTemplate ***jmsTemplate***;
        List<TradeEntity> tradeEntityList = eventsToBeSent.stream().map(DisruptionEventEntity::getTrade).distinct().collect(Collectors.toList());
        List<String> dateList = eventsToBeSent.stream().map(
                DisruptionEventEntity::getMeasureDate).distinct().collect(Collectors.toList());

            for (String date1: dateList){
                SendMeasureRequestPayload sendMeasureRequestPayload =
                        new SendMeasureRequestPayload(sendMeasureValues,date1,"Daily")
                        
                    if (!CollectionUtils.isEmpty(eventEntities)){
                        if (tradeEntity.getSfmConfiguration() !=null){
                            List<SendMeasureValues> measureValues = getMeasureValues(sfmConfiguration, sfmMeasureDTO);
                            sendMeasureValues.addAll(measureValues);
                            sendMeasureRequestPayload.setValues(sendMeasureValues);
                        }
                    }
                }

                log.info("Sending Data ...... {}", topic);
                jmsTemplate.send(topic,session -> session.createTextMessage(sendMeasureRequestPayload.toString())); // code to send data
                
            }

My Struggle is on the JmsConfig class and I would love any assistance that one could assist with

Below is the piece of code I tried but since I am using azure service bus it's not working because it's expecting an endpoint with tcp at the beging

@Configuration
@EnableJms
public class **JmsConfig** {

    @Value("${spring.jms.service.connection-string}")
    private String connectionString;
    @Value("${app.azure.service-bus.topic}")
    private String topic;

    @Bean
    public MessageConverter jacksonJmsMessageConverter(){
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTargetType(MessageType.TEXT);
        converter.setTypeIdPropertyName("_type");
        return converter;
    }

    @Bean
    public ActiveMQConnectionFactory amqConnectionFactory(){
        return new ActiveMQConnectionFactory(connectionString);
    }

    @Bean
    public CachingConnectionFactory connectionFactory(){
        return new CachingConnectionFactory(amqConnectionFactory());
    }

    @Bean
    public JmsTemplate jmsTemplate(){
        JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory());
        jmsTemplate.setDefaultDestinationName(topic);
        jmsTemplate.setConnectionFactory(connectionFactory());
        jmsTemplate.setMessageConverter(jacksonJmsMessageConverter());
        return jmsTemplate;
    }
}

Your guidance would be very appreciated thanks

1

There are 1 best solutions below

0
Balaji On

Spring Boot always using same SPRING-DATASOURCE-USERNAME & SPRING-DATASOURCE-PASSWORD from Azure Key Vault for two separate application

Azure Service Bus uses its own proprietary protocol for communication, so you can’t use the ActiveMQConnectionFactory for this purpose. Instead, use the Azure Service Bus JMS library for configuration. configure JMS to work with Azure Service Bus in the Spring Boot 2.2.11-RELEASE application.

  • Remove the org.springframework.boot:spring-boot-starter-activemq dependency from your build.gradle as you won’t be using ActiveMQ for Azure Service Bus.

  • Update the JmsConfig class to configure JMS for Azure Service Bus. Use the ServiceBusJMSConnectionFactory provided by the Azure Service Bus JMS library.

import com.microsoft.azure.servicebus.jms.ServiceBusJMSConnectionFactory;
import com.microsoft.azure.servicebus.jms.ServiceBusJMSClientConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;

@Configuration
public class JmsConfig {

    @Value("${spring.jms.servicebus.connection-string}")
    private String connectionString;
    @Value("${app.azure.service-bus.topic}")
    private String topic;

    @Bean
    public ServiceBusJMSConnectionFactory jmsConnectionFactory() {
        ServiceBusJMSClientConfig config = new ServiceBusJMSClientConfig();
        config.setConnectionString(connectionString);
        return new ServiceBusJMSConnectionFactory(config);
    }

    @Bean
    public JmsTemplate jmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate(jmsConnectionFactory());
        jmsTemplate.setDefaultDestinationName(topic);
        jmsTemplate.setMessageConverter(jacksonJmsMessageConverter());
        return jmsTemplate;
    }

    @Bean
    public MessageConverter jacksonJmsMessageConverter() {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTargetType(MessageType.TEXT);
        converter.setTypeIdPropertyName("_type");
        return converter;
    }
}

  • Now, I am able to send messages to an Azure Service Bus topic using JMS.

enter image description here