Reputation: 1499
I created a discovery server using Eureka, I added a gateway and 2 webservices. All I added 2 webservices and a gateway. My service do correctly register to Eureka. I am using :
I want to have all swagger documentation available in the gateway.
On webservices I added the following dependencies:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>
On each I also add OpenApiDefinition annotation:
...
@OpenAPIDefinition(info =
@Info(
title = "User Management and authentication Webservice",
description = "This web service allow register, log in and update user profile",
version = "1.0",
contact = @Contact(
name = "Technical Service",
url = "https://www.******/",
email = "****@****"
),
termsOfService = "https://www.*****",
license = @License(name = "Apache 2.0", url = "http://www.apache.org/licenses/LICENSE-2.0")
))
public class UserWsApplication {
public static void main(String[] args) {
SpringApplication.run(UserWsApplication.class, args);
}
}
On user webservice I added the following setting (extract):
server.port=${PORT:0}
spring.application.name=users-ws
springdoc.show-actuator=false
The second web service:
server.port=${PORT:0}
spring.application.name=licences-ws
springdoc.show-actuator=false
On the gateway, I added the following dependency
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
<version>2.3.0</version>
</dependency>
I configured my routes
# remote openapi
spring.cloud.gateway.routes[0].id=openapi
spring.cloud.gateway.routes[0].uri = http://localhost:${server.port}
spring.cloud.gateway.routes[0].predicates[0]=Path=/v3/api-docs/**
spring.cloud.gateway.routes[0].filters[0]=RewritePath=/v3/api-docs/(?<segment>.*), /$\{segment}/v3/api-docs
# status public page
spring.cloud.gateway.routes[1].id=users-ws-status
spring.cloud.gateway.routes[1].uri = lb://users-ws
spring.cloud.gateway.routes[1].predicates[0]=Path=/users/status
spring.cloud.gateway.routes[1].predicates[1]=Method=GET
spring.cloud.gateway.routes[1].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[1].filters[1]=RewritePath=/users-ws/users/status, /users/status
# user registration routes do not need filter
spring.cloud.gateway.routes[2].id=users-ws
spring.cloud.gateway.routes[2].uri = lb://users-ws
spring.cloud.gateway.routes[2].predicates[0]=Path=/users
spring.cloud.gateway.routes[2].predicates[1]=Method=POST
spring.cloud.gateway.routes[2].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[2].filters[1]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}
spring.cloud.gateway.routes[3].id = users-ws-login
spring.cloud.gateway.routes[3].uri = lb://users-ws
spring.cloud.gateway.routes[3].predicates[0]=Path=/users/login
spring.cloud.gateway.routes[3].predicates[1]=Method=POST
spring.cloud.gateway.routes[3].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[3].filters[1]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}
# reset request
spring.cloud.gateway.routes[4].id = users-ws-auth-reset-request
spring.cloud.gateway.routes[4].uri = lb://users-ws
spring.cloud.gateway.routes[4].predicates[0]=Path=/users/password-reset-request
spring.cloud.gateway.routes[4].predicates[1]=Method=POST
spring.cloud.gateway.routes[4].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[4].filters[1]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}
# reset password validation: we send get request with request param named token
spring.cloud.gateway.routes[5].id = users-ws-auth-reset-validation
spring.cloud.gateway.routes[5].uri = lb://users-ws
spring.cloud.gateway.routes[5].predicates[0]=Path=/users/password-reset
#spring.cloud.gateway.routes[5].predicates[1]=Query=token
spring.cloud.gateway.routes[5].predicates[1]=Method=POST
spring.cloud.gateway.routes[5].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[5].filters[1]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}
# user management routes do need filter
spring.cloud.gateway.routes[6].id=users-management-ws
spring.cloud.gateway.routes[6].uri=lb://users-ws
spring.cloud.gateway.routes[6].predicates[0]=Path=/users/**
spring.cloud.gateway.routes[6].predicates[1]=Method=GET,PUT,DELETE
spring.cloud.gateway.routes[6].predicates[2]=Header=Authorization, Bearer (.*)
spring.cloud.gateway.routes[6].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[6].filters[1]=AuthorizationHeaderFilter
spring.cloud.gateway.routes[6].filters[2]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}
# configuring filter for actuator
spring.cloud.gateway.routes[7].id = users-ws-actuator
spring.cloud.gateway.routes[7].uri = lb://users-ws
spring.cloud.gateway.routes[7].predicates[0]=Path=/users-ws/actuator/**
spring.cloud.gateway.routes[7].predicates[1]=Method=GET
spring.cloud.gateway.routes[7].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[7].filters[1]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}
# user registration routes do not need filter
spring.cloud.gateway.routes[8].id=licences-ws
spring.cloud.gateway.routes[8].uri = lb://licences-ws
spring.cloud.gateway.routes[8].predicates[0]=Path=/users/**
spring.cloud.gateway.routes[8].predicates[1]=Method=POST,GET
spring.cloud.gateway.routes[8].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[8].filters[1]=RewritePath=/licences-ws/(?<segment>.*), /$\{segment}
I also added then following settings for open api doc
springdoc.swagger-ui.use-root-path=true
springdoc.api-docs.enabled=true
#springdoc.api-docs.path=/api-docs
springdoc.swagger-ui.enabled=true
springdoc.swagger-ui.path=/swagger-ui.html
springdoc.swagger-ui.config-url=/v3/api-docs/swagger-config
springdoc.swagger-ui.urls[0]=/v3/api-docs
springdoc.swagger-ui.urls[0].name=API Gateway Service
springdoc.swagger-ui.urls[0].display-name=API Gateway Service
#springdoc.swagger-ui.urls[0].primaryName=API Gateway Service
springdoc.swagger-ui.urls[1].name=users
springdoc.swagger-ui.urls[1]=/v3/api-docs/users-ws
springdoc.swagger-ui.urls[1].display-name=Users Service
springdoc.swagger-ui.urls[2].name=licences
springdoc.swagger-ui.urls[2]=/v3/api-docs/licences-ws
springdoc.swagger-ui.urls[2].display-name=Licences Service
server.forward-headers-strategy=framework
And finally added the following configuration bean
@Bean
public List<GroupedOpenApi> apis(RouteDefinitionLocator locator) {
List<GroupedOpenApi> groups = new ArrayList<>();
List<RouteDefinition> definitions = locator
.getRouteDefinitions()
.collectList()
.block();
assert definitions != null;
definitions.forEach(definition ->
System.out.println("id: " + definition.getId() + " " +
definition.getUri().toString()));
System.out.println("**************************");
definitions.stream()
.filter(routeDefinition -> routeDefinition.getId()
.matches(".*-ws"))
.forEach(routeDefinition -> {
String name = routeDefinition
.getId()
.replaceAll("-ws", "");
System.out.println("Name >> " + name);
groups.add(GroupedOpenApi.builder()
.pathsToMatch("/" + name + "/**")
.group(name)
.build());
});
// we add services without ws in name
return groups;
}
When running my application:
My issue is:
Part of my openAPI implementation comes from here: https://github.com/piomin/sample-spring-microservices-new
Upvotes: 1
Views: 563
Reputation: 1499
I finally solved a few days ago. I simply added the OpenApiDefinition annotation with servers param on each micro services that register to Eureka:
@OpenAPIDefinition(
servers = { @Server(url = "/setups", description = "Default URL") },
info = @Info(
title = "...",
version = "1.0.0",
description = "..."))
Upvotes: 0