I found an issue regarding using generated contract stubs in a consumer service using Feign client.
Calls to a feign client results in:
Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: producer-service
at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483)
...
how to reproduce
I made a producer-service which generated a stub and pushed it to my local maven repo.
Than I made a consumer-service where I wanted to use this stub to make my integration tests. Like this:
@RunWith(SpringRunner.class)
@SpringBootTest()
@AutoConfigureMockMvc
@AutoConfigureStubRunner(ids = {"de.havonte.demo:producer-mock:+:stubs:6565"}, workOffline = true)
@DirtiesContext
@ActiveProfiles(value = "integration")
//@TestPropertySource(properties = {"producser-service.ribbon.listOfServers = localhost:6565"})
public class SlmDamagereportIntTest {
@Autowired
protected ProducerService producerService;
static {
System.setProperty("eureka.client.enabled", "false");
System.setProperty("spring.cloud.config.failFast", "false");
}
@Test
public void testCompleteHalNotification() {
producerService.call();
}
}
The ProducerService is located in my consumer-service-app and includs a feign client:
@Component
public class ProducerService {
@AutoWired
private ProducerFeignClient producerClient;
public viod call(){producerClient.doSomeThing())};
}
And of course the ProducerFeignClient
@FeignClient(value = "producer-service")
public interface ProducerFeignClient {
@RequestMapping(path = "/method", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
ResponseEntity<String> doSomeThing();
}
My application.yml looke like:
producer-service:
ribbon:
listOfServers: localhost:6565
eureka:
enabled: false
My build.gradle:
springBootVersion= 1.5.8.RELEASE
....
dependencyManagement {
imports {
mavenBom('org.springframework.cloud:spring-cloud-dependencies:Dalston.SR4')
}
}
....
testCompile('org.springframework.cloud:spring-cloud-starter-contract-stub-runner')
I found the StubRunnerRibbonConfiguration
always returning empty lists for getInitialListOfServers and getUpdatedListOfServers.
My next move would be to override this Bean and return localhost:6565 instead of empty lists.
But I realy wonder why this configuration was made.
issue/expectation
The StubRunner should not return empty lists for wiremocked feign clients. Calls to reign clients should end up on the internal wiremock server.
Have you seen this part of the documentation? http://cloud.spring.io/spring-cloud-static/Dalston.SR4/multi/multi__spring_cloud_contract_stub_runner.html#_stub_runner_spring_cloud Your app is called producer-service. Your artifact id is producer-mock. You need to set sth like this
stubrunner:
idsToServiceIds:
producer-mock: producer-service
and then automatically Stub Runner will redirect the calls for you. The example can be found here - https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/consumer_with_discovery
Worked like a charm. I totally missed that in the docs. Thanks a lot.
Most helpful comment
Have you seen this part of the documentation? http://cloud.spring.io/spring-cloud-static/Dalston.SR4/multi/multi__spring_cloud_contract_stub_runner.html#_stub_runner_spring_cloud Your app is called
producer-service. Your artifact id isproducer-mock. You need to set sth like thisand then automatically Stub Runner will redirect the calls for you. The example can be found here - https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/consumer_with_discovery