Невозможно записать в раздел служебной шины 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)