diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index 67dae0a5c..50d7ced38 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -63,6 +63,7 @@ brave-core ${brave.version} + com.github.kristofa brave-http diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/IntegrationTestSpanCollector.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestSpanCollector.java similarity index 98% rename from spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/IntegrationTestSpanCollector.java rename to spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestSpanCollector.java index e02b4cc6d..de18a1fa3 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/IntegrationTestSpanCollector.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestSpanCollector.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package tools; +package integration; import com.github.kristofa.brave.LoggingSpanCollector; import com.twitter.zipkin.gen.Span; diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java index a8863d242..1c593f7ce 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java @@ -15,32 +15,35 @@ */ package integration; -import com.twitter.zipkin.gen.BinaryAnnotation; -import com.twitter.zipkin.gen.Span; -import lombok.extern.slf4j.Slf4j; +import static org.assertj.core.api.BDDAssertions.then; + +import java.util.Collection; + import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.WebIntegrationTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.JdkIdGenerator; import org.springframework.util.StringUtils; + +import com.github.kristofa.brave.SpanCollector; +import com.twitter.zipkin.gen.BinaryAnnotation; +import com.twitter.zipkin.gen.Span; + +import integration.MessagingApplicationTests.IntegrationSpanCollectorConfig; import sample.SampleMessagingApplication; import tools.AbstractIntegrationTest; -import tools.IntegrationTestSpanCollector; - -import java.util.Collection; - -import static org.assertj.core.api.BDDAssertions.then; @RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = { AbstractIntegrationTest.IntegrationSpanCollectorConfig.class, SampleMessagingApplication.class }) +@SpringApplicationConfiguration(classes = { IntegrationSpanCollectorConfig.class, SampleMessagingApplication.class }) @WebIntegrationTest @TestPropertySource(properties="sample.zipkin.enabled=true") -@Slf4j public class MessagingApplicationTests extends AbstractIntegrationTest { private static int port = 3381; @@ -49,7 +52,7 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { @After public void cleanup() { - integrationTestSpanCollector.hashedSpans.clear(); + this.integrationTestSpanCollector.hashedSpans.clear(); } @Test @@ -76,7 +79,7 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { } private void thenThereIsAtLeastOneBinaryAnnotationWithKey(String binaryAnnotationKey) { - then(integrationTestSpanCollector.hashedSpans.stream() + then(this.integrationTestSpanCollector.hashedSpans.stream() .filter(Span::isSetBinary_annotations) .map(Span::getBinary_annotations) .flatMap(Collection::stream) @@ -86,7 +89,15 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { } private void thenAllSpansHaveTraceIdEqualTo(String traceId) { - then(integrationTestSpanCollector.hashedSpans.stream().allMatch(span -> span.getTrace_id() == zipkinHashedTraceId(traceId))).isTrue(); + then(this.integrationTestSpanCollector.hashedSpans.stream().allMatch(span -> span.getTrace_id() == zipkinHashedTraceId(traceId))).isTrue(); + } + + @Configuration + public static class IntegrationSpanCollectorConfig { + @Bean + SpanCollector integrationTestSpanCollector() { + return new IntegrationTestSpanCollector(); + } } } diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-stream/src/main/resources/application.yml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-stream/src/main/resources/application.yml index 398079019..e6c80f2b7 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-stream/src/main/resources/application.yml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-stream/src/main/resources/application.yml @@ -4,3 +4,6 @@ server: spring: application: name: testSleuthApp +# TODO: remove this once Brave is off the class path + zipkin: + enabled: false \ No newline at end of file diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml index d8b452d8e..14b7ab226 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml @@ -59,10 +59,6 @@ org.springframework.cloud spring-cloud-sleuth-core - - org.springframework.cloud - spring-cloud-sleuth-zipkin - org.springframework.boot spring-boot-starter-aop diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java index 21e5f83c3..74bcdd920 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java @@ -26,9 +26,6 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import org.springframework.cloud.sleuth.zipkin.ZipkinProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -36,16 +33,11 @@ import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; -import com.github.kristofa.brave.EmptySpanCollectorMetricsHandler; -import com.github.kristofa.brave.HttpSpanCollector; -import com.github.kristofa.brave.SpanCollector; -import com.github.kristofa.brave.SpanCollectorMetricsHandler; import com.jayway.awaitility.Awaitility; import com.jayway.awaitility.core.ConditionFactory; import io.zipkin.Codec; import io.zipkin.Span; -import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; /** @@ -108,11 +100,15 @@ public abstract class AbstractIntegrationTest { } protected ResponseEntity endpointToCheckZipkinServerHealth() { - URI uri = URI.create("http://localhost:9411/health"); + URI uri = URI.create("http://localhost:" +getZipkinServerPort()+"/health"); log.info("Sending request to the Zipkin Server [{}]", uri); return exchangeRequest(uri); } + protected int getZipkinServerPort() { + return 9411; + } + protected ResponseEntity checkStateOfTheTraceId(String traceId) { String hexTraceId = zipkinHashedHexStringTraceId(traceId); URI uri = URI.create(getZipkinTraceQueryUrl() + hexTraceId); @@ -127,11 +123,11 @@ public abstract class AbstractIntegrationTest { } protected String getZipkinTraceQueryUrl() { - return "http://localhost:9411/api/v1/trace/"; + return "http://localhost:"+getZipkinServerPort()+"/api/v1/trace/"; } protected String getZipkinServicesQueryUrl() { - return "http://localhost:9411/api/v1/services"; + return "http://localhost:"+getZipkinServerPort()+"/api/v1/services"; } protected Runnable httpMessageWithTraceIdInHeadersIsSuccessfullySent(String endpoint, String traceId) { @@ -148,7 +144,7 @@ public abstract class AbstractIntegrationTest { List serviceNamesNotFoundInZipkin = serviceNamesNotFoundInZipkin(spans); List spanNamesNotFoundInZipkin = annotationsNotFoundInZipkin(spans); log.info("The following services were not found in Zipkin {}", serviceNamesNotFoundInZipkin); - log.info("The following spans were not found in Zipkin {}", spanNamesNotFoundInZipkin); + log.info("The following annotations were not found in Zipkin {}", spanNamesNotFoundInZipkin); then(serviceNamesNotFoundInZipkin).isEmpty(); then(spanNamesNotFoundInZipkin).isEmpty(); log.info("Zipkin tracing is working! Sleuth is working! Let's be happy!"); @@ -201,39 +197,4 @@ public abstract class AbstractIntegrationTest { return "random-sleep-millis"; } - @Configuration - public static class IntegrationSpanCollectorConfig { - @Bean - SpanCollector integrationTestSpanCollector() { - return new IntegrationTestSpanCollector(); - } - } - - @Configuration - @Slf4j - public static class WaitUntilZipkinIsUpConfig { - @Bean - @SneakyThrows - public SpanCollector spanCollector(final ZipkinProperties zipkin) { - await().until(new Runnable() { - @Override - public void run() { - try { - WaitUntilZipkinIsUpConfig.this.getSpanCollector(zipkin); - } catch (Exception e) { - log.error("Exception occurred while trying to connect to zipkin [" + e.getCause() + "]"); - throw new AssertionError(e); - } - } - }); - return getSpanCollector(zipkin); - } - - private SpanCollector getSpanCollector(ZipkinProperties zipkin) { - String url = "http://localhost:" + zipkin.getPort(); - // TODO: parameterize this - SpanCollectorMetricsHandler metrics = new EmptySpanCollectorMetricsHandler(); - return HttpSpanCollector.create(url, zipkin.getHttpConfig(), metrics); - } - } } diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/pom.xml index b31e7b8c6..040e546fc 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/pom.xml @@ -72,10 +72,6 @@ lombok true - - io.zipkin - zipkin-java-core - org.springframework.cloud diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/src/test/java/integration/SampleApp.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/src/test/java/integration/SampleApp.java deleted file mode 100644 index 673b2ce3f..000000000 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/src/test/java/integration/SampleApp.java +++ /dev/null @@ -1,49 +0,0 @@ -package integration; - -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; -import org.springframework.cloud.sleuth.TraceManager; -import org.springframework.cloud.sleuth.trace.TraceContextHolder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.Random; - -/** - * @author Marcin Grzejszczak - */ -@RestController -@Slf4j -public class SampleApp { - - @Autowired - private TraceManager traceManager; - - @SneakyThrows - @RequestMapping("/hi2") - public String hi2() { - log.info("I'm in the sample app"); - final Random random = new Random(); - int millis = random.nextInt(1000); - Thread.sleep(millis); - this.traceManager.addAnnotation("random-sleep-millis", String.valueOf(millis)); - log.info("Current span is [{}]", TraceContextHolder.getCurrentSpan()); - return "hi2"; - } - - @Configuration - @EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) - @Slf4j - public static class Config { - - @Bean SampleApp sampleApp() { - return new SampleApp(); - } - - } -} diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/src/test/java/integration/ZipkinStreamTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/src/test/java/integration/ZipkinStreamTests.java index 3f410d1dd..9ff944c37 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/src/test/java/integration/ZipkinStreamTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/src/test/java/integration/ZipkinStreamTests.java @@ -15,41 +15,71 @@ */ package integration; -import example.ZipkinStreamServerApplication; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import java.util.Arrays; + 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.beans.factory.annotation.Value; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.WebIntegrationTest; +import org.springframework.cloud.sleuth.MilliSpan; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.stream.Host; +import org.springframework.cloud.sleuth.stream.SleuthSink; +import org.springframework.cloud.sleuth.stream.Spans; import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration; +import org.springframework.integration.support.MessageBuilder; +import org.springframework.messaging.MessageChannel; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.JdkIdGenerator; + +import example.ZipkinStreamServerApplication; +import lombok.SneakyThrows; import tools.AbstractIntegrationTest; @RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = { SampleApp.Config.class, - AbstractIntegrationTest.WaitUntilZipkinIsUpConfig.class, - TestSupportBinderAutoConfiguration.class, +@SpringApplicationConfiguration(classes = { TestSupportBinderAutoConfiguration.class, ZipkinStreamServerApplication.class }) -@WebIntegrationTest -@Slf4j +@WebIntegrationTest({ "server.port=0", "management.health.rabbit.enabled=false" }) @ActiveProfiles("test") public class ZipkinStreamTests extends AbstractIntegrationTest { - private static int port = 9411; - private static String sampleAppUrl = "http://localhost:" + port; + @Value("${local.server.port}") + private int zipkinServerPort = 9411; + + @Autowired + @Qualifier(SleuthSink.INPUT) + private MessageChannel input; @Test @SneakyThrows public void should_propagate_spans_to_zipkin() { - await().until(zipkinServerIsUp()); - String traceId = new JdkIdGenerator().generateId().toString(); - await().until(httpMessageWithTraceIdInHeadersIsSuccessfullySent(sampleAppUrl + "/hi2", traceId)); + await().until(zipkinServerIsUp()); + + String traceId = new JdkIdGenerator().generateId().toString(); + Span span = MilliSpan.builder().traceId(traceId).spanId(traceId).name("test") + .build(); + span.tag(getRequiredBinaryAnnotationName(), "10131"); + + this.input.send(MessageBuilder.withPayload( + new Spans(new Host(getAppName(), "127.0.0.1", 8080), Arrays.asList(span))) + .build()); await().until(allSpansWereRegisteredInZipkinWithTraceIdEqualTo(traceId)); } + @Override + protected int getZipkinServerPort() { + return this.zipkinServerPort; + } + + @Override + protected String getAppName() { + return "local"; + } + } diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/IntegrationTestSpanCollector.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/IntegrationTestSpanCollector.java new file mode 100644 index 000000000..de18a1fa3 --- /dev/null +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/IntegrationTestSpanCollector.java @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package integration; + +import com.github.kristofa.brave.LoggingSpanCollector; +import com.twitter.zipkin.gen.Span; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * Span Collector that logs spans and adds Spans to a list + * + * @author Marcin Grzejszczak + */ +public class IntegrationTestSpanCollector extends LoggingSpanCollector { + + public List hashedSpans = Collections.synchronizedList(new LinkedList()); + + @Override + public void collect(Span span) { + super.collect(span); + hashedSpans.add(span); + } + +} diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java index f0b587a68..5a4a845f0 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java @@ -15,27 +15,35 @@ */ package integration; -import io.zipkin.server.ZipkinServer; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.WebIntegrationTest; +import org.springframework.cloud.sleuth.zipkin.ZipkinProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.JdkIdGenerator; + +import com.github.kristofa.brave.EmptySpanCollectorMetricsHandler; +import com.github.kristofa.brave.HttpSpanCollector; +import com.github.kristofa.brave.SpanCollector; +import com.github.kristofa.brave.SpanCollectorMetricsHandler; + +import integration.ZipkinTests.WaitUntilZipkinIsUpConfig; +import io.zipkin.server.ZipkinServer; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import sample.SampleZipkinApplication; import tools.AbstractIntegrationTest; @RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = { - AbstractIntegrationTest.WaitUntilZipkinIsUpConfig.class, +@SpringApplicationConfiguration(classes = { WaitUntilZipkinIsUpConfig.class, SampleZipkinApplication.class }) @WebIntegrationTest -@TestPropertySource(properties="sample.zipkin.enabled=true") -@Slf4j +@TestPropertySource(properties = "sample.zipkin.enabled=true") public class ZipkinTests extends AbstractIntegrationTest { private static final String APP_NAME = "testsleuthzipkin"; @@ -44,7 +52,7 @@ public class ZipkinTests extends AbstractIntegrationTest { @Before public void setup() { - ZipkinServer.main(new String[]{"server.port=9411"}); + ZipkinServer.main(new String[] { "server.port=9411" }); await().until(zipkinQueryServerIsUp()); } @@ -53,7 +61,8 @@ public class ZipkinTests extends AbstractIntegrationTest { public void should_propagate_spans_to_zipkin() { String traceId = new JdkIdGenerator().generateId().toString(); - await().until(httpMessageWithTraceIdInHeadersIsSuccessfullySent(sampleAppUrl + "/hi2", traceId)); + await().until(httpMessageWithTraceIdInHeadersIsSuccessfullySent( + sampleAppUrl + "/hi2", traceId)); await().until(allSpansWereRegisteredInZipkinWithTraceIdEqualTo(traceId)); } @@ -62,4 +71,34 @@ public class ZipkinTests extends AbstractIntegrationTest { protected String getAppName() { return APP_NAME; } + + @Configuration + @Slf4j + public static class WaitUntilZipkinIsUpConfig { + @Bean + @SneakyThrows + public SpanCollector spanCollector(final ZipkinProperties zipkin) { + await().until(new Runnable() { + @Override + public void run() { + try { + WaitUntilZipkinIsUpConfig.this.getSpanCollector(zipkin); + } + catch (Exception e) { + log.error("Exception occurred while trying to connect to zipkin [" + + e.getCause() + "]"); + throw new AssertionError(e); + } + } + }); + return getSpanCollector(zipkin); + } + + private SpanCollector getSpanCollector(ZipkinProperties zipkin) { + String url = "http://localhost:" + zipkin.getPort(); + // TODO: parameterize this + SpanCollectorMetricsHandler metrics = new EmptySpanCollectorMetricsHandler(); + return HttpSpanCollector.create(url, zipkin.getHttpConfig(), metrics); + } + } }