Skip to content

Commit c2bf8bd

Browse files
committed
fix issue 907. Hidden controller showing up in swagger UI when springdoc.show-actuator is enabled
1 parent 113b481 commit c2bf8bd

File tree

4 files changed

+111
-0
lines changed

4 files changed

+111
-0
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIBuilder.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
import org.springframework.beans.factory.config.BeanDefinition;
6060
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
61+
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
6162
import org.springframework.context.ApplicationContext;
6263
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
6364
import org.springframework.core.annotation.AnnotatedElementUtils;
@@ -73,6 +74,7 @@
7374
import static org.springdoc.core.Constants.DEFAULT_SERVER_DESCRIPTION;
7475
import static org.springdoc.core.Constants.DEFAULT_TITLE;
7576
import static org.springdoc.core.Constants.DEFAULT_VERSION;
77+
import static org.springdoc.core.SpringDocUtils.getConfig;
7678

7779
/**
7880
* The type Open api builder.
@@ -213,11 +215,23 @@ else if (calculatedOpenAPI.getInfo() == null) {
213215
this.mappingsMap.putAll(context.getBeansWithAnnotation(RequestMapping.class));
214216
this.mappingsMap.putAll(context.getBeansWithAnnotation(Controller.class));
215217

218+
initializeHiddenRestController();
219+
216220
// add security schemes
217221
this.calculateSecuritySchemes(calculatedOpenAPI.getComponents());
218222
openApiBuilderCustomisers.ifPresent(customisers -> customisers.forEach(customiser -> customiser.customise(this)));
219223
}
220224

225+
private void initializeHiddenRestController() {
226+
getConfig().addHiddenRestControllers(BasicErrorController.class);
227+
List<Class<?>> hiddenRestControllers = this.mappingsMap.entrySet().parallelStream()
228+
.filter(controller -> (AnnotationUtils.findAnnotation(controller.getValue().getClass(),
229+
Hidden.class) != null)).map(controller -> controller.getValue().getClass())
230+
.collect(Collectors.toList());
231+
if(!CollectionUtils.isEmpty(hiddenRestControllers))
232+
getConfig().addHiddenRestControllers(hiddenRestControllers.toArray(new Class<?>[hiddenRestControllers.size()]));
233+
}
234+
221235
/**
222236
* Update servers open api.
223237
*
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app139;
20+
21+
import io.swagger.v3.oas.annotations.Hidden;
22+
23+
import org.springframework.web.bind.annotation.GetMapping;
24+
import org.springframework.web.bind.annotation.RestController;
25+
26+
@RestController
27+
@Hidden
28+
public class HelloHiddenController {
29+
30+
@GetMapping("/testA")
31+
public void testA(String hello) {
32+
}
33+
34+
@GetMapping("/testB")
35+
public void testB(String hello) {
36+
}
37+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app139;
20+
21+
import org.hamcrest.Matchers;
22+
import org.junit.jupiter.api.Assertions;
23+
import org.junit.jupiter.api.Test;
24+
import org.springdoc.core.Constants;
25+
import test.org.springdoc.api.AbstractSpringDocTest;
26+
27+
import org.springframework.boot.autoconfigure.SpringBootApplication;
28+
import org.springframework.test.context.TestPropertySource;
29+
import org.springframework.test.web.servlet.MvcResult;
30+
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
31+
32+
import static org.hamcrest.Matchers.containsString;
33+
import static org.hamcrest.Matchers.is;
34+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
35+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
36+
37+
/**
38+
* Test issue 907 fix.
39+
* Hidden controller showing up in swagger UI when springdoc.show-actuator is enabled
40+
*/
41+
@TestPropertySource(properties = "springdoc.show-actuator=true")
42+
public class SpringDocApp139Test extends AbstractSpringDocTest {
43+
44+
@SpringBootApplication
45+
static class SpringDocTestApp {}
46+
47+
@Test
48+
public void testApp() throws Exception {
49+
MvcResult mockMvcResult = mockMvc.perform(MockMvcRequestBuilders.get(Constants.DEFAULT_API_DOCS_URL)).andExpect(status().isOk())
50+
.andExpect(jsonPath("$.openapi", is("3.0.1")))
51+
.andExpect(jsonPath("$.paths./actuator/info.get.operationId", containsString("handle_")))
52+
.andExpect(jsonPath("$.paths./actuator/info.get.summary", Matchers.is("Actuator web endpoint 'info'")))
53+
.andExpect(jsonPath("$.paths./actuator/health.get.operationId", containsString("handle_")))
54+
.andReturn();
55+
String result = mockMvcResult.getResponse().getContentAsString();
56+
String expected = getContent("results/app139.json");
57+
Assertions.assertEquals(expected, result);
58+
}
59+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://localhost","description":"Generated server url"}],"tags":[{"name":"Actuator","description":"Monitor and interact","externalDocs":{"description":"Spring Boot Actuator Web API Documentation","url":"https://docs.spring.io/spring-boot/docs/current/actuator-api/html/"}}],"paths":{"/actuator":{"get":{"tags":["Actuator"],"summary":"Actuator root web endpoint","operationId":"links_0","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Link"}}}}}}}}},"/actuator/info":{"get":{"tags":["Actuator"],"summary":"Actuator web endpoint 'info'","operationId":"handle_1","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/actuator/health":{"get":{"tags":["Actuator"],"summary":"Actuator web endpoint 'health'","operationId":"handle_2","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/actuator/health/**":{"get":{"tags":["Actuator"],"summary":"Actuator web endpoint 'health-path'","operationId":"handle_3","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}}}}},"components":{"schemas":{"Link":{"type":"object","properties":{"href":{"type":"string"},"templated":{"type":"boolean"}}}}}}

0 commit comments

Comments
 (0)