Showing posts with label MicroServices. Show all posts
Showing posts with label MicroServices. Show all posts

Monday, June 9, 2025

spring-cloud-starter-gateway-server-webflux vs spring-cloud-starter-gateway-server-webmvc

 The difference between spring-cloud-starter-gateway-server-webflux and spring-cloud-starter-gateway-server-webmvc lies in their underlying technology stack, concurrency model, and official support in Spring Cloud Gateway. Here's a breakdown:

1. spring-cloud-starter-gateway-server-webflux (Reactive/WebFlux)

  • Technology Stack:
    Built on Spring WebFlux (reactive stack) and Project Reactor.

  • Concurrency Model:
    Uses non-blocking I/O (event-loop) for high scalability and efficiency with concurrent requests.

  • Dependencies:
    Includes spring-boot-starter-webflux (reactive Netty, Undertow, etc.).

  • Performance:
    Optimized for high-throughput, low-latency scenarios (e.g., microservices, streaming).

  • Official Support:
    This is the standard/officially supported starter for Spring Cloud Gateway.

  • Use Case:
    Reactive applications, cloud-native microservices requiring scalability.

2. spring-cloud-starter-gateway-server-webmvc (Blocking/WebMVC)

  • Technology Stack:
    Built on Spring WebMVC (servlet stack) with blocking I/O.

  • Concurrency Model:
    Uses thread-per-request (blocking) model, limiting scalability under heavy load.

  • Dependencies:
    Includes spring-boot-starter-web (Tomcat, Jetty, etc.).

  • Performance:
    May bottleneck under high concurrency due to thread overhead.

  • Official Support:
    Not officially supported or maintained by Spring Cloud.
    Likely a community experiment or deprecated prototype.

  • Use Case:
    Only for legacy servlet applications (not recommended for new projects).


Key Technical Differences:

Aspectwebflux (Reactive)webmvc (Blocking)
HTTP ServerNetty, Reactor-based serversTomcat, Jetty (Servlet containers)
Request HandlingAsynchronous (event-loop)Synchronous (thread-per-request)
ScalabilityHigh (efficient resource usage)Limited (thread exhaustion risk)
Backpressure SupportYes (via Project Reactor)No
Reactive StreamsFull support (Mono/Flux)Not applicable

Why Spring Officially Recommends WebFlux:

  1. Gateway Design:
    Spring Cloud Gateway relies on reactive APIs (e.g., ServerWebExchange, Reactor).

  2. Compatibility:
    Integrates seamlessly with reactive Spring projects (Spring Data R2DBC, RSocket).

  3. Performance:
    Non-blocking I/O handles 10K+ concurrent connections with minimal threads.

  4. Future-Proof:
    Aligns with cloud-native/async trends (gRPC, WebSocket, streaming).


Should You Use webmvc?

  • Avoid it.
    The webmvc variant is unsupported, may have bugs, and negates the core benefits of Spring Cloud Gateway (scalability, non-blocking).

  • If you need a blocking API gateway, consider alternatives:

    • Spring Cloud Netflix Zuul (deprecated but servlet-based).

    • Traditional reverse proxies (Nginx, HAProxy).

Correct Starter for New Projects:

Use the standard (and only officially maintained) dependency:

xml
Copy
Download
Run
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId> <!-- Implicitly uses WebFlux -->
</dependency>

This automatically pulls spring-cloud-starter-gateway-server-webflux under the hood.

Summary:

  • webflux: Production-ready, reactive, high-performance.

  • webmvc: Experimental/legacy, blocking, unsupported.
    Always choose spring-cloud-starter-gateway (WebFlux) for new work.

Spring cloud api gateway migration

"spring-cloud-starter-gateway " is deprecated and  "spring-cloud-starter-gateway-server-webflux " is preferred to use. 

When you migrate remember to migrate the route path configured in the property or yml file also.

eg: let's take a simple scenario where you have service running on "http://localhost:8001/greet" and gateway is configured with port '9191'

your old properties will looks like beow.


----------------------------------------------------------------------

## As per Old configuration with spring.cloud.gateway.routes


server:

  port: 9191


spring:

  application:

    name: api-gateway

  cloud:

    gateway:

      routes:

        - id: greet-service

          uri: http://localhost:8001

          predicates:

            - Path=/greet/**

----------------------------------------------------------------------------

There won't any issue, but when you run the api-gateway it will give a warning message with sample content like below. api-gateway automatically recognized the usage of newer server-webflux and map old properties with new server-webflux properties

----------------------------------------------------------------------------

The use of configuration keys that have been renamed was found in the environment:


Property source 'Config resource 'class path resource [application.yml]' via location 'optional:classpath:/'':

Key: spring.cloud.gateway.routes[0].id

Line: 10

Replacement: spring.cloud.gateway.server.webflux.routes[0].id

Key: spring.cloud.gateway.routes[0].uri

Line: 11

Replacement: spring.cloud.gateway.server.webflux.routes[0].uri

Key: spring.cloud.gateway.routes[0].predicates[0]

Line: 13

Replacement: spring.cloud.gateway.server.webflux.routes[0].predicates[0]



Each configuration key has been temporarily mapped to its replacement for your convenience. To silence this warning, please update your configuration to use the new keys.


--------------------------------------------------------------------------------------

Solution

Simply add 'server-webflux' just between gateway and routes

-------------------------------------------------------------------------------------------

## new configuration with spring.cloud.gateway.server.webflux.routes

## Note : server.webflux  comes just after 'gateway'

server:
port: 9191

spring:
application:
name: api-gateway
cloud:
gateway:
server:
webflux:
routes:
- id: greet-service
uri: http://localhost:8001
predicates:
- Path=/greet/**
# filters:





Tuesday, June 3, 2025

Error in console running simple rest client using RestTemplate : java.net.UnknownHostException: greet-service

Here Problem is whichever configured application cannot find the host=greet-service. If you have a application with hostname, the request will go to it, but in this scenario we are looking at service registered with Discovery service.

1. Service main Spring Boot class  is missing @EnableDiscoveryClient and also 

2. maven POM dependency for Discovery client


@SpringBootApplication

public class GreetServiceWithEurekaApplication {

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

}

Sample Controller

@RestController
public class GreetClientController {

private RestTemplate restTemplate = new RestTemplate();

@RequestMapping("/greet-call")
Greet greet() {
//Phase 1 - without Discovery/Eureka client
// Greet greet = restTemplate.getForObject("http://localhost:8090/greet", Greet.class);
//With Discovery client - Now we can use service name - and with other option available via eureka server
// you need to configure DiscoveryClient - else cannot find hte hostname "greet-service" which is registered inEureka server
Greet greet = restTemplate.getForObject("http://greet-service/greet", Greet.class);
return greet;
}
}


Solution Steps

1. Add Discovery Client dependency to POM

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

you cannot simply add the dependency unless you don't have the dependency management. So add below dependency management block and property to identify the version.

<properties>

<spring-cloud.version>2025.0.0</spring-cloud.version>
</properties>


<!--    added dependency mgt after adding discovery client dependency-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

2. Add  Discovery Client Enable annotations - @EnableDiscoveryClient

3. Make RestTemplate Autowired. 

4. You need to define the RestTemplate bean 

5. RestTamplate bean must be Load balanced

6. Make sure Discovery server and corresponding service greet-service up and running

So after this code blocks of main class and Sample controller would be like below

package com.example.rest_client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class RestClientApplication {

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

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


package com.example.rest_client.controller;

import com.example.rest_client.model.Greet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class GreetClientController {

// private RestTemplate restTemplate = new RestTemplate();
@Autowired
private RestTemplate restTemplate;

@RequestMapping("/greet-call")
Greet greet() {
//Phase 1 - without Discovery/Eureka client
// Greet greet = restTemplate.getForObject("http://localhost:8090/greet", Greet.class);
//With Discovery client - Now we can use service name - and with other option available via eureka server
// you need to configure DiscoveryClient - else cannot find hte hostname "greet-service" which is registered inEureka server
Greet greet = restTemplate.getForObject("http://greet-service/greet", Greet.class);
return greet;
}
}


So when you call with

http://localhost:8095/greet-call

you should get a response like below.

{"message":"Demo with RestTemplate"}


Below is the full stacktrace:

----------------------------

 2025-06-03T16:54:02.056+05:30 ERROR 26616 --- [rest-client] [nio-8095-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://greet-service/greet": greet-service] with root cause


java.net.UnknownHostException: greet-service

at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:567) ~[na:na]

at java.base/java.net.Socket.connect(Socket.java:751) ~[na:na]

at java.base/java.net.Socket.connect(Socket.java:686) ~[na:na]

at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:183) ~[na:na]

at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:531) ~[na:na]

at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:636) ~[na:na]

at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:280) ~[na:na]

at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:386) ~[na:na]

at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:408) ~[na:na]

at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1304) ~[na:na]

at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1237) ~[na:na]

at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1123) ~[na:na]

at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1052) ~[na:na]

at org.springframework.http.client.SimpleClientHttpRequest.executeInternal(SimpleClientHttpRequest.java:79) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.http.client.AbstractStreamingClientHttpRequest.executeInternal(AbstractStreamingClientHttpRequest.java:71) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:81) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:900) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:801) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:415) ~[spring-web-6.2.7.jar:6.2.7]

at com.example.rest_client.controller.GreetClientController.greet(GreetClientController.java:19) ~[classes/:na]

at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]

at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]

at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.2.7.jar:6.2.7]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986) ~[spring-webmvc-6.2.7.jar:6.2.7]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891) ~[spring-webmvc-6.2.7.jar:6.2.7]

at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.2.7.jar:6.2.7]

at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.2.7.jar:6.2.7]

at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.2.7.jar:6.2.7]

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.7.jar:6.2.7]

at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.2.7.jar:6.2.7]

at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.41.jar:6.0]

at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.7.jar:6.2.7]

at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.41.jar:6.0]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.41.jar:10.1.41]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.7.jar:6.2.7]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.7.jar:6.2.7]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.7.jar:6.2.7]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.7.jar:6.2.7]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658) ~[tomcat-embed-core-10.1.41.jar:10.1.41]

at org.apache.tomcat.util.threads.TaskThread$WrappingRunn



---------------------

Next StackStrace

When RestTemplate bean is not configured.

---------------------------------

2025-06-03T17:50:35.259+05:30  INFO 18284 --- [rest-client] [           main] .s.b.a.l.ConditionEvaluationReportLogger : 


Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.

2025-06-03T17:50:35.288+05:30 ERROR 18284 --- [rest-client] [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 


***************************

APPLICATION FAILED TO START

***************************


Description:


Field restTemplate in com.example.rest_client.controller.GreetClientController required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.


The injection point has the following annotations:

- @org.springframework.beans.factory.annotation.Autowired(required=true)



Action:


Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.



Step - Solution - Still we have the problem

----------

Define Bean - Here at main Spring Boot class for time being

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

With this also Still you will get the above error cannot find the hostname with {service-name}

to solve completely , you need to add the @LoadBalanced annotation to configure with Eureka

Solution

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



Complete Code with imports

package com.example.rest_client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class RestClientApplication {

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

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


Tuesday, June 27, 2023

MS - chapter 4 - Create Config server - Problem with *

 Error


org.springframework.cloud.config.server.environment.FailedToConstructEnvironmentException: Could not construct context for config=student profile=default label=null includeOrigin=true; nested exception is while scanning an alias

 in 'reader', line 33, column 18:

            include: *

                     ^

unexpected character found  (0)

 in 'reader', line 33, column 19:

            include: *

                      ^


at org.springframework.cloud.config.server.environment.NativeEnvironmentRepository.findOne(NativeEnvironmentRepository.java:165) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.CompositeEnvironmentRepository.findOne(CompositeEnvironmentRepository.java:82) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryWrapper.lambda$findOne$3(ObservationEnvironmentRepositoryWrapper.java:75) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at io.micrometer.observation.Observation.lambda$observe$4(Observation.java:544) ~[micrometer-observation-1.11.1.jar:1.11.1]

at io.micrometer.observation.Observation.observeWithContext(Observation.java:603) ~[micrometer-observation-1.11.1.jar:1.11.1]

at io.micrometer.observation.Observation.observe(Observation.java:544) ~[micrometer-observation-1.11.1.jar:1.11.1]

at org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryWrapper.findOne(ObservationEnvironmentRepositoryWrapper.java:75) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.EnvironmentEncryptorEnvironmentRepository.findOne(EnvironmentEncryptorEnvironmentRepository.java:64) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.EnvironmentController.getEnvironment(EnvironmentController.java:134) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.EnvironmentController.defaultLabelIncludeOrigin(EnvironmentController.java:116) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]

at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]

at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:281) ~[spring-core-6.0.10.jar:6.0.10]

at org.springframework.cloud.context.scope.GenericScope$LockedScopedProxyFactoryBean.invoke(GenericScope.java:482) ~[spring-cloud-context-4.0.3.jar:4.0.3]

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.10.jar:6.0.10]

at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:756) ~[spring-aop-6.0.10.jar:6.0.10]

at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-6.0.10.jar:6.0.10]

at org.springframework.cloud.config.server.environment.EnvironmentController$$SpringCGLIB$$0.defaultLabelIncludeOrigin(<generated>) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]

at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]

at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.0.10.jar:6.0.10]

at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.10.jar:6.0]

at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.10.jar:6.0.10]

at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.10.jar:6.0]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.10.jar:6.0.10]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.10.jar:6.0.10]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.10.jar:6.0.10]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Caused by: org.yaml.snakeyaml.scanner.ScannerException: while scanning an alias

 in 'reader', line 33, column 18:

            include: *

                     ^

unexpected character found  (0)

 in 'reader', line 33, column 19:

            include: *

                      ^

Reason

Problem with * character in the yaml file. 

#Enable actuator and all
management:
endpoints:
web:
exposure:
include: *

Here we give * 

solution

give the star character inside the quotes

#Enable actuator and all
management:
endpoints:
web:
exposure:
include: "*"




MS - chapter 4 - Create Config server

 Let's create config server to keep all the configurations and get the configurations from it.

Up to now, we have kept all the configurations in the same service. Here we are going to create a separate service to keep only the configurations.

Below are the steps

1. create spring boot application adding "config server" dependency

        <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency

2. add @EnableConfigServer annotation in the main class

3. create a "config" directory inside resources folder. After that create files with each service name

eg: student.yaml

copy all the configurations from service, here student service

4. Go to respective service (student service) and add the link to configuration server.

you can keep the service name in the respective property files inside each service.

As you shown client service to import details from config server , now student service can take properties from config server

spring:
application:
name: student
config:
import: optional:configserver:http://localhost:8088
cloud:
config:
server:
bootstrap: true

5. Not enough, you need to add the config server client dependency to the student service.

<!--config server client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

6. 


   

Below is the total code samples for Config server

main class

package com.demo.micro.configserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

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

}


Student .yaml file inside "config" directory

server:
port: 8203
spring:
datasource:
url: jdbc:mysql://localhost:3306/student_mgt
username: root
password: root

# for Spring Boot 2
# spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
# for Spring Boot 3
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.MySQLDialect
show-sql: false
generate-ddl: true
# Hibernate ddl auto (create, create-drop, validate, update)
hibernate:
ddl-auto: update
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
#Enable actuator and all
management:
endpoints:
web:
exposure:
include: "*"


application.yaml

server:
port: 8088
spring:
profiles:
active: native

POM 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo.micro</groupId>
<artifactId>config-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>config-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

Student Service - application.yaml

spring:
application:
name: student
config:
import: optional:configserver:http://localhost:8088
cloud:
config:
server:
bootstrap: true