Невозможно записать в раздел служебной шины Azure из приложения Spring Boot с помощью azure-servicebus-jms-spring-boot-starter

Я пытаюсь отправить сообщение в тему служебной шины Azure, используя JMS в Spring Boot.

Как вы можете видеть ниже, я вытащил зависимость для azure-servicebus-jms-spring-boot-starter

я настроил @EnableJmsв моем приложении, и я также установил строку подключения в моем файле application.yml, который я проверил правильно, и я вижу, что он правильно подключается к служебной шине, как видно из этих журналов -

      2020-12-15 13:36:18.431  INFO 4487 --- [windows.net:-1]] o.a.qpid.jms.sasl.SaslMechanismFinder    : Best match for SASL auth was: SASL-PLAIN
2020-12-15 13:36:18.704  INFO 4487 --- [windows.net:-1]] org.apache.qpid.jms.JmsConnection        : Connection ID:MY_CONNECTION connected to remote Broker: amqps://**-****-*****.servicebus.windows.net

Как только это соединение установлено, я пытаюсь отправить сообщение в тему на моей служебной шине, используя службу, которую я указал ниже, однако я не вижу транзакции в служебной шине. Я проверил правильность пункта назначения.

Поскольку я не использую подписку на это приложение, я не указал spring.jms.servicebus.topic-client-id=<ServiceBusSubscriptionID>как указано здесь

На стороне потребления, где я указал идентификатор клиента темы (другое приложение), я создал фиктивный контроллер для отправки образца сообщения в служебную шину, и он отлично работает, что заставило бы меня поверить, что мне не хватает некоторой конфигурации в этом приложении. .

Однако мне не нужно указывать здесь какой-либо конкретный идентификатор клиента темы, поскольку я хочу только нажать на тему. Как только у меня будет строка подключения к служебной шине, я смогу отправлять сообщения в любую указанную мной тему - jmsTemplate.convertAndSend(<TOPIC_NAME>, <MESSAGE>)

      @Service
class MessageServiceImpl : MessageService {

    private val logger: Logger = LoggerFactory.getLogger(this.javaClass)

    @Autowired
    lateinit var jmsTemplate: JmsTemplate

    override fun sendMessage(topic: Topic, message: Message): Result<Unit> = Result {
        logger.info("Sending message $message to topic ${topic.destination}")
        jmsTemplate.convertAndSend(topic.destination, message)
    }
}

enum class Topic(val destination: String) {
    AWARDS("awards")
}

open class Message(
    val eventTrigger: String,
    val eventTriggeredBy: String,
    val eventTimestamp: LocalDateTime,
    val eventSourceSystem: String
)
        jms:
    servicebus:
      connection-string: ${JMS_CONNECTION_STRING:''}
      idle-timeout: 180000
      compile 'com.microsoft.azure:azure-servicebus-jms-spring-boot-starter:2.2.5'
      @SpringBootApplication
@EnableJms
class WebServiceApplication {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            SpringApplication.run(WebServiceApplication::class.java, *args)
        }
    }
}

1 ответ

Причина, по которой мне не удалось отправить сообщение, указанное в назначении данной темы, заключалась в том, что мой класс Message не был сериализуемым. В результате запрос jms не выполнялся.

Есть два возможных решения проблемы, которую я имел выше.

Первый — сериализовать объект, как я уже упоминал —

      open class Message(
    val eventTrigger: String,
    val eventTriggeredBy: String,
    val eventTimestamp: LocalDateTime,
    val eventSourceSystem: String
) : Serializable

Однако есть одна основная проблема с этим подходом.

      open class Message(
    val eventTrigger: String,
    val eventTriggeredBy: String,
    val eventTimestamp: LocalDateTime,
    val eventSourceSystem: String,
    val newField: NewField
) : Serializable

data class NewField(val sampleField: String)

Например, если вы добавите новое поле, которое не является сериализуемым, то этот класс Message не будет сериализуемым, и запросы снова перестанут работать (это может быть неприятно, поскольку вы можете не знать, что сломали его, пока позже!)

Однако существует второе возможное решение, заключающееся в маршалировании класса в json и отправке сообщения в виде строки. Это решение более полное, чем его сериализация.

      val jsonMessage = ObjectMapper().writeValueAsString(message)
jmsTemplate.convertAndSend(topic.destination, jsonMessage)

Другие вопросы по тегам