Ribbon with Spring Cloud and Eureka: java.lang.IllegalStateException: No instances available for Samarths-MacBook-Pro.local
The RestTemplate
you autowired is already connected to Ribbon. So you do a lookup by hand and then RestTemplate
is trying to lookup the hostname passed in to ribbon. You have two options: 1) Don't use the netflix DiscoveryClient
and pass the serviceId as a logical hostname to ribbon (http://TEST/myservice
), 2) Don't use the autowired RestTemplate
, create a new one for your class. My choice would be #1.
I got this working. The only change I had to make was in the way I was using RestTemplate api.
Error Code:
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/",method = RequestMethod.GET)
String consumer(){
String baseDir = restTemplate.getForObject("TEST", String.class);
return baseDir;
}
Working Code:
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/",method = RequestMethod.GET)
String consumer(){
String baseDir = restTemplate.getForObject("http://TEST", String.class);
return baseDir;
}
Solution:
The first parameter to restTemplate.getForObject should have the format of a URL. And the domain name should be the name of the service you want to discover.
Ex: http://TEST. Here, TEST is the name of my server registered to eureka registry
The question is already answered, but I found a workaround that seems neat and fixed our problem.
First declare a new @Component class and in it create a method that returns RestTemplate:
@Component
public class RestTemplateComponentFix{
@Autowired
SomeConfigurationYouNeed someConfiguration;
@LoadBalanced
public RestTemplate getRestTemplate() {
// TODO set up your restTemplate
rt.setRequestFactory( new HttpComponentsClientHttpRequestFactory() );
return rt;
}
}
After that just Autowire the restTemplateComponentFix in your class and when when you need the rest template call the restTemplate() method. Something like this:
@Service
public class someClass{
@Autowired
RestTemplateComponentFix restTemplateComponentFix;
public void methodUsingRestTemplate(){
// Some code...
RestTemplate rt = restTemplateComponentFix.getRestTemplate();
// Some code...
}
}
After that you can unit test with something like:
RestTemplate rt = Mockito.mock(RestTemplate.class)
when(restTemplateComponentFix.getRestTemplate()).thenReturn(rt);
when(rt.someMethod()).thenReturn(something);