Skip to content

Commit 808b654

Browse files
author
springdoc
committed
fixes #96
1 parent f0ededb commit 808b654

File tree

6 files changed

+181
-24
lines changed

6 files changed

+181
-24
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java

+30-23
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public abstract class AbstractOpenApiResource {
4444
protected RequestBodyBuilder requestBodyBuilder;
4545
protected GeneralInfoBuilder generalInfoBuilder;
4646
protected Optional<List<OpenApiCustomiser>> openApiCustomisers;
47+
private boolean computeDone;
4748

4849
protected AbstractOpenApiResource(OpenAPIBuilder openAPIBuilder, AbstractRequestBuilder requestBuilder,
4950
AbstractResponseBuilder responseBuilder, OperationBuilder operationParser,
@@ -59,29 +60,35 @@ protected AbstractOpenApiResource(OpenAPIBuilder openAPIBuilder, AbstractRequest
5960
}
6061

6162
protected OpenAPI getOpenApi() {
62-
Instant start = Instant.now();
63-
generalInfoBuilder.build(openAPIBuilder.getOpenAPI());
64-
Map<String, Object> restControllersMap = generalInfoBuilder.getRestControllersMap();
65-
Map<String, Object> requestMappingMap = generalInfoBuilder.getRequestMappingMap();
66-
Map<String, Object> restControllers = Stream.of(restControllersMap, requestMappingMap)
67-
.flatMap(mapEl -> mapEl.entrySet().stream())
68-
.filter(controller -> (AnnotationUtils.findAnnotation(controller.getValue().getClass(),
69-
Hidden.class) == null))
70-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1));
71-
72-
Map<String, Object> findControllerAdvice = generalInfoBuilder.getControllerAdviceMap();
73-
// calculate generic responses
74-
responseBuilder.buildGenericResponse(openAPIBuilder.getComponents(), findControllerAdvice);
75-
76-
getPaths(restControllers);
77-
OpenAPI openApi = openAPIBuilder.getOpenAPI();
78-
79-
// run the optional customisers
80-
if (openApiCustomisers.isPresent()) {
81-
openApiCustomisers.get().stream().forEach(openApiCustomiser -> openApiCustomiser.customise(openApi));
82-
}
83-
84-
LOGGER.info("Init duration for springdoc-openapi is: {} ms", Duration.between(start, Instant.now()).toMillis());
63+
OpenAPI openApi;
64+
if (!computeDone) {
65+
Instant start = Instant.now();
66+
generalInfoBuilder.build(openAPIBuilder.getOpenAPI());
67+
Map<String, Object> restControllersMap = generalInfoBuilder.getRestControllersMap();
68+
Map<String, Object> requestMappingMap = generalInfoBuilder.getRequestMappingMap();
69+
Map<String, Object> restControllers = Stream.of(restControllersMap, requestMappingMap)
70+
.flatMap(mapEl -> mapEl.entrySet().stream())
71+
.filter(controller -> (AnnotationUtils.findAnnotation(controller.getValue().getClass(),
72+
Hidden.class) == null))
73+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1));
74+
75+
Map<String, Object> findControllerAdvice = generalInfoBuilder.getControllerAdviceMap();
76+
// calculate generic responses
77+
responseBuilder.buildGenericResponse(openAPIBuilder.getComponents(), findControllerAdvice);
78+
79+
getPaths(restControllers);
80+
openApi = openAPIBuilder.getOpenAPI();
81+
82+
// run the optional customisers
83+
if (openApiCustomisers.isPresent()) {
84+
openApiCustomisers.get().stream().forEach(openApiCustomiser -> openApiCustomiser.customise(openApi));
85+
}
86+
LOGGER.info("Init duration for springdoc-openapi is: {} ms",
87+
Duration.between(start, Instant.now()).toMillis());
88+
computeDone = true;
89+
} else {
90+
openApi = openAPIBuilder.getOpenAPI();
91+
}
8592
return openApi;
8693
}
8794

springdoc-openapi-core/src/test/java/test/org/springdoc/api/AbstractSpringDocTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
public abstract class AbstractSpringDocTest {
2828

2929
@Autowired
30-
private MockMvc mockMvc;
30+
protected MockMvc mockMvc;
3131

3232
@Test
3333
public void testApp() throws Exception {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package test.org.springdoc.api.app41;
2+
3+
import javax.validation.Valid;
4+
import javax.validation.constraints.NotNull;
5+
6+
import org.springframework.http.HttpStatus;
7+
import org.springframework.http.MediaType;
8+
import org.springframework.http.ResponseEntity;
9+
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.web.bind.annotation.RequestParam;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
import io.swagger.v3.oas.annotations.Operation;
14+
import io.swagger.v3.oas.annotations.Parameter;
15+
import io.swagger.v3.oas.annotations.media.Content;
16+
import io.swagger.v3.oas.annotations.media.Schema;
17+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
18+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
19+
20+
@RestController("/api")
21+
public class HelloController {
22+
23+
@Operation(description = "Download file")
24+
@ApiResponses(value = {
25+
@ApiResponse(responseCode = "200", description = "File resource", content = @Content(schema = @Schema(implementation = java.io.File.class))),
26+
@ApiResponse(responseCode = "400", description = "Wrong request", content = @Content(schema = @Schema(implementation = java.lang.Error.class))),
27+
@ApiResponse(responseCode = "500", description = "Unexpected error", content = @Content(schema = @Schema(implementation = java.lang.Error.class))) })
28+
@GetMapping(value = "/file", produces = MediaType.APPLICATION_JSON_VALUE)
29+
public ResponseEntity<java.io.File> getFile(
30+
@NotNull @Parameter(description = "File path", required = true) @Valid @RequestParam(value = "path") String path) {
31+
return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build();
32+
}
33+
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package test.org.springdoc.api.app41;
2+
3+
import static org.hamcrest.Matchers.*;
4+
import static org.skyscreamer.jsonassert.JSONAssert.*;
5+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
6+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
7+
8+
import java.nio.file.Files;
9+
import java.nio.file.Path;
10+
import java.nio.file.Paths;
11+
12+
import org.junit.Test;
13+
import org.springdoc.core.Constants;
14+
import org.springframework.test.web.servlet.MvcResult;
15+
16+
import test.org.springdoc.api.AbstractSpringDocTest;
17+
18+
public class SpringDocApp41Test extends AbstractSpringDocTest {
19+
20+
@Test
21+
public void testApp() throws Exception {
22+
String className = getClass().getSimpleName();
23+
String testNumber = className.replaceAll("[^0-9]", "");
24+
MvcResult mockMvcResult = mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL)).andExpect(status().isOk())
25+
.andExpect(jsonPath("$.openapi", is("3.0.1"))).andReturn();
26+
// Test result consistency
27+
mockMvcResult = mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL)).andExpect(status().isOk())
28+
.andExpect(jsonPath("$.openapi", is("3.0.1"))).andReturn();
29+
String result = mockMvcResult.getResponse().getContentAsString();
30+
Path path = Paths.get(getClass().getClassLoader().getResource("results/app" + testNumber + ".json").toURI());
31+
byte[] fileBytes = Files.readAllBytes(path);
32+
String expected = new String(fileBytes);
33+
assertEquals(expected, result, false);
34+
}
35+
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package test.org.springdoc.api.app41;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class SpringDocTestApp {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(SpringDocTestApp.class, args);
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"openapi":"3.0.1",
3+
"info":{
4+
"title":"OpenAPI definition",
5+
"version":"v0"
6+
},
7+
"servers":[
8+
{
9+
"url":"http://localhost",
10+
"description":"Generated server url"
11+
}
12+
],
13+
"paths":{
14+
"/file":{
15+
"get":{
16+
"description":"Download file",
17+
"operationId":"getFile",
18+
"parameters":[
19+
{
20+
"name":"path",
21+
"in":"query",
22+
"description":"File path",
23+
"required":true,
24+
"schema":{
25+
"type":"string"
26+
}
27+
}
28+
],
29+
"responses":{
30+
"200":{
31+
"description":"File resource",
32+
"content":{
33+
"application/json":{
34+
"schema":{
35+
"type":"string",
36+
"format":"binary"
37+
}
38+
}
39+
}
40+
},
41+
"400":{
42+
"description":"Wrong request",
43+
"content":{
44+
"application/json":{
45+
"schema":{
46+
"type":"error"
47+
}
48+
}
49+
}
50+
},
51+
"500":{
52+
"description":"Unexpected error",
53+
"content":{
54+
"application/json":{
55+
"schema":{
56+
"type":"error"
57+
}
58+
}
59+
}
60+
}
61+
}
62+
}
63+
}
64+
},
65+
"components":{
66+
67+
}
68+
}

0 commit comments

Comments
 (0)