Skip to content

Commit ac74116

Browse files
committed
Instrument JmsTemplate#sendAndReceive
Prior to this commit, the `JmsTemplate#sendAndReceive` method would not instrument the JMS session. This means that no metric would be recorded when sending the message and no trace would be propagated downstream. This commit ensures that the JMS session is instrumented in this case as well. Note, the reception of the response message does not create a `"jms.message.process"` observation as the session is only receiving the message, no listener has been configured on the message consumer. Fixes gh-32606
1 parent c5590ae commit ac74116

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

spring-jms/src/main/java/org/springframework/jms/core/JmsTemplate.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -971,6 +971,9 @@ private <T> T executeLocal(SessionCallback<T> action, boolean startConnection) t
971971
try {
972972
con = createConnection();
973973
session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
974+
if (micrometerJakartaPresent && this.observationRegistry != null) {
975+
session = MicrometerInstrumentation.instrumentSession(session, this.observationRegistry);
976+
}
974977
if (startConnection) {
975978
con.start();
976979
}

spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateObservationTests.java

+54-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,9 +20,14 @@
2020
import java.util.concurrent.TimeUnit;
2121

2222
import io.micrometer.observation.tck.TestObservationRegistry;
23+
import jakarta.jms.Destination;
24+
import jakarta.jms.JMSException;
25+
import jakarta.jms.Message;
2326
import jakarta.jms.MessageConsumer;
27+
import jakarta.jms.Session;
2428
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
2529
import org.apache.activemq.artemis.junit.EmbeddedActiveMQExtension;
30+
import org.assertj.core.api.Assertions;
2631
import org.junit.jupiter.api.AfterEach;
2732
import org.junit.jupiter.api.BeforeEach;
2833
import org.junit.jupiter.api.Test;
@@ -81,6 +86,54 @@ void shouldRecordJmsProcessObservations() {
8186
.hasHighCardinalityKeyValue("messaging.destination.name", "spring.test.observation");
8287
}
8388

89+
@Test
90+
void shouldRecordJmsPublishAndProcessObservations() throws Exception {
91+
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
92+
jmsTemplate.setObservationRegistry(registry);
93+
94+
new Thread(() -> {
95+
jmsTemplate.execute(session -> {
96+
try {
97+
CountDownLatch latch = new CountDownLatch(1);
98+
MessageConsumer mc = session.createConsumer(session.createQueue("spring.test.observation"));
99+
mc.setMessageListener(message -> {
100+
try {
101+
Destination jmsReplyTo = message.getJMSReplyTo();
102+
jmsTemplate.send(jmsReplyTo, new MessageCreator() {
103+
@Override
104+
public Message createMessage(Session session) throws JMSException {
105+
latch.countDown();
106+
return session.createTextMessage("response content");
107+
}
108+
});
109+
}
110+
catch (JMSException e) {
111+
throw new RuntimeException(e);
112+
}
113+
});
114+
return latch.await(2, TimeUnit.SECONDS);
115+
}
116+
catch (InterruptedException e) {
117+
throw new RuntimeException(e);
118+
}
119+
}, true);
120+
121+
}).start();
122+
Message response = jmsTemplate.sendAndReceive("spring.test.observation", new MessageCreator() {
123+
@Override
124+
public Message createMessage(Session session) throws JMSException {
125+
return session.createTextMessage("request content");
126+
}
127+
});
128+
129+
String responseBody = response.getBody(String.class);
130+
Assertions.assertThat(responseBody).isEqualTo("response content");
131+
132+
assertThat(registry).hasNumberOfObservationsWithNameEqualTo("jms.message.publish", 2);
133+
assertThat(registry).hasObservationWithNameEqualTo("jms.message.process").that()
134+
.hasHighCardinalityKeyValue("messaging.destination.name", "spring.test.observation");
135+
}
136+
84137
@AfterEach
85138
void shutdownServer() {
86139
connectionFactory.close();

0 commit comments

Comments
 (0)