I am using Springboot autoconfiguration, and currently all my Feign endpoints are exposed in swagger-ui. How can I disable this feature?
You can set this in your application.properties as:
endpoints.enabled=false
endpoints.health.enabled=true
endpoints.loggers.enabled=true
In your case it will be something like
endpoints.feign.***=true
But this is not disabling for swagger but endpoints exposure themselves. For Swagger you have to markup them explicitly with #Api#hidden() for example.
So far the best way to not include unrelated endpoints is through Swagger Docker, e.g.
#Configuration
#EnableSwagger2
class SwaggerConf {
#Bean
Docket allApis() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("all")
.select().apis(RequestHandlerSelectors.basePackage("com.example.base"))
.build();
}
}
Simplest solution that worked for me is to add #ApiIgnore to the Feign Client
#ApiIgnore
#FeignClient()
public interface FeignApi {
}
Related
I am trying to implement Prometheus in my microservices based spring boot application, deployed over weblogic server. As part of POC,I have included the configs as part of one war. To enable it, i have set below config -
Application.properties
management:
endpoint:
prometheus:
enabled: true
endpoints:
web:
exposure:
include: "*"
Gradle -
implementation 'io.micrometer:micrometer-registry-prometheus'
But the actuator request is getting blocked by existing interceptors. It asks to pass values in headers specific to our project. Through postman(http:localhost:8080/abc/actuator/prometheus), I am able to test my POC(with required headers) and it returns time-series data expected by Prometheus. But Prometheus is not able to scrap data on its own(with pull approach), as the call lacks headers in request.
I tried following links (link1,link2) to bypass it, but my request still got intercepted by existing interceptor.
Interceptors blocking the request are part of dependent jars.
Edited --
I have used following way to exclude all calls to interceptor -
#Configuration
public class MyConfig implements WebMvcConfigurer{
#Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new MyCustomInterceptor()).addPathPatterns("**/actuator/**");
}
}
MyCustomInterceptor
#Component
public class MyCustomInterceptor implements HandlerInterceptor{
}
I have not implemented anything custom in MyCustomInterceptor(as i only want to exclude all calls to 'actuator' endpoint from other interceptors).
#Configuration
public class ActuatorConfig extends WebMvcEndpointManagementContextConfiguration {
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebAnnotationEndpointDiscoverer endpointDiscoverer,
EndpointMediaTypes endpointMediaTypes,
CorsEndpointProperties corsProperties,
WebEndpointProperties webEndpointProperties) {
WebMvcEndpointHandlerMapping mapping = super.webEndpointServletHandlerMapping(
endpointDiscoverer,
endpointMediaTypes,
corsProperties,
webEndpointProperties);
mapping.setInterceptors(null);
return mapping;
}
}
Maybe you can override with setting null. I got code from https://github.com/spring-projects/spring-boot/issues/11234
AFAIK Spring HandlerInterceptor do not intercept actuator's endpoints by default.
Spring Boot can't intercept actuator access
I am working on a new project in my team and we are implementing an API following the API first methodology. We are using openapi-generator-maven-plugin to generate our API from an yml file of format OpenAPI 3.0.3. To generate the swagger file we use springfox 2.9.2. The issue that I am facing is when I am trying to add security to the swagger for the requests.
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: [ ]
The Authorize button doesn't appear in swagger page, only the lock near to the request appears but it doesn't do anything (see picture below).
What I observed is that if I open the /v2/api-docs the swagger json doesn't include the security definitions part.
The only way that I managed to add security is by adding by code in the Docket object the security part like so:
new Docket(DocumentationType.SWAGGER_2)
.securityContexts(Collections.singletonList(securityContext()))
.securitySchemes(Collections.singletonList(bearerJwtKey()))
.select()
.apis(RequestHandlerSelectors.basePackage("com.example"))
.paths(PathSelectors.any())
.build();
Is this the only way to add security to Swagger UI or am I missing something?
Reason: Bearer Auth isn't implemented in spring library yet :(
Workaround solution - extend generated Docket:
Import generated config class and then add a security schema (ApiKey) to the existing Docket bean. Example:
#Configuration
#Import(OpenAPIDocumentationConfig.class) // openapi generated config class
public class SwaggerConfiguration {
#Autowired
ApplicationContext context;
#PostConstruct
public void extendExistingDocketWithSecurity() {
Docket docket = context.getBean(Docket.class);
docker.securitySchemes(Collections.singletonList(bearer()));
}
private static ApiKey bearer() {
// where "bearerAuth" - name of your schema in YML spec. file
return new ApiKey ("bearerAuth", HttpHeaders.AUTHORIZATION, "header");
}
Done! You're awesome!
Now you're using generated swagger config without overriding, but just extending
Could we add Actuator endpoints as a groupedOpenApi that will be gourped separately ?
ex :
#bean
public GroupedOpenApi actuatorApi() {
return GroupedOpenApi.builder().setGroup("Actuator")
.packagesToScan("org.springframework.boot.actuate")
.pathsToMatch("/actuator/**")
.build();
}
Thanks
First you need to enable actuator on the swagger-ui:
springdoc.show-actuator=true
You just need to declare GroupedOpenApi bean:
#Bean
public GroupedOpenApi actuatorApi(){
String[] paths = {"/actuator/**"};
return GroupedOpenApi.builder()
.setGroup("groups")
.pathsToMatch(paths)
.build();
}
Here are the steps to add actuator:
https://github.com/springdoc/springdoc-openapi-demos/commit/aa6bcf1f0312c8fc36f94aeb4653718b36c308f6
The solution provided by #brianbro mostly works but there is an issue where some endpoints that use parameters in URL, e.g. /actuator/metrics/{requiredMetricName} due to way spring boot handles the actuator endpoints (single handler method, no #PathParam) the PathParam fields don't show in Swagger. See Spring boot actuator endpoint parameters issue.
Example of what shows in Swagger without resolving the issue:
Example of what shows in Swagger after resolving the issue:
How to fix this is discussed in Adding Actuator as a groupedOpenApi but some of the links are broken. The key issue is there is an ActuatorOpenApiCustomiser class that is used to fix the PathParams for Actuator, and that class is not being called when Actuator resides within a GroupedOpenApi.
Full solution (working with springdoc:1.6.9)...
First you need to enable actuator on the swagger-ui:
springdoc.show-actuator=true
Declare GroupedOpenApi bean using code (you can't use the springdoc.group-configs[0] properties because you need to add a OpenApiCustomiser to the group):
#Bean
public GroupedOpenApi actuatorApi(OpenApiCustomiser actuatorOpenApiCustomiser){
String[] paths = {"/actuator/**"};
return GroupedOpenApi.builder()
.setGroup("Actuator")
.pathsToMatch(paths)
.addOpenApiCustomiser(actuatorOpenApiCustomiser)
.build();
}
Addtional Sample from SpringDoc
I am working on a new Spring Boot reactive server application. The application exposes reactive endpoints as shown below:
#Configuration
public class XXXXRouter {
#Bean
public RouterFunction<ServerResponse> routes(ClaimsHandler handler) {
return nest(path("/api/xxxx"), nestedRoutes(handler));
}
private static RouterFunction<ServerResponse> nestedRoutes(xxxxHandler handler) {
return route(GET("/"), handler::allClaims)
.andRoute(GET("/{id}"), handler::byId)
.andRoute(GET("/{id}/notes"), handler::notesById);
}
}
I need to make these endpoints to swagger-ui like framework. I am using following dependencies to generate required swagger-ui and api-docs:
implementation 'org.springdoc:springdoc-openapi-webflux-core:1.2.32'
implementation 'org.springdoc:springdoc-openapi-webflux-ui:1.2.32'
I also have the following API config:
#Configuration
public class OpenAPIConfig {
#Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().components(new Components()).info(new Info().title("Contact Application API")
.description("This is a sample Spring Boot RESTful service using springdoc-openapi and OpenAPI 3."));
}
}
localhost:8080/swagger-ui.html shows swagger-ui page. But, endpoints are not shown there.
Here is the output from localhost:8080/v3/api-docs:
{"openapi":"3.0.1","info":{"title":"Contact Application API","description":"This is a sample Spring Boot RESTful service using springdoc-openapi and OpenAPI 3."},"servers":[{"url":"http://localhost:8080","description":"Generated server url"}],"paths":{},"components":{}}
My question is how do we make the reactive endpoints available to swagger-ui.html?
I am trying to set up Spring Actuator with existing Gradle Spring MVC project. I am not able to use #EnableAutoConfiguration.
Unfortunately, I am not able to reach actuator endpoints, I think I am missing something.
The Spring dependencies in the project are:
// springVersion = 5.1.+
implementation(
"org.springframework:spring-beans:$springVersion",
"org.springframework:spring-webmvc:$springVersion",
"org.springframework:spring-jdbc:$springVersion")
implementation 'org.springframework.boot:spring-boot-starter-actuator'
I am trying to configure project with following:
#Configuration
#Import({EndpointAutoConfiguration.class,
MetricsEndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
MappingsEndpointAutoConfiguration.class,
InfoEndpointAutoConfiguration.class})
#EnableWebMvc
public class DI_App {
}
In properties file, I added:
management.endpoints.web.exposure.include=*
Non of actuator endpoints is enabled, I am getting 404 when trying to access them.
I went through many related questions, but non of the solutions worked for me.
I might need to define custom EndpointHandlerMapping but not sure how to do this, it seems unavailable.
(Ref: https://stackoverflow.com/a/53010693)
EDIT:
Currently, my app config looks like this:
#Configuration
#EnableWebMvc
#ComponentScan("com.test.springtest")
#Import({
ConfigurationPropertiesReportEndpointAutoConfiguration.class,
EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
HealthIndicatorAutoConfiguration.class,
InfoEndpointAutoConfiguration.class,
InfoContributorAutoConfiguration.class,
LogFileWebEndpointAutoConfiguration.class,
LoggersEndpointAutoConfiguration.class,
WebMvcMetricsAutoConfiguration.class,
ManagementWebSecurityAutoConfiguration.class,
ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class
})
public class DI_App {
private final ApplicationContext _applicationContext;
DI_App(ApplicationContext applicationContext) {
_applicationContext = applicationContext;
System.setProperty("management.endpoints.web.exposure.include", "*");
System.setProperty("management.endpoints.jmx.exposure.exclude", "*");
System.setProperty("management.endpoints.web.base-path", "/manage");
System.setProperty("management.server.port", "10100");
}
#Bean
public WebMvcEndpointHandlerMapping endpointHandlerMapping(Collection<ExposableWebEndpoint> endpoints) {
List<String> mediaTypes = List.of(MediaType.APPLICATION_JSON_VALUE, ActuatorMediaType.V2_JSON);
EndpointMediaTypes endpointMediaTypes = new EndpointMediaTypes(mediaTypes, mediaTypes);
WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(_applicationContext,
new ConversionServiceParameterValueMapper(),
endpointMediaTypes,
List.of(EndpointId::toString),
emptyList(),
emptyList());
return new WebMvcEndpointHandlerMapping(new EndpointMapping("/manage"),
endpoints,
endpointMediaTypes,
new CorsConfiguration(),
new EndpointLinksResolver(discoverer.getEndpoints()));
}
}
I had to add dispatcherServlet bean, in order to be able to add ManagementContextAutoConfiguration.class to Imports:
#Component
public class AppDispatcherServlet implements DispatcherServletPath {
#Override
public String getPath() {
return "/";
}
}
Current state is that when going to /manage endpoint I get this:
{"_links":{"self":{"href":"http://localhost:10100/dev/manage","templated":false},"info":{"href":"http://localhost:10100/dev/manage/info","templated":false}}}
But http://localhost:10100/dev/manage/info returns 404 and no other endpoints are available.
I'm using Maven, not Gradle, but was in a similar situation. I had a working spring-boot-actuator 1.4.2.RELEASE Health actuator endpoint with Spring MVC 4.3.21. Upgraded to spring-boot-starter-actuator 2.6.1 and Spring MVC 5.3.13 and the following works for me to reach /myAppContext/health.
The DispatcherServletAutoConfiguration import may be able to replace your explicit DispatcherServlet bean. My case doesn't include the Info actuator endpoint but the key thing for me was the specific Imports below. Order is somewhat important for certain imports, at least in my testing.
I know very little about spring boot so this is the result of enabling auto configuration, pouring through spring boot TRACE log output, and trying lots of different import combinations.
#Configuration
#EnableWebMvc
#Import({
DispatcherServletAutoConfiguration.class,
WebMvcAutoConfiguration.class,
WebEndpointAutoConfiguration.class,
EndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
WebMvcEndpointManagementContextConfiguration.class
})
#PropertySource("classpath:/health.properties")
public class MyAppActuatorConfig {
// 1.x version had EndpointHandlerMapping and HealthMvcEndpoint beans here.
// There may be a more spring-boot-ish way to get this done : )
}
And a minimal health.properties that suited my deployment specifics where security was already in place:
management.endpoints.web.base-path=/
management.endpoint.health.show-details=when-authorized
management.endpoint.health.show-components=when-authorized