Spring Cloud Gateway Circuit Breaker: Default and Specific - spring

I have a Spring Boot application with Spring Cloud Gateway using Resilience4j for circuit breaker:
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'
Currently I have the following routes:
routes:
- id: swapi-planets
uri: https://swapi.devs/api/planets/
predicates:
- Path=/api/planets/**
filters:
- name: CircuitBreaker
args:
fallbackUri: https://swapi.dev/api/species/
- id: swapi-species
uri: https://swapi.dev/api/species/
predicates:
- Path=/api/species/**
default-filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
When I do a call to swapi-planets route I receive the following return from myCircuitBreaker:
{
"timestamp": "2022-07-21T12:48:59.402+00:00",
"path": "/api/planets",
"status": 504,
"error": "Gateway Timeout",
"requestId": "8a8cdca2-1"
}
Is there a way to ignore default circuit breaker filter when the route already have a specific circuit breaker? In this case swapi-planets has a fallbackUri.

Related

Change Server URL in Spingdoc From Remote apis

I am using the following configuration in my spring boot cloud gateway application:
spring:
cloud:
gateway:
# httpclient:
# wiretap: true
# ssl:
# use-insecure-trust-manager: true
# httpserver:
# wiretap: true
routes:
- id: humio_log
uri: ${rewrite.backend.uri:https://xxx.local}
predicates:
- Path=/api/log
filters:
- RewritePath=/api/log, /api/v1/ingest/humio-unstructured
- RemoveRequestHeader=Authorization
- AddRequestHeader=Authorization, Bearer xx
- ModifyHumioLoggingBody
- id: openapi_tasks_service
uri: ${rewrite.backend.uri:http://localhost:8082}
predicates:
- Path=/v3/api-docs/tasks-service
filters:
- RewritePath=/v3/api-docs/tasks-service, /v3/api-docs
- id: openapi_sales_org_service
uri: ${rewrite.backend.uri:http://localhost:8083}
predicates:
- Path=/v3/api-docs/sales-org-service
filters:
- RewritePath=/v3/api-docs/sales-org-service, /v3/api-docs
- id: sales_org_service
uri: ${rewrite.backend.uri:http://localhost:8083}
predicates:
- Path=/api/sos/**, /sos/**
filters:
- RewritePath=/api/sos/(?<segment>.*),/sos/$\{segment}
- id: tasks_service
uri: ${rewrite.backend.uri:http://localhost:8082}
predicates:
- Path=/api/**, /task-and-assignment/**, /task-fulfillment/**, /task-overview/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{segment}
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedHeaders: "*"
allowedMethods:
- GET
- POST
- DELETE
- PUT
springdoc:
webjars:
prefix: /openapi
swagger-ui:
urls:
- name: tasks-service
url: /v3/api-docs/tasks-service
- name: Sales-Org-Service
url: /v3/api-docs/sales-org-service
This results in the following overview:
Now I want to be able to manipulate the Dropdown of the Servers field. The remote OpenAPI is sending me this localhost:8080 back, but I want to change it to a completely different URL. Do you know of any possiblity?
Add List of ur Servers in spring openApi Configuration like bellow:
import io.swagger.v3.oas.models.*;
#Configuration
public class OpenApiConfig {
#Bean
public OpenAPI openAPiConfig() {
ArrayList<Server> servers = new ArrayList<>();
servers.add(new Server().url("http://localhost:8080").description("Local Server"));
servers.add(...);
return new OpenAPI()
.info(new Info().title("My Service").description("My Service Description")
.license(new License().url("http://MyDomainLicence.com").name("My info"))
.contact(new Contact().name("contactName")
.email("myemail#gmail.com")
.url("http://contactDomain.com"))
.version("1.0.0"))
.servers(servers);
}
}

Spring Cloud gateway fails to establish websocket connections when server expects case sensitive headers

I have a third party webapplication having websocket connections. It is expecting Upgrade, Connection header names to be case sensitive. I am using spring cloud gateway as a reverse proxy to this webapp. All the http calls are success but for websocket requests i am getting the following error
io.netty.handler.codec.http.websocketx.WebSocketClientHandshakeException:
Invalid handshake response getStatus: 404 Not Found at
io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker13.verify(WebSocketClientHandshaker13.java:272)
~[netty-codec-http-4.1.65.Final.jar:4.1.65
WebSocketClientHandshaker is setting the upgrade and connection headers and it is in lower case. How do I override these header values ?
application.yml configuration is as below
spring:
main:
web-application-type: reactive
profiles:
active: dev
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowedHeaders: "*"
httpclient:
pool:
max-idle-time: 10s
ssl:
useInsecureTrustManager: true
filter:
remove-non-proxy-headers:
headers:
- Keep-Alive
- TE
- Trailer
- Transfer-Encoding
routes:
- id : no_op
uri: no://op
predicates:
- Path=/falcon/tunneling/**
- id: reroute_ws
uri: ws://localhost:5555
predicates:
- Path=/websocket/**
- id: reroute_2
uri: http://localhost:5555
predicates:
- Path=/**

Spring Cloud Gateway - RewriteLocationResponseHeader

I have the following route inside my Spring Cloud Gateway configuration:
- id: pgadmin
uri: lb://pg-admin-service
predicates:
- Path=/pgadmin/**
filters:
- RewritePath=/pgadmin(?<segment>/?.*), $\{segment}
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, , <---- this line is incorrect
The request comes in on http://10.0.0.100/pgadmin/ as an unauthenticated user. The application returns a response containing a location header with the value:
http://10.0.0.100/login
The browser tries to rediect to that URL. Instead, it should redirect to:
http://10.0.0.100/pgadmin/login
What is the correct value for the RewriteLocationResponseHeader in the route definition?
Many thanks
JT
Try something this if you want to rewrite your path:
- id: docs
uri: lb://auth-service
predicates:
- Path=/my-auth/**
filters:
- RewritePath=/my-auth(?<segment>/?.*), $\{segment}
or to simply forward the request onto your service:
- id: docs
uri: lb://auth-service
predicates:
- Path=/my-auth/**

How to export spring boot metrics as single json

Spring boot actuator's /metrics returns list of metrics names
{
"names": [
"jvm.gc.pause",
"tomcat.global.received",
"jvm.memory.used",
...
]
}
I want to configure the metrics aggregation via elastic search metric beat. I use elastic search auto discovery and http module
metricbeat.autodiscover:
providers:
- type: kubernetes
host: ${HOSTNAME}
templates:
- condition.equals:
kubernetes.labels.app: employee-rewards
config:
- module: http
metricsets: json
period: 10s
hosts: ["${data.host}:8080"]
namespace: "app_metrics"
path: /actuator/metrics/jvm.gc.pause
method: "GET"
- module: http
metricsets: json
period: 10s
hosts: ["${data.host}:8080"]
namespace: "app_metrics"
path: /actuator/metrics/jvm.memory.used
method: "GET"
Problem with approach is when ever microservices team add a new metric, i need to configure metric beat to include the added metric.
Instead is there any way to get all the metrics values in a single json?
{
"#timestamp": "2018-08-14T20:16:02.339Z",
"tomcat_global_received_count": 0,
"tomcat_global_request_max_value": 0.3569999933242798,
"tomcat_sessions_active_current_value": 0,
"tomcat_sessions_active_max_value": 0,
"tomcat_sessions_expired_count": 0,
"tomcat_sessions_alive_max_value": 0,
"jvm_memory_committed_value": 854982656,
"jvm_gc_pause_max": 0,
"jvm_gc_pause_count": 4,
"jvm_memory_used_value": 429412576,
"tomcat_global_request_count": 106,
"host": {
"name": "webapp003.my.network.example.com"
},
"jvm_threads_peak_value": 64,
"jvm_memory_max_value": 4518313984
}
I know that actuator supports a push mechanism to push the metrics directly to elastic search. But i cannot use this because i want additional details about kubernetes environment as part of the metrics which is supported by metricsbeat.

Spring Cloud Gateway : disable default routes

I'm using spring cloud to manage my microservices.
For security reasons, for one specific microservice (name it ms_secure), I want to use custom route choose a specific microservice version depending on client IP.
My gateway config looks like this:
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: ms_secure_v1
uri: lb://ms_secure_v1
predicates:
- Path=/ms_secure/**
filters:
- RewritePath=/ms_secure/(?<segment>.*), /$\{segment}
- name: <my filter>
args:
xForwardedForHeaderName: X-Forwarded-For
hosts:
- <IP1>
- <IP2>
- id: ms_secure
uri: lb://ms_secure_v2
predicates:
- Path=/ms_secure/**
filters:
- RewritePath=/ms_secure/(?<segment>.*), /$\{segment}
- name: <my filter>
args:
xForwardedForHeaderName: X-Forwarded-For
hosts:
- <IP3>
- <IP4>
When when requesting /ms_secure:
IP1 and IP2 will be redirected to ms_secure_v1
IP3 and IP4 will be redirected to ms_secure_v2
My problem is that all my clients will also be able to access directly ms_secure_v1 or ms_secure_v2 by using the default routes:
http:///ms_secure_v1/...
http:///ms_secure_v2/...
I tried to disable these routes by using SetStatus GatewayFilter:
- id: setstatusstring_route
uri: lb://ms-gateway
predicates:
- Path=/ms_secure_v**
filters:
- SetStatus=403
But this route is not matched.
Is there a way to disable these default routes in spring gateway?
The following creates routes in gateway based on services registered:
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
Set it to false (which is the default), if you don't want this.

Resources