Refactored Stomp Propagation Channel tests
This commit is contained in:
@@ -16,10 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
@@ -27,6 +23,10 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
import org.springframework.messaging.simp.SimpMessageType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Builder class to create STOMP message
|
||||
*
|
||||
@@ -77,16 +77,13 @@ public class StompMessageBuilder {
|
||||
|
||||
public Message<?> build() {
|
||||
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
|
||||
String key;
|
||||
Object value;
|
||||
for (Map.Entry<String, Object> entry : this.headers.entrySet()) {
|
||||
key = entry.getKey();
|
||||
String key = entry.getKey();
|
||||
if (key != null) {
|
||||
value = entry.getValue();
|
||||
Object value = entry.getValue();
|
||||
pushHeaders(headerAccessor, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return org.springframework.messaging.support.MessageBuilder.createMessage(this.message.getPayload(),
|
||||
headerAccessor.getMessageHeaders());
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
@@ -31,6 +29,8 @@ import org.springframework.messaging.support.ChannelInterceptorAdapter;
|
||||
import org.springframework.messaging.support.ExecutorChannelInterceptor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gaurav Rai Mazra
|
||||
@@ -51,9 +51,7 @@ public class TraceStompMessageContextPropagationChannelInterceptor extends Chann
|
||||
if (DirectChannel.class.isAssignableFrom(AopUtils.getTargetClass(channel))) {
|
||||
return message;
|
||||
}
|
||||
|
||||
Span span = this.traceManager.getCurrentSpan();
|
||||
|
||||
if (span != null) {
|
||||
return new MessageWithSpan(message, span);
|
||||
} else {
|
||||
@@ -66,7 +64,7 @@ public class TraceStompMessageContextPropagationChannelInterceptor extends Chann
|
||||
if (message instanceof MessageWithSpan) {
|
||||
MessageWithSpan messageWithSpan = (MessageWithSpan) message;
|
||||
Message<?> messageToHandle = messageWithSpan.message;
|
||||
populatePropagatedContext(messageWithSpan.span, messageToHandle, channel);
|
||||
populatePropagatedContext(messageWithSpan.span);
|
||||
|
||||
return message;
|
||||
}
|
||||
@@ -83,7 +81,7 @@ public class TraceStompMessageContextPropagationChannelInterceptor extends Chann
|
||||
return postReceive(message, channel);
|
||||
}
|
||||
|
||||
protected void populatePropagatedContext(Span span, Message<?> message, MessageChannel channel) {
|
||||
protected void populatePropagatedContext(Span span) {
|
||||
if (span != null) {
|
||||
ORIGINAL_CONTEXT.set(this.traceManager.continueSpan(span).getSavedTrace());
|
||||
}
|
||||
@@ -116,11 +114,9 @@ public class TraceStompMessageContextPropagationChannelInterceptor extends Chann
|
||||
span.addAnnotation(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
Object payload = message.getPayload();
|
||||
if (payload != null) {
|
||||
span.addAnnotation("/messaging/payload/type", payload.getClass().getCanonicalName());
|
||||
|
||||
if (payload instanceof String) {
|
||||
span.addAnnotation("/messaging/payload/size", String.valueOf(((String) payload).length()));
|
||||
} else if (payload instanceof byte[]) {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceManager;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.ExecutorSubscribableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
abstract class AbstractTraceStompIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("executorSubscribableChannel")
|
||||
ExecutorSubscribableChannel channel;
|
||||
@Autowired TraceManager traceManager;
|
||||
@Autowired StompMessageHandler stompMessageHandler;
|
||||
@Autowired AlwaysSampler sampler;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
this.channel.subscribe(stompMessageHandler);
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
this.channel.unsubscribe(stompMessageHandler);
|
||||
}
|
||||
|
||||
Trace givenALocallyStartedSpan() {
|
||||
return traceManager.startSpan("testSendMessage", sampler, null);
|
||||
}
|
||||
|
||||
Message<?> givenMessageToBeSampled() {
|
||||
return StompMessageBuilder.fromMessage(new GenericMessage<>("Message2")).build();
|
||||
}
|
||||
|
||||
void whenTheMessageWasSent(Message<?> message) {
|
||||
this.channel.send(message);
|
||||
then(stompMessageHandler.message).isNotNull();
|
||||
}
|
||||
|
||||
String thenSpanIdFromHeadersIsNotEmpty() {
|
||||
String header = getValueFromHeaders(Trace.SPAN_ID_NAME);
|
||||
then(header).as("Span id should not be empty").isNotEmpty();
|
||||
return header;
|
||||
}
|
||||
|
||||
String thenTraceIdFromHeadersIsNotEmpty() {
|
||||
String header = getValueFromHeaders(Trace.TRACE_ID_NAME);
|
||||
then(header).as("Trace id should not be empty").isNotEmpty();
|
||||
return header;
|
||||
}
|
||||
|
||||
String getValueFromHeaders(String headerName) {
|
||||
return stompMessageHandler.message.getHeaders().get(headerName, String.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
|
||||
class StompMessageHandler implements MessageHandler {
|
||||
|
||||
Message<?> message;
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -35,27 +35,10 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* @author Gaurav Rai Mazra
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
|
||||
@SpringApplicationConfiguration(classes = TestApplication.class)
|
||||
@IntegrationTest
|
||||
public class TraceStompMessageChannelInterceptorTests {
|
||||
@Autowired
|
||||
@Qualifier("executorSubscribableChannel")
|
||||
private ExecutorSubscribableChannel channel;
|
||||
|
||||
@Autowired TraceManager traceManager;
|
||||
@Autowired StompMessageHandler stompMessageHandler;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
this.channel.subscribe(stompMessageHandler);
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
this.channel.unsubscribe(stompMessageHandler);
|
||||
}
|
||||
public class TraceStompMessageChannelInterceptorTests extends AbstractTraceStompIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void should_not_create_span_if_message_contains_not_sampled_header() {
|
||||
@@ -93,49 +76,20 @@ public class TraceStompMessageChannelInterceptorTests {
|
||||
then(TraceContextHolder.getCurrentTrace()).isNull();
|
||||
}
|
||||
|
||||
private Trace givenALocallyStartedSpan() {
|
||||
return traceManager.startSpan("testSendMessage", new AlwaysSampler(), null);
|
||||
}
|
||||
|
||||
private Message<?> givenMessageNotToBeSampled() {
|
||||
return StompMessageBuilder.fromMessage(new GenericMessage<>("Message2")).setHeader(Trace.NOT_SAMPLED_NAME, "").build();
|
||||
}
|
||||
|
||||
private Message<?> givenMessageToBeSampled() {
|
||||
return StompMessageBuilder.fromMessage(new GenericMessage<>("Message2")).build();
|
||||
}
|
||||
|
||||
private void whenTheMessageWasSent(Message<?> message) {
|
||||
this.channel.send(message);
|
||||
then(stompMessageHandler.message).isNotNull();
|
||||
}
|
||||
|
||||
private String thenSpanIdFromHeadersIsEmpty() {
|
||||
String header = getValueFromHeaders(Trace.SPAN_ID_NAME);
|
||||
then(header).as("Span id should be empty").isNullOrEmpty();
|
||||
return header;
|
||||
}
|
||||
|
||||
private String thenSpanIdFromHeadersIsNotEmpty() {
|
||||
String header = getValueFromHeaders(Trace.SPAN_ID_NAME);
|
||||
then(header).as("Span id should not be empty").isNotEmpty();
|
||||
return header;
|
||||
}
|
||||
|
||||
private String thenTraceIdFromHeadersIsNotEmpty() {
|
||||
String header = getValueFromHeaders(Trace.TRACE_ID_NAME);
|
||||
then(header).as("Trace id should not be empty").isNotEmpty();
|
||||
return header;
|
||||
}
|
||||
|
||||
private void thenReceivedMessageIsEqualToTheSentOne(Message<?> message) {
|
||||
then(message.getPayload()).isEqualTo(stompMessageHandler.message.getPayload());
|
||||
}
|
||||
|
||||
private String getValueFromHeaders(String headerName) {
|
||||
return stompMessageHandler.message.getHeaders().get(headerName, String.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
static class TestApplication {
|
||||
@@ -154,14 +108,4 @@ public class TraceStompMessageChannelInterceptorTests {
|
||||
return new AlwaysSampler();
|
||||
}
|
||||
}
|
||||
|
||||
static class StompMessageHandler implements MessageHandler {
|
||||
|
||||
Message<?> message;
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,22 @@
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceManager;
|
||||
import org.springframework.cloud.sleuth.instrument.integration.TraceStompMessageContextPropagationChannelInterceptorTests.TestApplication;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.support.ExecutorSubscribableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
@@ -34,78 +27,47 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes=TestApplication.class)
|
||||
@IntegrationTest
|
||||
public class TraceStompMessageContextPropagationChannelInterceptorTests implements MessageHandler {
|
||||
@Autowired
|
||||
@Qualifier("executorSubscribableChannel")
|
||||
private ExecutorSubscribableChannel channel;
|
||||
public class TraceStompMessageContextPropagationChannelInterceptorTests extends AbstractTraceStompIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private TraceManager traceManager;
|
||||
|
||||
@Autowired
|
||||
private AlwaysSampler sampler;
|
||||
|
||||
private Message<?> message;
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@org.junit.Before
|
||||
public void init() {
|
||||
this.channel.subscribe(this);
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
this.channel.unsubscribe(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpanPropagation() {
|
||||
final TraceManager traceManager = this.traceManager;
|
||||
|
||||
Trace trace = traceManager.startSpan("testSendMessage", this.sampler, null);
|
||||
Message<?> m = StompMessageBuilder.fromMessage(new GenericMessage<String>("Message2")).build();
|
||||
public void should_propagate_span_information() {
|
||||
Trace trace = givenALocallyStartedSpan();
|
||||
Message<?> m = givenMessageToBeSampled();
|
||||
|
||||
this.channel.send(m);
|
||||
|
||||
String expectedSpanId = trace.getSpan().getSpanId();
|
||||
whenTheMessageWasSent(m);
|
||||
String expectedTraceId = trace.getSpan().getTraceId();
|
||||
traceManager.close(trace);
|
||||
|
||||
Message<?> message = this.message;
|
||||
|
||||
assertNotNull("message was null", message);
|
||||
|
||||
String spanId = message.getHeaders().get(Trace.SPAN_ID_NAME, String.class);
|
||||
assertEquals("spanId was wrong", expectedSpanId, spanId);
|
||||
|
||||
String traceId = message.getHeaders().get(Trace.TRACE_ID_NAME, String.class);
|
||||
assertNotNull("traceId was null", traceId);
|
||||
thenReceivedMessageIsNotNull();
|
||||
String traceId = thenTraceIdFromHeadersIsNotEmpty();
|
||||
then(traceId).isEqualTo(expectedTraceId);
|
||||
thenSpanIdFromHeadersIsNotEmpty();
|
||||
}
|
||||
|
||||
|
||||
private void thenReceivedMessageIsNotNull() {
|
||||
Message<?> message = stompMessageHandler.message;
|
||||
then(message).isNotNull();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
static class TestApplication {
|
||||
@Autowired
|
||||
TraceStompMessageChannelInterceptor stompChannelInterceptor;
|
||||
|
||||
@Autowired
|
||||
TraceStompMessageContextPropagationChannelInterceptor stompMessageContextChannelInterceptor;
|
||||
|
||||
@Bean
|
||||
public ExecutorSubscribableChannel executorSubscribableChannel() {
|
||||
|
||||
@Bean ExecutorSubscribableChannel executorSubscribableChannel(
|
||||
TraceStompMessageChannelInterceptor stompChannelInterceptor,
|
||||
TraceStompMessageContextPropagationChannelInterceptor stompMessageContextChannelInterceptor) {
|
||||
ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel();
|
||||
channel.addInterceptor(stompChannelInterceptor);
|
||||
channel.addInterceptor(stompMessageContextChannelInterceptor);
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AlwaysSampler alwaysSampler() {
|
||||
@Bean AlwaysSampler alwaysSampler() {
|
||||
return new AlwaysSampler();
|
||||
}
|
||||
|
||||
@Bean StompMessageHandler stompMessageHandler() {
|
||||
return new StompMessageHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user