Spring cloud sleuth - Propagation of headers in rest call - spring-boot

We incorporated spring cloud sleuth (1.1.3 RELEASE) in our spring boot 1.x application and had no problems with header propagation over rest.
However we upgraded our application to spring boot 2.0.4 and added cloud sleuth 2.0.1 RELEASE. Now, trace and Span Ids are not propagated over rest calls.
Debug points inside of B3Propagation and TracingClientHttpRequestInterceptor are not being invoked at all.
Has something changed in the newer versions of sleuth or is any additional configuration required for the TracingClientHttpRequestInterceptor?
Any pointers would be greatly appreciated.
Thanks.

In your bean you need to inject the interceptor, for example with a RestTemplateBuilder:
#Bean
public RestTemplateBuilder clientRestTemplateBuilder(TracingClientHttpRequestInterceptor tracingClientHttpRequestInterceptor) {
return new RestTemplateBuilder()
.additionalInterceptors(tracingClientHttpRequestInterceptor)
.(additional config);
}

This was happening because the rest template was not available at the time of hooking the TracingClientHttpRequestInterceptor. (was created much before the injection)
Changing the way the rest template was being injected fixed this issue.
Thanks.

Related

Spring Cloud Sleuth stopped pushing X-B3-TraceId into MDC after spring-boot/spring cloud upgrade

I have upgraded my Spring boot dependencies from 2.1 to 2.4.5 and spring cloud to 2020.0.2.
After this upgrade, my MDC context is not populated.
Any ideas of what should be done here?
in spring cloud 2020.0.2 you have sleuth 3.x and there is a migration guide telling about some changes to MDC
I think the answer depends on your use-case but as far as I remember, there was a change and the MDC context is cleaned-up after the span is finished.
This means that if you are in the scope of the Span (e.g.: controller method), you can see the Sleuth-related parts of the MDC but if you are outside of the scope of the span (e.g.: Tomcat access logs), you don't.
To test this, try to log out the MDC context map inside of the controller method, the MDC context should contain the tracing-related fields.

Using 'feign clients' without springboot is possible?

My framework is spring framework. core version is 4.3.16.RELEASE.
Not using springboot. It's one of the legacy project.
And I wanna know what can I use the feign client without springboot.
Is this possible? and where can I found document about that.
thanks for your help :)
Yes, it's possible. You can find the documentation on their Github page.
Feign wasn't integrated with Spring initially. There is another wrapper library called Spring Cloud OpenFeign, and with it, you can use Feign in Spring Boot & Cloud applications more convenient (eg., you can use Spring's #RequestMapping annotation instead of default Feign's #RequestLine).

How to swap Spring Boot mapper from Jackson to kotlinx.serialization

I would like my Spring Boot project to use kotlinx.serialization. I can't figure out how to swap the mapper correctly... If I wanted to use GSON, I could just note it in the props via spring.http.converters.preferred-json-mapper=gson.
Has anyone had success with this?
Just use Spring >= 5.3 and add corresponding kotlin plugin and serialization dependency. Spring switches serialization automatically. Details

Minimum version of spring for spring-boot v 1.3

I have an existing spring application built using spring framework version 3.1.2. I am trying to create a spring-boot application out of this existing application, but getting some dependency issues. So just wondering, what is the spring framework version, that is supported by spring-boot v 1.3.0.
Or to put it in another words, is it possible to have a spring-boot application from a spring 3.1.2 based application?
Spring boot has hard dependencies on classes in Spring 4 and could not be configured to work with Spring 3. If you are really interested in using Spring Boot the only way you can do this is to follow a migration path to Spring 4 and then add Spring Boot to your application.
It is worth mentioning that the "boot" in Spring Boot is meant to be short for bootstrapping, as in initial setup of an application. I'm not saying there would be zero benefits from migrating from Spring 4 vanilla to Spring Boot. But make sure you are migrating for the right reasons the main purpose of Spring Boot is easy bootstrapping of applications but here are some other features which might be worth making the move.
Spring Boot dev-tools (Auto restart on code changes)
Awesome spring boot plugins for maven and gradle to ease upgrading spring in the future (hint it upgrades many other dependencies for you)
Bootstrapping new features such as MongoDb through auto-configuration.
Migration from 3.1 to 3.2
https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/migration-3.2.html
Migration from Spring 3 to Spring 4.
https://spring.io/blog/2014/01/30/migrating-from-spring-framework-3-2-to-4-0-1
There are many features in spring boot that are dependent upon new features added to Spring 4. One primary example is the new list of annotations added to Spring 4 that allow conditional wiring/loading of beans. Which is the primary method of wiring configurations in a plugin-like way.
For example lets see the AutoConfiguration class for the H2 console
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfiguration.java
The first thing we see is it's wired to be a Configuration class. It will only load if WebServlet.class is on the classpath and if the property spring.h2.console is = true. It is also configured to load SecurityAutoConfiguration first as this is a dependency at least for securing the h2 console page.
#Configuration
#ConditionalOnWebApplication
#ConditionalOnClass(WebServlet.class)
#ConditionalOnProperty(prefix = "spring.h2.console", name = "enabled", havingValue = "true", matchIfMissing = false)
#EnableConfigurationProperties(H2ConsoleProperties.class)
#AutoConfigureAfter(SecurityAutoConfiguration.class)
public class H2ConsoleAutoConfiguration {
When this Configuration is loaded it will check these conditions and upon all conditions being true then and only then will it load in the beans defined in the class. In this case it wires the h2console servlet.
#Bean
public ServletRegistrationBean h2Console() {
String path = this.properties.getPath();
String urlMapping = (path.endsWith("/") ? path + "*" : path + "/*");
return new ServletRegistrationBean(new WebServlet(), urlMapping);
}
There is also the security configuration in that class which introduces one more concept of conditionally loading a configuration based on another class being loaded into the context. These annotations do not always need to be on a Configuration level but can also apply to the bean level.
These concepts are core to how Spring Boot is implemented and therefore could not work with Spring 3.
Spring 3 list of annotations
http://docs.spring.io/spring/docs/3.0.x/javadoc-api/org/springframework/context/annotation/
Spring 4 Conditional Annotations
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/
Thanks Zergleb for posting detailed answer. I found a way to run the spring 3 app as an independent jar by created an uber jar with a little instrumentation to bootstrap spring through a java class.
It is explained nicely in a short post at https://mihhaillapushkin.wordpress.com/2013/02/18/spring-3-for-standalone-applications

Intellij spring boot integration

For some reason Intellij 13.1.3 doesn't detect the spring boot beans. Spring boot version is 1.1.1-Release. When i try to inject ObjectMapper in some component i get an error in the IDE "No bean of type ObjectMapper defined", however the application compiles and runs just fine and the ObjectMapper beans is visible in the /beans json.
I have added my application-context and my Application.java files to a spring facet and the IDE recognizes all my other beans that I manually defined, it just ignores the ones that come with Spring boot #EnableAutoConfiguration. Any idea how to solve that since its kinda tedious not to have the correct linking in the IDE and get errors all over the place. I would assume thats a common issue?
Thanks!
As an update for this answer: IntelliJ now supports Spring Boot. Must be at least R14. R15 is including some more integration.
Spring Boot is not supported yet, please watch http://youtrack.jetbrains.com/issue/IDEA-119230

Resources