Skip to content

Add support for caching based on Locale #1356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 2, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ public static void addHiddenRestControllers(String... classes) {
*/
protected synchronized OpenAPI getOpenApi(Locale locale) {
OpenAPI openApi;
if (openAPIService.getCachedOpenAPI() == null || springDocConfigProperties.isCacheDisabled()) {
if (openAPIService.getCachedOpenAPI(locale) == null || springDocConfigProperties.isCacheDisabled()) {
Instant start = Instant.now();
openAPIService.build(locale);
Map<String, Object> mappingsMap = openAPIService.getMappingsMap().entrySet().stream()
Expand Down Expand Up @@ -335,15 +335,15 @@ protected synchronized OpenAPI getOpenApi(Locale locale) {
if (!CollectionUtils.isEmpty(openApi.getServers()) && !openApi.getServers().equals(serversCopy))
openAPIService.setServersPresent(true);

openAPIService.setCachedOpenAPI(openApi);
openAPIService.setCachedOpenAPI(openApi, locale);
openAPIService.resetCalculatedOpenAPI();

LOGGER.info("Init duration for springdoc-openapi is: {} ms",
Duration.between(start, Instant.now()).toMillis());
}
else {
LOGGER.debug("Fetching openApi document from cache");
openApi = openAPIService.updateServers(openAPIService.getCachedOpenAPI());
openApi = openAPIService.updateServers(openAPIService.getCachedOpenAPI(locale));
}
return openApi;
}
Expand Down Expand Up @@ -1109,8 +1109,8 @@ else if (existingOperation != null) {
/**
* Init open api builder.
*/
protected void initOpenAPIBuilder() {
if (openAPIService.getCachedOpenAPI() != null && springDocConfigProperties.isCacheDisabled()) {
protected void initOpenAPIBuilder(Locale locale) {
if (openAPIService.getCachedOpenAPI(locale) != null && springDocConfigProperties.isCacheDisabled()) {
openAPIService = openAPIBuilderObjectFactory.getObject();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@ public class OpenAPIService {
/**
* The Cached open api.
*/
private OpenAPI cachedOpenAPI;
/**
* The Mappings map.
*/
private final Map<String, OpenAPI> cachedOpenAPI = new HashMap<>();

/**
* The Calculated open api.
Expand Down Expand Up @@ -725,19 +728,28 @@ public Map<String, Object> getControllerAdviceMap() {
/**
* Gets cached open api.
*
* @param locale associated the the cache entry
* @return the cached open api
*/
public OpenAPI getCachedOpenAPI() {
return cachedOpenAPI;
public OpenAPI getCachedOpenAPI(Locale locale) {
Locale cachedLocale = (locale == null ? Locale.getDefault() : locale);
if (cachedOpenAPI != null && cachedOpenAPI.containsKey(cachedLocale.getLanguage())) {
return cachedOpenAPI.get(cachedLocale.getLanguage());
}
return null;
}

/**
* Sets cached open api.
*
* @param locale associated the the cache entry
* @param cachedOpenAPI the cached open api
*/
public void setCachedOpenAPI(OpenAPI cachedOpenAPI) {
this.cachedOpenAPI = cachedOpenAPI;
public void setCachedOpenAPI(OpenAPI cachedOpenAPI, Locale locale) {
Locale cachedLocale = (locale == null ? Locale.getDefault() : locale);
if (this.cachedOpenAPI != null) {
this.cachedOpenAPI.put(cachedLocale.getLanguage(), cachedOpenAPI);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,10 @@ void calculatePathFromRouterOperation() {
@Test
void preLoadingModeShouldNotOverwriteServers() throws InterruptedException {
when(openAPIService.updateServers(any())).thenCallRealMethod();
when(openAPIService.getCachedOpenAPI()).thenCallRealMethod();
when(openAPIService.getCachedOpenAPI(any())).thenCallRealMethod();
doAnswer(new CallsRealMethods()).when(openAPIService).setServersPresent(true);
doAnswer(new CallsRealMethods()).when(openAPIService).setServerBaseUrl(any());
doAnswer(new CallsRealMethods()).when(openAPIService).setCachedOpenAPI(any());
doAnswer(new CallsRealMethods()).when(openAPIService).setCachedOpenAPI(any(), any());

String customUrl = "https://custom.com";
String generatedUrl = "https://generated.com";
Expand All @@ -197,8 +197,8 @@ void preLoadingModeShouldNotOverwriteServers() throws InterruptedException {
// emulate generating base url
openAPIService.setServerBaseUrl(generatedUrl);
openAPIService.updateServers(openAPI);

OpenAPI after = resource.getOpenApi(Locale.getDefault());
Locale locale = Locale.US;
OpenAPI after = resource.getOpenApi(locale);

assertThat(after.getServers().get(0).getUrl(), is(customUrl));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ public Mono<String> openapiYaml(ServerHttpRequest serverHttpRequest, Locale loca
}

@Override
protected void calculateServerUrl(ServerHttpRequest serverHttpRequest, String apiDocsUrl) {
super.initOpenAPIBuilder();
protected void calculateServerUrl(ServerHttpRequest serverHttpRequest, String apiDocsUrl, Locale locale) {
super.initOpenAPIBuilder(locale);
URI uri = getActuatorURI(serverHttpRequest.getURI().getScheme(), serverHttpRequest.getURI().getHost());
openAPIService.setServerBaseUrl(uri.toString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public OpenApiResource(ObjectFactory<OpenAPIService> openAPIBuilderObjectFactory
*/
protected Mono<String> openapiJson(ServerHttpRequest serverHttpRequest, String apiDocsUrl, Locale locale)
throws JsonProcessingException {
calculateServerUrl(serverHttpRequest, apiDocsUrl);
calculateServerUrl(serverHttpRequest, apiDocsUrl, locale);
OpenAPI openAPI = this.getOpenApi(locale);
return Mono.just(writeJsonValue(openAPI));
}
Expand All @@ -138,7 +138,7 @@ protected Mono<String> openapiJson(ServerHttpRequest serverHttpRequest, String a
*/
protected Mono<String> openapiYaml(ServerHttpRequest serverHttpRequest, String apiDocsUrl, Locale locale)
throws JsonProcessingException {
calculateServerUrl(serverHttpRequest, apiDocsUrl);
calculateServerUrl(serverHttpRequest, apiDocsUrl, locale);
OpenAPI openAPI = this.getOpenApi(locale);
return Mono.just(writeYamlValue(openAPI));
}
Expand Down Expand Up @@ -232,8 +232,8 @@ protected void getWebFluxRouterFunctionPaths(Locale locale) {
* @param serverHttpRequest the server http request
* @param apiDocsUrl the api docs url
*/
protected void calculateServerUrl(ServerHttpRequest serverHttpRequest, String apiDocsUrl) {
initOpenAPIBuilder();
protected void calculateServerUrl(ServerHttpRequest serverHttpRequest, String apiDocsUrl, Locale locale) {
initOpenAPIBuilder(locale);
String serverUrl = getServerUrl(serverHttpRequest,apiDocsUrl);
openAPIService.setServerBaseUrl(serverUrl);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public OpenApiResource(ObjectFactory<OpenAPIService> openAPIBuilderObjectFactory
public String openapiJson(HttpServletRequest request,
String apiDocsUrl, Locale locale)
throws JsonProcessingException {
calculateServerUrl(request, apiDocsUrl);
calculateServerUrl(request, apiDocsUrl, locale);
OpenAPI openAPI = this.getOpenApi(locale);
return writeJsonValue(openAPI);
}
Expand All @@ -174,7 +174,7 @@ public String openapiJson(HttpServletRequest request,
public String openapiYaml(HttpServletRequest request,
String apiDocsUrl, Locale locale)
throws JsonProcessingException {
calculateServerUrl(request, apiDocsUrl);
calculateServerUrl(request, apiDocsUrl, locale);
OpenAPI openAPI = this.getOpenApi(locale);
return writeYamlValue(openAPI);
}
Expand Down Expand Up @@ -290,8 +290,8 @@ private Comparator<Map.Entry<RequestMappingInfo, HandlerMethod>> byReversedReque
* @param request the request
* @param apiDocsUrl the api docs url
*/
protected void calculateServerUrl(HttpServletRequest request, String apiDocsUrl) {
super.initOpenAPIBuilder();
protected void calculateServerUrl(HttpServletRequest request, String apiDocsUrl, Locale locale) {
super.initOpenAPIBuilder(locale);
String calculatedUrl = getServerUrl(request, apiDocsUrl);
openAPIService.setServerBaseUrl(calculatedUrl);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
*
* * Copyright 2019-2020 the original author or authors.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * https://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/

package test.org.springdoc.api.app171;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;

import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@Tag(name = "greeting", description = "test")
public class HelloLocaleController {

@GetMapping("/persons")
public void persons(@Valid @NotBlank String name) {
}

@GetMapping("/test")
public HttpEntity<String> demo2() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
*
* * Copyright 2019-2020 the original author or authors.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * https://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/

package test.org.springdoc.api.app171;

import static org.hamcrest.Matchers.is;
import static org.skyscreamer.jsonassert.JSONAssert.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.Locale;

import org.junit.jupiter.api.Test;
import org.springdoc.core.Constants;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpHeaders;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MvcResult;

import test.org.springdoc.api.AbstractSpringDocTest;

@TestPropertySource(properties = Constants.SPRINGDOC_CACHE_DISABLED + "=false")
public class SpringDocApp171Test extends AbstractSpringDocTest {

@SpringBootApplication
static class SpringDocTestApp {
}

@Test
@Override
public void testApp() throws Exception {
testApp(Locale.US);
testApp(Locale.FRANCE);
}

private void testApp(Locale locale) throws Exception {
className = getClass().getSimpleName();
String testNumber = className.replaceAll("[^0-9]", "");
MvcResult mockMvcResult =
mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL).locale(locale).header(HttpHeaders.ACCEPT_LANGUAGE, locale.toLanguageTag())).andExpect(status().isOk())
.andExpect(jsonPath("$.openapi", is("3.0.1"))).andReturn();
String result = mockMvcResult.getResponse().getContentAsString();
String expected = getContent("results/app" + testNumber + "-" + locale.getLanguage() + ".json");
assertEquals(expected, result, true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
greeting=Hello! Welcome to our website![FR]
lang.change=Change the language[FR]
lang.eng=English[FR]
lang.fr=French[FR]
mySample=toto[FR]
test=This is a test message[FR]
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"openapi": "3.0.1",
"info": {
"title": "OpenAPI definition",
"version": "v0"
},
"servers": [
{
"url": "http://localhost",
"description": "Generated server url"
}
],
"tags": [
{
"name": "Hello! Welcome to our website!",
"description": "This is a test message"
}
],
"paths": {
"/test": {
"get": {
"tags": [
"Hello! Welcome to our website!"
],
"operationId": "demo2",
"responses": {
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/persons": {
"get": {
"tags": [
"Hello! Welcome to our website!"
],
"operationId": "persons",
"parameters": [
{
"name": "name",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
}
},
"components": {}
}
Loading