Issues with Spring cloud consul config while starting a Groovy app through Spring cloud cli - spring

I am Exploring Consul for discovery and config server. I have added the required dependencies and yml file is set up. When i try to start the server using spring cloud cli (Spring run .) I am getting the below error which i am unable to resolve. Any help is appreciated.
Error :
"A component required a bean named 'configServerRetryInterceptor' that could >not be found."
I tried to define this bean but when i start the app through spring cloud cli it is not recognizing it.
Please see the code below
App.groovy
#Grab("spring-cloud-starter-consul-config")
#Grab("spring-cloud-starter-consul-discovery")
#EnableDiscoveryClient
#EnableCircuitBreaker
#RestController
#Log
class Application{
#Autowired
Greeter greeter
int counter = 0
#RequestMapping(value = "/counter", produces = "application/json")
String produce() {
counter++
log.info("Produced a value: ${counter}")
"{\"value\": ${counter}}"
}
#RequestMapping("/")
String home() {
"${greeter.greeting} World!"
}
#RequestMapping(value = '/questions/{questionId}')
#HystrixCommand(fallbackMethod = "defaultQuestion")
def question(#PathVariable String questionId) {
if(Math.random() < 0.5) {
throw new RuntimeException('random');
}
[questionId: questionId]
}
def defaultQuestion(String questionId) {
[questionId: 'defaultQuestion']
}
}
#Component
#RefreshScope
class Greeter {
#Value('${greeting}')
String greeting
}
bootstrap.yml
consul:
host: localhost
port: 8500
config:
enabled: true
prefix: config
defaultContext: master
profileSeparator: '::'
format: FILES
discovery:
instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
health-check-url: http://127.0.0.1:${server.port}/health

This issue was due to unwanted dependencies being pulled.
Explicitly disabling spring cloud config and spring cloud discovery fixed it.
spring:
cloud:
config:
enabled: false
discovery:
enabled: false
serviceId: CONFIG
eureka:
client:
register-with-eureka: false
fetch-registry: false

Related

Error while using custom loadbalancer for spring cloud loadbalancer with healthcheck configuration

I am using a static list (SimpleDiscoveryClient) to loadbalance using spring cloud loadbalancer. Using StickySession Loadbalancer rule in https://github.com/fitzoh/spring-cloud-commons/blob/e10997b6141ff560479ef7065c3547f1f59360c8/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/StickySessionLoadBalancer.java.
My WebClientConfig class:
#Configuration
#LoadBalancerClient(name = "testservice", configuration = CustomLoadBalancerConfiguration.class)
public class WebClientConfig {
#LoadBalanced
#Bean
WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
Custom LoadBalancer Configuration class:
public class CustomLoadBalancerConfiguration {
#Bean
ReactorLoadBalancer<ServiceInstance> StickySessionLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new StickySessionLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
#Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withHealthChecks()
.build(context);
}
}
Posting my yml here :
spring:
application:
name: sample
cloud:
discovery:
client:
health-indicator:
enabled: false
simple:
instances:
testservice:
- uri: http://localhost:8082
- uri: http://localhost:8081
loadbalancer:
configurations: health-check
cache:
enabled: false
health-check:
path:
default: /actuator/health
interval: 10000
gateway:
routes:
- id: testrouting
path: /user/*
uri: lb://testservice
predicates:
- Method=GET,POST
- Path=/user/**
It's all according to the official documentation. But with the customloadbalancer rule (Stickysession Loadbalancer), the healthchecks to servers are not happening to checkif the servers are alive or not. The server list is always empty (all servers are marked as not alive).

Zuul throwing 404 No meesage Available error

I have my below app (microservices) which is successfully registered to Eureka server.I t has below Rest end point
#Controller
#RequestMapping("v1/base/")
public class PersonController {
#PostMapping
#RequestMapping(value="/personid")
public ResponseEntity< ?> getPersonList(){
return ResponseEntity.ok("All person list");
}
The properties file for person-application
eureka:
instance:
appname: person-application
client:
enabled: true
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
My zuul server yml file config is is .
server:
port:9000
servlet:
contextPath: /zuulapp
zuul:
routes:
person:
path: /v1/base/**
serviceId: person-application
When i call hit the rest point localhost:9000/zuulapp/person/personid i get the below error.How do i resolve this error
{
"timestamp":"2019-10-08T12:42:09.479+0000",
"status":404,
"error":"Internal Server Error",
"message":"No Message available"
"path" : "/zuulapp/person/personid"
}
Since the registered path in the zuul of the application is "/v1/base/**"
try this one: delete the contextpath properties then replace it with zuul.prefix properties.
server:
port:9000
zuul:
prefix: /zuulapp
routes:
person:
path: /person/**
serviceId: person-application
Now try checking this endpoint:
localhost:9000/zuulapp/person/v1/base/personid
try this in the controller class:
#RestController
#RequestMapping("/v1/base/")
public class PersonController {
#GetMapping(value="/personid")
public ResponseEntity< ?> getPersonList(){
return ResponseEntity.ok("All person list");
}

Feign Client cannot communicate with a method inside of eureka server

I have a eureka server configured and inside that eureka server I have written a rest api. Now I have a eureka client service and I am trying to call one of the method of eureka service using feign from client service. But I am getting an error "Load balancer does not have available server for client: eureka-service".
But If I call api from a client service to another client service using feign then it is giving successful result. Just can't call API from eureka service.
eureka-service is application name of my eureka server.
#EnableEurekaServer
#SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
#RestController
#RequestMapping("test")
public class TestController {
#GetMapping
public String test(){
return "test success";
}
}
bootstrap.yml of eureka service
eureka:
client:
registerWithEureka: false
fetchRegistry: false
eureka-server-read-timeout-seconds: 60
eureka-server-connect-timeout-seconds: 60
serviceUrl:
defaultZone: http://localhost:8763/eureka/
dashboard:
enabled: true
spring:
application:
name: eureka-service
And client service is:
#SpringBootApplication
#EnableFeignClients
#EnableDiscoveryClient
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
#FeignClient("eureka-service")
public interface TestFeign {
#GetMapping("test")
String test();
}
bootstrap.yml of client service
eureka:
client:
registerWithEureka: true
fetchRegistry: true
eureka-server-read-timeout-seconds: 60
eureka-server-connect-timeout-seconds: 60
serviceUrl:
defaultZone: http://localhost:8763/eureka/
spring:
application:
name: client-service
feign:
hystrix:
enabled: true
ERROR log : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: TestFeign#test() failed and no fallback available.] with root cause
com.netflix.client.ClientException: Load balancer does not have available server for client: eureka-service.
How can we solve this issue. Thanks for help in advance.
You need to scan your interfaces that declare they are FeignClients with the #EnableFeignClients annotation in your main class and add the feign.hystrix.enabled=true property.

Spring Cloud Vault Configuration without YAML file

I have mentioned the Spring Cloud Vault Configuration in my bootstrap.ymlfile
spring:
cloud:
vault:
authentication: APPROLE
app-role:
role-id: *****
secret-id: ****
host: ****
port: 80
scheme: http
But i dont want to have these in my YML file, rather i would like to have these configured as a bean
#configuration / #bean
Please help. Thanks
I was able to do this successfully by configuring a Bean of type VaultProperties. Below is the code snippet which completely eliminated the need for maintaining the same in bootstrap.yml
#Configuration
public class VaultConfiguration {
#Bean
public VaultProperties vaultProperties() {
VaultProperties vaultProperties = new VaultProperties();
vaultProperties.setAuthentication(VaultProperties.AuthenticationMethod.APPROLE);
VaultProperties.AppRoleProperties appRoleProperties = new VaultProperties.AppRoleProperties();
appRoleProperties.setRoleId("****");
appRoleProperties.setSecretId("****");
vaultProperties.setAppRole(appRoleProperties);
vaultProperties.setHost("***");
vaultProperties.setPort(80);
vaultProperties.setScheme("http");
return vaultProperties;
}
}
Note : When you are having a configuration that should be treated as bootstrap-configuration, then you need to mention the class name under src/main/resources/META-INF/spring.factories
The content in spring.factories is
org.springframework.cloud.bootstrap.BootstrapConfiguration=com.arun.local.cloudconfig.VaultConfiguration

Share configuration between Spring cloud config clients

I'm trying to share configuration between Spring Cloud clients with a Spring Cloud config server which have a file-based repository:
#Configuration
#EnableAutoConfiguration
#EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
// application.yml
server:
port: 8888
spring:
profiles:
active: native
test:
foo: world
One of my Spring Cloud client use the test.foo configuration, defined in the config server, and it is configured like below:
#SpringBootApplication
#RestController
public class HelloWorldServiceApplication {
#Value("${test.foo}")
private String foo;
#RequestMapping(path = "/", method = RequestMethod.GET)
#ResponseBody
public String helloWorld() {
return "Hello " + this.foo;
}
public static void main(String[] args) {
SpringApplication.run(HelloWorldServiceApplication.class, args);
}
}
// boostrap.yml
spring:
cloud:
config:
uri: ${SPRING_CONFIG_URI:http://localhost:8888}
fail-fast: true
// application.yml
spring:
application:
name: hello-world-service
Despite this configuration, the Environment in the Spring Cloud Client doesn't contains the test.foo entry (cf java.lang.IllegalArgumentException: Could not resolve placeholder 'test.foo')
However it's works perfectly if i put the properties in a hello-world-service.yml file, in my config server file-based repository.
Maven dependencies on Spring Cloud Brixton.M5 and Spring Boot 1.3.3.RELEASE with spring-cloud-starter-config and spring-cloud-config-server
From Spring Cloud documentation
With the "native" profile (local file system backend) it is
recommended that you use an explicit search location that isn’t part
of the server’s own configuration. Otherwise the application*
resources in the default search locations are removed because they are
part of the server.
So i should put the shared configuration in an external directory and add the path in the application.yml file of the config-server.
// application.yml
spring:
profiles:
active: native
cloud:
config:
server:
native:
search-locations: file:/Users/herau/config-repo
// /Users/herau/config-repo/application.yml
test:
foo: world

Resources