0

I have a running code with spring boot and spring cloud using sleuth to log the TraceId. However i have problems in call one controller from other in the integrationTest

  public class TraceIdApp {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(TraceIdApp.class, args);
    }

    }

    @Slf4j
    @Getter
    @RestController
    public class TraceIdController {

    private SpanAccessor spanAccessor;
    private RestTemplate restTemplate;
    private String url;

    @Autowired
    public TraceIdController(SpanAccessor spanAccessor, RestTemplate restTemplate,
            @Value("http://localhost:${local.server.port:${server.port:8080}}/other") String url) {
        this.spanAccessor = spanAccessor;
        this.restTemplate = restTemplate;
        this.url = url;
    }

    @GetMapping(path = "/")
    public String handlerOne() {
        long traceId = spanAccessor.getCurrentSpan().getTraceId();
        log.info("loggin the real traceId => " + traceId);
        String response = getRestTemplate().getForObject(getUrl(), String.class);

        return "one" + response;
    }

    @GetMapping(path = "/other")
    public String handlerOther() {
        long traceId = spanAccessor.getCurrentSpan().getTraceId();
        log.info("loggin the real traceId => " + traceId);
        return "other";
    }
}

@Getter
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class TraceIdAppTest {

    @Autowired
    private SpanAccessor spanAccessor;

    @Autowired
    private MockMvc mockMvc;
    @Value("http://localhost:${local.server.port:${server.port:8080}}/other")
    String url;

    @Test
    public void test() throws Exception {
        mockMvc.perform(get("/")).andExpect(status().isOk());
        assertTrue("trace is wrong type", getSpanAccessor() instanceof DefaultTracer);
    }
}

running on test the first i notice its that the port on url take a correct value on the test, however its value is zero on the controller. hardcoding the port didnt fix the problem.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
nekperu15739
  • 3,311
  • 2
  • 26
  • 25

1 Answers1

1

I don't think it has anything to do with Sleuth. You're using @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) . So the port will be set at some point to the bound port. Initially it will be equal to 0, that's why you get the port with value equal to 0 injected to your controller. You can try to inject the port via a setter at a later time (sth like this https://github.com/spring-cloud/spring-cloud-contract/blob/master/samples/standalone/pact/pact-http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java#L30-L36 ). In your case you should resolve the value of the port once you're sending the request or when the test is ready to run.

Marcin Grzejszczak
  • 10,624
  • 1
  • 16
  • 32
  • Thank you for the quick answer, yeah, i saw it that the problem is that the controller initialize before the test, and obviously before the set te rigth port. i think that the real question , is why? or how change it? to not doing something like your solution or this one @Before public void before() { ReflectionTestUtils.setField(controller, "url", url); } or even mark the controller like lazy, it should be another way – nekperu15739 Mar 07 '17 at 16:09
  • Why do you want to inject your own port to your own controller. It makes no sense. You should resolve this lazily in your tests. Anything else is just a hack for doing something improper. – Marcin Grzejszczak Mar 07 '17 at 17:05