Spring Cloud Gateway with CircuitBreaker - spring

I am getting following exception while starting Gateway spring boot Application
ava.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name CircuitBreaker
filter configuration is
filters:
- name: CircuitBreaker
args:
name: MicroService
fallback: forward:/fallbackurl
Does any one has idea how can this be fixed.
``

Related

Spring Cloud API gateway not working after deploying it on tomcat

After deploying the gateway war file on tomcat not able to access it.
application.yml file setup
server:
port: 9000
servlet:
context-path: /gateway
spring:
cloud:
gateway:
routes:
- id: mysqlservice
uri: http://localhost:8080
predicates:
- Path= /gateway/mysql/**
filters:
- StripPrefix=1
- id: xyzservice
uri: http://localhost:8080
predicates:
- Path= /gateway/xyz/**
filters:
- StripPrefix=1
- id: lightservice
uri: http://localhost:8080
predicates:
- Path= /gateway/light/**
filters:
- StripPrefix=1
The above configuration works fine when I run it through the normal spring boot JAR file
Ex. http://localhost:9000/gateway/mysql/mysqlapi/test
when it deployed on the tomcat server that time I am not able to access it
Ex. Ex. http://localhost:8080/gateway/mysql/mysqlapi/test
So how can i access it from tomcat server?
You can’t as it is not supported:
Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux. It does not work in a traditional Servlet Container or when built as a WAR.

Quarkus application - add base path to OpenAPI definition

I'm currently working on a Quarkus based API that is due to be hosted on an API gateway that requires our application to be running with a base-path and I found out that by setting quarkus.resteasy.path in application.properties I can run the application with a base-path and it is being added to the specification automatically.
I am generating an OpenAPI 3 specification by using org.eclipse.microprofile.openapi.annotations. My problem is that in the specification this base-path is added to every single operation. I am instead trying to only apply the base-path within the servers declaration basically like the equivalent of what basePath used to be in OpenAPI 2.0.
Current outcome:
servers:
- url: https://dev.example.com
description: Development
- url: https://example.com
description: Production
security:
- jwt: []
paths:
/api/capacity/availability:
get:
...
/api/capacity/consume:
post:
...
Desired outcome:
servers:
- url: https://dev.example.com/api
description: Development
- url: https://example.com/api
description: Production
security:
- jwt: []
paths:
/capacity/availability:
get:
...
/capacity/consume:
post:
...
Any help would be appreciated.
You can also use config to set the servers: quarkus.smallrye-openapi.servers
See https://quarkus.io/guides/openapi-swaggerui#quarkus-smallrye-openapi_quarkus.smallrye-openapi.servers

Spring cloud gateway refresh with RewritePath fails

I'm running a spring cloud gateway instance that relies on spring cloud configuration server. My application starts up with the given following configuration.
cloud:
gateway:
routes:
- id: route-foo
uri: lb://foo
predicates:
- Path=/api/foo/**
filters:
- name: RewritePath
args:
regexp: "/api/foo/(?<remaining>.*)"
replacement: "/${remaining}"
Say I make a modification to my configuration and add an additional route below
- id: route-bar
uri: lb://bar
predicates:
- Path=/api/bar/**
filters:
- name: RewritePath
args:
regexp: "/api/bar/(?<remaining>.*)"
replacement: "/${remaining}"
Executing a POST to http://localhost:8080/actuator/refresh returns the following error.
500 Server Error for HTTP POST "/actuator/refresh" (Encoded)
java.lang.IllegalArgumentException: Could not resolve placeholder 'remaining' in value "/${remaining}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:178)
It appears that spring is trying to parse my RewritePath replacement and substitute it with environment variables. What are my options?
You're running into spring trying to replace variables in your configuration.
There are two solutions
Escape the replacement syntax (Preferred)
change replacement: "/${remaining}"
to replacement: "/$\\{remaining}"
The RewriteGatewayFilterFactory does a replace on the configuration before running the filter.
Enable ignoreUnresolvableNestedPlaceholders
#Bean
#Primary
public StandardReactiveWebEnvironment standardReactiveWebEnvironmentCustomizer(StandardReactiveWebEnvironment environment) {
environment.setIgnoreUnresolvableNestedPlaceholders(true);
return environment;
}
This will leave all unresolvable placeholders alone in your configuration and not fail during the refresh. I would recommend against this approach as it may end up delaying some issues into runtime if you're relying on a field to be populated correctly.
Theoretically you should be able to accomplish this same functionality with the PropertySourcesPlaceholderConfigurer, I had a hard time getting that to cooperate.

Spring Cloud Gateway and TokenRelay Filter

I’m trying to migrate JHipster from using Zuul to Spring Cloud Gateway. JHipster uses Eureka to look up routes and I believe I’ve configured Spring Cloud Gateway correctly to look up routes and propagate the access token to them. Here’s my config:
spring:
cloud:
gateway:
default-filters:
- TokenRelay
discovery:
locator:
enabled: true
lower-case-service-id: true
route-id-prefix: /services/
httpclient:
pool:
max-connections: 1000
The problem I’m experiencing is the access token is not sending an Authorization header to the downstream services.
Here's how things were configured with Zuul in my application.yml:
zuul: # those values must be configured depending on the application specific needs
sensitive-headers: Cookie,Set-Cookie #see https://github.com/spring-cloud/spring-cloud-netflix/issues/3126
host:
max-total-connections: 1000
max-per-route-connections: 100
prefix: /services
semaphore:
max-semaphores: 500
I created a pull request to show what's changed after integrating Spring Cloud Gateway.
https://github.com/mraible/jhipster-reactive-microservices-oauth2/pull/4
Steps to reproduce the issue:
git clone -b reactive git#github.com:mraible/jhipster-reactive-microservices-oauth2.git
Start JHipster Registry, Keycloak, and the gateway app:
cd jhipster-reactive-microservices-oauth2/gateway
docker-compose -f src/main/docker/jhipster-registry.yml up -d
docker-compose -f src/main/docker/keycloak.yml up -d
./mvnw
Start MongoDB and the blog app:
cd ../blog
docker-compose -f src/main/docker/mongodb.yml up -d
./mvnw
Navigate to http://localhost:8080 in your browser, log in with admin/admin, and try to go to Entities > Blog. You will get a 403 access denied error. If you look in Chrome Developer Tools at the network traffic, you'll see the access token isn't included in any headers.
I was able to solve this using this answer.
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
predicates:
- name: Path
args:
pattern: "'/services/'+serviceId.toLowerCase()+'/**'"
filters:
- name: RewritePath
args:
regexp: "'/services/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
I also had to add .pathMatchers("/services/**").authenticated() to my security config, which wasn't needed for Zuul. You can see my commit here.

Dockerized Spring boot and Zuul

I got troubles get Zuul working with a dockerized Spring boot app.
It seems Zuul is not able to proxy requests to the target application (gis_import_export) even if it is up and running.
My Zuul based Spring app configuration:
spring:
banner:
location: classpath:banner.txt
zuul:
debug:
request: true
routes:
ie:
url: http://gis_import_export:8080
geoserver:
url: http://geoserver:8080
geonetwork:
url: http://geonetwork:8080
ribbon:
eureka:
enabled: false
and my docker-compose.yml file:
version: "3"
services:
geoserver:
image: kartoza/geoserver
geonetwork:
image: geonetwork
postgres:
image: postgres
environment:
- POSTGRES_DB=xxx
- POSTGRES_PASSWORD=xxx
- POSTGRES_USER=xxx
gis_import_export:
image: gis_import_export:develop
ports:
- 8888:8080
zuul:
image: gis_api_gateway:develop
ports:
- 8080:8080
I'm able to have geonetwork/geoserver proxied correctly via Zuul service exposed port but I'm stuck with getting with Spring boot app seems not get proxied.
By the way, the dockerized Spring boot apps works as expected if accessed via the 8888 port and via Zuul if zuul itself is not deployed via Docker.
Running a ping/telnet to dockerized spring boot app inside the Zuul docker container works as expected, so names are being resolved correctly.
Ideas?
Thanks, FB
Your services running in different docker networkds.
You have to specify same network in two files network.
And of course it will be good if you specify hostname parameter for each container

Resources