为什么spring cloud stream在向Solace主题发布消息时不填充JMSMessageID? 问题概述
在我的项目中,我们尝试使用Spring Cloud Stream(SCS)连接到Solace。最终我们计划搬到卡夫卡。因此,使用SCS将帮助我们非常轻松地转移到卡夫卡,而无需任何代码更改和非常小的配置和依赖项更改 我们使用JMS使用Solace已有一段时间了。现在,当我们尝试使用SCS向Solace发布消息时,我们发现在消息中,一些关键的JMS头(JMSMessageID、JMSType、JMSPriority、JMSCorrelationID、JMSExpiration)是空白的 我们需要单独配置JMS头吗?如果是,如何进行 我已经试过了 我试图像这样设置标题,但这只会导致相同名称的重复标题为什么spring cloud stream在向Solace主题发布消息时不填充JMSMessageID? 问题概述,jms,spring-cloud-stream,solace,Jms,Spring Cloud Stream,Solace,在我的项目中,我们尝试使用Spring Cloud Stream(SCS)连接到Solace。最终我们计划搬到卡夫卡。因此,使用SCS将帮助我们非常轻松地转移到卡夫卡,而无需任何代码更改和非常小的配置和依赖项更改 我们使用JMS使用Solace已有一段时间了。现在,当我们尝试使用SCS向Solace发布消息时,我们发现在消息中,一些关键的JMS头(JMSMessageID、JMSType、JMSPriority、JMSCorrelationID、JMSExpiration)是空白的 我们需要单独
@输出(SendReport.TO_NMR)
公共无效发送消息(字符串请求){
log.info(“****************收到此报告请求:“+请求”);
MessageBuilder=MessageBuilder.withPayload(请求);
setHeader(“JMSType”、“报告请求”);
builder.setHeader(“JMSMessageId”、“1”);
builder.setHeader(“JMSCorrelationId”、“11”);
builder.setHeader(“JMSMessageID”、“4”);
builder.setHeader(“JMSCorrelationID”、“114”);
setHeader(“ApplicationMessageId”、“111”);
setHeader(“ApplicationMessageID”、“112”);
builder.setCorrelationId(“23434”);
Message=builder.build();
sendReport.output().send(消息);
}
Solace中消息的JMS头如下所示
JMSMessageID
JMSDestination TOPIC_NAME
JMSTimestamp Wed Dec 31 18:00:00 CST 1969
JMSType
JMSReplyTo
JMSCorrelationID
JMSExpiration 0
JMSPriority 0
JMSType nmr-report-request
JMSMessageId 1
JMSMessageID 4
_isJavaSerializedObject-contentType true
_isJavaSerializedObject-id true
solaceSpringCloudStreamBinderVersion 0.1.0
ApplicationMessageId 111
ApplicationMessageID 112
JMSCorrelationId 11
JMSCorrelationID 114
correlationId 23434
id [-84,-19,0,5,115,114,0,14,106,97,118,97,46,117,116,105,108,46,85,85,73,68,-68,-103,3,-9,-104,109,-123,47,2,0,2,74,0,12,108,101,97,115,116,83,105,103,66,105,116,115,74,0,11,109,111,115,116,83,105,103,66,105,116,115,120,112,13,-26,2,-51,111,-17,73,73,-18,-32,-26,-11,-46,-89,50,-37] (offset=377, length=80)
contentType [-84,-19,0,5,115,114,0,33,111,114,103,46,115,112,114,105,110,103,102,114,97,109,101,119,111,114,107,46,117,116,105,108,46,77,105,109,101,84,121,112,101,56,-76,29,-63,64,96,-36,-81,2,0,3,76,0,10,112,97,114,97,109,101,116,101,114,115,116,0,15,76,106,97,118,97,47,117,116,105,108,47,77,97,112,59,76,0,7,115,117,98,116,121,112,101,116,0,18,76,106,97,118] (offset=473, length=190)
timestamp 1555707627482
用于连接Solace的代码
弹簧靴主类
@springboot应用程序
@EnableDiscoveryClient
@Slf4j
@EnableBinding({SendReport.class})
公共类ReportServerApplication{
公共静态void main(最终字符串[]args){
ApplicationContext ctx=新类路径XmlApplicationContext(“ApplicationContext server.xml”);
新的SpringApplicationBuilder(ReportServerApplication.class).listeners(新环境PreparedListener()).run(args);
}
类将频道连接到主题:
公共接口发送报告{
字符串指向\u NMR=“solace poc outbound”;
@输出(SendReport.TO_NMR)
MessageChannel输出();
}
消息处理程序:
@Slf4j
@组成部分
@EnableBinding({SendReport.class})
公共类MessageHandler{
私人发送报告发送报告;
公共消息处理程序(SendReport SendReport){
this.sendReport=sendReport;
}
@输出(SendReport.TO_NMR)
公共无效发送消息(字符串请求){
log.info(“****************收到此报告请求:“+请求”);
var message=MessageBuilder.withPayload(request.build();
sendReport.output().send(消息);
}
}
用于配置的属性:application.yml
spring:
cloud:
# spring cloud stream binding
stream:
bindings:
solace-poc-outbound:
destination: TOPIC_NAME
contentType: text/plain
solace:
java:
host: tcp://xyz.abc.com
#port: xxx
msgVpn: yyy
clientUsername: aaa
使用的依赖项:
'org.springframework.cloud:spring-cloud-stream',
'com.solace.spring.cloud:spring-cloud-starter-stream-solace:1.1.+'
观察
- 预期结果:所有JMS头都应该由SCS填充
- 实际结果:未填充某些JMS头
消息
JavaDocs:
/** Sets the message ID.
*
* <P>This method is for use by JMS providers only to set this field
* when a message is sent. This message cannot be used by clients
* to configure the message ID. This method is public
* to allow a JMS provider to set this field when sending a message
* whose implementation is not its own.
*
* @param id the ID of the message
*
* @exception JMSException if the JMS provider fails to set the message ID
* due to some internal error.
*
* @see javax.jms.Message#getJMSMessageID()
*/
void
setJMSMessageID(String id) throws JMSException;
但是:这不是我们可以从应用程序级别控制的
可以从JmsSendingMessageHandler
填充优先级
、deliveryMode
和timeToLive
:
if (this.jmsTemplate instanceof DynamicJmsTemplate && this.jmsTemplate.isExplicitQosEnabled()) {
Integer priority = StaticMessageHeaderAccessor.getPriority(message);
if (priority != null) {
DynamicJmsTemplateProperties.setPriority(priority);
}
if (this.deliveryModeExpression != null) {
Integer deliveryMode =
this.deliveryModeExpression.getValue(this.evaluationContext, message, Integer.class);
if (deliveryMode != null) {
DynamicJmsTemplateProperties.setDeliveryMode(deliveryMode);
}
}
if (this.timeToLiveExpression != null) {
Long timeToLive = this.timeToLiveExpression.getValue(this.evaluationContext, message, Long.class);
if (timeToLive != null) {
DynamicJmsTemplateProperties.setTimeToLive(timeToLive);
}
}
}
JmsCorrelationID
必须由JmsHeaders.CORRELATION\u ID
填充。JmsHeaders.TYPE
分别填充JmsType
:
public void fromHeaders(MessageHeaders headers, javax.jms.Message jmsMessage) {
try {
Object jmsCorrelationId = headers.get(JmsHeaders.CORRELATION_ID);
if (jmsCorrelationId instanceof Number) {
jmsCorrelationId = jmsCorrelationId.toString();
}
if (jmsCorrelationId instanceof String) {
try {
jmsMessage.setJMSCorrelationID((String) jmsCorrelationId);
}
catch (Exception e) {
this.logger.info("failed to set JMSCorrelationID, skipping", e);
}
}
Object jmsReplyTo = headers.get(JmsHeaders.REPLY_TO);
if (jmsReplyTo instanceof Destination) {
try {
jmsMessage.setJMSReplyTo((Destination) jmsReplyTo);
}
catch (Exception e) {
this.logger.info("failed to set JMSReplyTo, skipping", e);
}
}
Object jmsType = headers.get(JmsHeaders.TYPE);
if (jmsType instanceof String) {
try {
jmsMessage.setJMSType((String) jmsType);
}
catch (Exception e) {
this.logger.info("failed to set JMSType, skipping", e);
}
}
有关更多信息,请参阅
DefaultJmsHeaderMapper
。请参阅JMSMessage
JavaDocs:
/** Sets the message ID.
*
* <P>This method is for use by JMS providers only to set this field
* when a message is sent. This message cannot be used by clients
* to configure the message ID. This method is public
* to allow a JMS provider to set this field when sending a message
* whose implementation is not its own.
*
* @param id the ID of the message
*
* @exception JMSException if the JMS provider fails to set the message ID
* due to some internal error.
*
* @see javax.jms.Message#getJMSMessageID()
*/
void
setJMSMessageID(String id) throws JMSException;
但是:这不是我们可以从应用程序级别控制的
可以从JmsSendingMessageHandler
填充优先级
、deliveryMode
和timeToLive
:
if (this.jmsTemplate instanceof DynamicJmsTemplate && this.jmsTemplate.isExplicitQosEnabled()) {
Integer priority = StaticMessageHeaderAccessor.getPriority(message);
if (priority != null) {
DynamicJmsTemplateProperties.setPriority(priority);
}
if (this.deliveryModeExpression != null) {
Integer deliveryMode =
this.deliveryModeExpression.getValue(this.evaluationContext, message, Integer.class);
if (deliveryMode != null) {
DynamicJmsTemplateProperties.setDeliveryMode(deliveryMode);
}
}
if (this.timeToLiveExpression != null) {
Long timeToLive = this.timeToLiveExpression.getValue(this.evaluationContext, message, Long.class);
if (timeToLive != null) {
DynamicJmsTemplateProperties.setTimeToLive(timeToLive);
}
}
}
JmsCorrelationID
必须由JmsHeaders.CORRELATION\u ID
填充。JmsHeaders.TYPE
分别填充JmsType
:
public void fromHeaders(MessageHeaders headers, javax.jms.Message jmsMessage) {
try {
Object jmsCorrelationId = headers.get(JmsHeaders.CORRELATION_ID);
if (jmsCorrelationId instanceof Number) {
jmsCorrelationId = jmsCorrelationId.toString();
}
if (jmsCorrelationId instanceof String) {
try {
jmsMessage.setJMSCorrelationID((String) jmsCorrelationId);
}
catch (Exception e) {
this.logger.info("failed to set JMSCorrelationID, skipping", e);
}
}
Object jmsReplyTo = headers.get(JmsHeaders.REPLY_TO);
if (jmsReplyTo instanceof Destination) {
try {
jmsMessage.setJMSReplyTo((Destination) jmsReplyTo);
}
catch (Exception e) {
this.logger.info("failed to set JMSReplyTo, skipping", e);
}
}
Object jmsType = headers.get(JmsHeaders.TYPE);
if (jmsType instanceof String) {
try {
jmsMessage.setJMSType((String) jmsType);
}
catch (Exception e) {
this.logger.info("failed to set JMSType, skipping", e);
}
}
有关更多信息,请参见DefaultJmsHeaderMapper