API Gateway doesn't aggregate microservices swagger docs Spring boot - java

Pom.xml:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.7</version>
</dependency>
SwaggerConfig.java:
#Configuration
#RequiredArgsConstructor
public class SwaggerConfig {
private final RouteDefinitionLocator locator;
#Bean
public List<GroupedOpenApi> apis() {
List<GroupedOpenApi> groups = new ArrayList<>();
List<RouteDefinition> definitions = locator.getRouteDefinitions().collectList().block();
definitions.stream().filter(routeDefinition -> routeDefinition.getId().matches(".*-service")).forEach(routeDefinition -> {
String name = routeDefinition.getId().replaceAll("-service", "");
GroupedOpenApi api = GroupedOpenApi.builder().pathsToMatch("/" + name + "/**").group(name).build();
groups.add(api);
});
return groups;
}
}
application.yml:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
routes:
- id: swagger
uri: http://localhost:${server.port}
predicates:
- Path=/v3/api-docs/**
filters:
- RewritePath=/v3/api-docs/(?<path>.*), /$\{path}/v3/api-docs
- id: test-service
uri: lb://test-service
predicates:
- Path=/testservice/**
filters:
- RewritePath=/testservice/(?<path>.*), /$\{path}
Api gateway sees test-service with the help of discovery-server. When I enter swagger-ui of my gateway server,
in the "Select a definition" tab I only see "default" definition but no test-service definition that I really want. I've used those tutorials:
https://piotrminkowski.com/2020/02/20/microservices-api-documentation-with-springdoc-openapi/
https://dgempiuc.medium.com/api-gateway-swagger-composition-e9416398ca47
Screenshot:

I solved with this application.yml:
spring:
cloud:
gateway:
routes:
- id: openapi
uri: http://localhost:${server.port}
predicates:
- Path=/v3/api-docs/**
filters:
- RewritePath=/v3/api-docs/(?<path>.*), /$\{path}/v3/api-docs
- id: characters-service
uri: lb://characters-service
predicates:
- Path=/characters-service/**
filters:
- RewritePath=/characters-service/(?<path>.*), /$\{path}
springdoc:
enable-native-support: true
api-docs:
groups:
enabled: true
enabled: true
group-configs:
- group: api-gateway
packages-to-scan:
- dev.kambei.apigateway
display-name: API Gateway
- group: characters-service
paths-to-match:
- /characters-service/**
display-name: Characters Service
swagger-ui:
config-url: /v3/api-docs/swagger-config
url: /v3/api-docs
urls:
- url: /v3/api-docs
name: API Gateway
- url: /characters-service/v3/api-docs
name: Characters Service

you can add this config in the yaml fie
springdoc:
api-docs:
enabled: true
swagger-ui:
config-url: v3/api-docs/swagger-config
url: /v3/api-docs
urls:
- name: test
url: /v3/api-docs/test

Related

Config Server URI not detected in Spring Boot Microservice Project

I am working on a microservice project and implementing the Config Server using GitHub.
I created following files on GitHub-
Each file has the same configuration code (the common configuration for microservices) with different names-
spring:
application:
name: Config-default
eureka:
instance:
prefer-ip-address: true
client:
fetch-registry: true #true by default
register-with-eureka: true #true by default
service-url:
defaultZone: http://localhost:8761/eureka #url of the eureka server, registers with this url
I use the #EnableConfigServer annotation for the configuration server.
In the application.yml for the Configuration Server Microservice I add-
server:
port: 8089
spring:
application:
name: CONFIG-SERVER
cloud:
config:
server:
git:
uri: <github repository url>
clone-on-start: true
For the client microservices I added following dependency to pom.xml-
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
In the application.yml for the clients I add the configuration-
spring:
application:
name: USER-SERVICE #changes the name of application from UNKNOWN to UserService
config:
import: optional:configserver:http://localhost:8089
profiles:
active: prod
Problem- When I try to run my configuration server microservice I get the following error message-
***************************
APPLICATION FAILED TO START
***************************
Description:
Invalid config server configuration.
Action:
If you are using the git profile, you need to set a Git URI in your configuration. If you have set spring.cloud.config.server.bootstrap=true, you need to use a composite configuration.
Can somebody please help me find out the problem, why the URL is not detected.

Spring springdoc-openapi : swagger-ui/index.html cannot be found status=404

I've a spring boot application (2.5.6) with a dependency on springdoc-openapi.
However, launching swagger-ui (http://localhost:8080/v1/swagger-ui/index.html) doesn't work.
The debug logs are indicating that index.html is not present.
What could be the reason that index.html is not found ?
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.8</version>
</dependency>
application.yaml
springdoc:
swagger-ui:
tagsSorter: alpha
operations-sorter: alpha
doc-expansion: none
disable-swagger-default-url: true
logging:
level:
root: DEBUG
server:
port: 8080
spring:
application:
name: fe-applic-app
api-version: "v1"
I found the cause of the problem. The context-path was not set in application.yaml.
http://localhost:8080/v1/swagger-ui/index.html
After adding servlet : context-path, swagger-ui is rendered
server:
port: 8080
servlet:
context-path: "/${spring.application.api-version}"
Try swagger-ui.html instead of swagger-ui/index.html. In 60% of the cases swagger-ui.html redirects to its real location.
http://localhost:8080/v1/swagger-ui.html
http://localhost:8080/v3/swagger-ui.html
add this to your configs:
#Configuration
public class WebAppConfig extends WebMvcConfigurationSupport
{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/4.14.3/");
}
see source
and static-resources

How to collect the Prometheus metrics in a java program?

I searched most of the articles, but not found my expected solutions. I am new to Prometheus. I need to get the Prometheus metrics to collect by my java program. So, need help to read or get the Prometheus metrics by my java program.
Any help or suggestion would be helpful.
Thanks
If you are using Spring boot 2.1.5.RELEASE then
add dependencies actuator and micrometer-prometheus
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
add config to enable access to endpoint /actuator/prometheus
management:
endpoints:
web:
exposure:
include: '*'
try to request http://domain:port/actuator/prometheus
EDIT
For kubernetes im using kind deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myAppName
spec:
replicas: 1
selector:
matchLabels:
app: myAppName
template:
metadata:
labels:
app: myAppName
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8091"
prometheus.io/path: "/actuator/prometheus"
spec:
containers:
- name: myAppName
image: images.com/app-service:master
imagePullPolicy: Always
ports:
- containerPort: 8091
env:
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: CONFIG_SERVER_ADDRESS
value: "http://config-server:8888"
livenessProbe:
failureThreshold: 3
httpGet:
path: /actuator/health
port: 8091
scheme: HTTP
initialDelaySeconds: 45
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
failureThreshold: 5
httpGet:
path: /actuator/health
port: 8091
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
nodeSelector:
servicetype: mvp-cluster
There are bunch of ways you can do it Please refer this https://github.com/prometheus/client_java

Spring cloud config client load local properties if the config server is down

I am trying to access the spring cloud config server but it is down. I still want to test the application using local application.properties. Is there any way i could do this?
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
bootstrap.yml
server:
port: 8086
spring:
application:
name: PromoMS
security:
basic:
enabled: false
management:
security:
enabled: false
cloud:
config:
fail-fast: true
discovery:
enabled: true
service-id: ms-config-server
I am getting following exception
java.lang.IllegalStateException: No instances found of configserver (ms-config-server)
at org.springframework.cloud.config.client.ConfigServerInstanceProvider.getConfigServerInstances(ConfigServerInstanceProvider.java:48) ~[spring-cloud-config-client-2.2.2.RELEASE.jar:2.2.2.RELEASE]
To disable spring-cloud-config you and use your local properties, you need to add this property to your bootstrap.yml:
spring.cloud.config.enabled=false
And then enable it only when you need to run your application via application args, something like this:
java -jar your-application-name.jar --spring.cloud.config.enabled=true

Zuul proxy not routing

While working on spring Microservices I am not able to route api through zuul proxy
This is my code
eurka:
application.yml
spring:
application:
name: api
cloud:
config:
enabled: true
server:
port: ${PORT:8761}
eureka:
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
instance:
hostname: localhost
zuul:
application.yml
spring:
application:
name: proxy-server
server:
port: 8079
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
fetchRegistry: true
zuul:
ignored-services: '*'
prefix: /api
routes:
account:
path: /account/**
serviceId: account
stripPrefix: false
host:
socket-timeout-millis: 30000
ribbion:
eureka:
enabled: true
account
application.yml
ribbion:
eureka:
enabled: true
eureka:
instance:
preferIpAddress: true
client:
serviceUrl:
defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
instance:
preferIpAddress: true
dependency:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Now the url localhost:8080/user/ is working fine but localhost:8080/api/account/user/ is throwing a 404.
Not sure what wrong I am doing here, any insight will be helpful please let me know if you need other details
What you need to do is,
Generate a Spring boot project with Zuul as a dependency.
Annotate the main class with #EnableZuulProxy
Configure routes and endpoints in application.properties file
Build and start the service
I suggest to implement the above steps first and make them work. Then customize that project as per your need. Found below article explaining the above steps with more details.
How to build an API-Gateway with Netflix Zuul + Spring Boot
I think you forgotten to add the name the of account service in account application.yml
spring:
application:
name: account

Categories