Skip to content

Commit de10059

Browse files
committed
Merge branch 'skylar-stark-patch-1'
2 parents 6ce3b5a + 1af222c commit de10059

File tree

4 files changed

+118
-7
lines changed

4 files changed

+118
-7
lines changed

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

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
import org.slf4j.Logger;
5757
import org.slf4j.LoggerFactory;
5858
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
59-
59+
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
6060
import org.springframework.beans.BeansException;
6161
import org.springframework.beans.factory.config.BeanDefinition;
6262
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
@@ -114,6 +114,11 @@ public class OpenAPIService implements ApplicationContextAware {
114114
*/
115115
private final Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers;
116116

117+
/**
118+
* The server base URL customisers.
119+
*/
120+
private final Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers;
121+
117122
/**
118123
* The Spring doc config properties.
119124
*/
@@ -182,7 +187,8 @@ public class OpenAPIService implements ApplicationContextAware {
182187
*/
183188
public OpenAPIService(Optional<OpenAPI> openAPI, SecurityService securityParser,
184189
SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils,
185-
Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers) {
190+
Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers,
191+
Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomisers) {
186192
if (openAPI.isPresent()) {
187193
this.openAPI = openAPI.get();
188194
if (this.openAPI.getComponents() == null)
@@ -196,6 +202,7 @@ public OpenAPIService(Optional<OpenAPI> openAPI, SecurityService securityParser,
196202
this.securityParser = securityParser;
197203
this.springDocConfigProperties = springDocConfigProperties;
198204
this.openApiBuilderCustomisers = openApiBuilderCustomisers;
205+
this.serverBaseUrlCustomizers = serverBaseUrlCustomisers;
199206
if (springDocConfigProperties.isUseFqn())
200207
TypeNameResolver.std.setUseFqn(true);
201208
}
@@ -434,7 +441,15 @@ public void buildTagsFromClass(Class<?> beanType, Set<io.swagger.v3.oas.models.t
434441
* @param serverBaseUrl the server base url
435442
*/
436443
public void setServerBaseUrl(String serverBaseUrl) {
437-
this.serverBaseUrl = serverBaseUrl;
444+
String customServerBaseUrl = serverBaseUrl;
445+
446+
if (serverBaseUrlCustomizers != null && serverBaseUrlCustomizers.isPresent()) {
447+
for (ServerBaseUrlCustomizer customiser : serverBaseUrlCustomizers.get()) {
448+
customServerBaseUrl = customiser.customize(customServerBaseUrl);
449+
}
450+
}
451+
452+
this.serverBaseUrl = customServerBaseUrl;
438453
}
439454

440455
/**
@@ -715,8 +730,17 @@ public SecurityService getSecurityParser() {
715730
return securityParser;
716731
}
717732

733+
/**
734+
* Gets server base URL
735+
*
736+
* @return the server base URL
737+
*/
738+
public String getServerBaseUrl() {
739+
return serverBaseUrl;
740+
}
741+
718742
@Override
719743
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
720744
this.context = applicationContext;
721745
}
722-
}
746+
}

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import org.springdoc.core.customizers.OpenApiCustomiser;
5454
import org.springdoc.core.customizers.OperationCustomizer;
5555
import org.springdoc.core.customizers.PropertyCustomizer;
56+
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
5657
import org.springdoc.core.providers.ActuatorProvider;
5758
import org.springdoc.core.providers.CloudFunctionProvider;
5859
import org.springdoc.core.providers.JavadocProvider;
@@ -226,8 +227,9 @@ PolymorphicModelConverter polymorphicModelConverter() {
226227
OpenAPIService openAPIBuilder(Optional<OpenAPI> openAPI,
227228
SecurityService securityParser,
228229
SpringDocConfigProperties springDocConfigProperties,PropertyResolverUtils propertyResolverUtils,
229-
Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers) {
230-
return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers);
230+
Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers,
231+
Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomisers) {
232+
return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers);
231233
}
232234

233235
/**
@@ -580,4 +582,4 @@ CloudFunctionProvider springCloudFunctionProvider(Optional<FunctionCatalog> func
580582
return new SpringCloudFunctionProvider(functionCatalog, genericResponseService, springDocConfigProperties);
581583
}
582584
}
583-
}
585+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.springdoc.core.customizers;
2+
3+
/**
4+
* The interface Server Base URL customiser.
5+
* @author skylar-stark
6+
*/
7+
@FunctionalInterface
8+
public interface ServerBaseUrlCustomizer {
9+
10+
/**
11+
* Customise.
12+
*
13+
* @param serverBaseUrl the serverBaseUrl.
14+
* @return the customised serverBaseUrl
15+
*/
16+
String customize(String serverBaseUrl);
17+
}

springdoc-openapi-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package org.springdoc.api;
2222

23+
import java.util.ArrayList;
2324
import java.util.HashMap;
2425
import java.util.List;
2526
import java.util.Locale;
@@ -49,6 +50,7 @@
4950
import org.springdoc.core.SpringDocProviders;
5051
import org.springdoc.core.customizers.OpenApiCustomiser;
5152
import org.springdoc.core.customizers.OperationCustomizer;
53+
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
5254
import org.springdoc.core.filters.OpenApiMethodFilter;
5355
import org.springdoc.core.fn.RouterOperation;
5456

@@ -111,6 +113,7 @@ public void setUp() {
111113
openAPI = new OpenAPI();
112114
openAPI.setPaths(new Paths().addPathItem(PATH, new PathItem()));
113115
ReflectionTestUtils.setField(openAPIService, "cachedOpenAPI", new HashMap<>());
116+
ReflectionTestUtils.setField(openAPIService, "serverBaseUrlCustomizers", Optional.empty());
114117

115118
when(openAPIService.getCalculatedOpenAPI()).thenReturn(openAPI);
116119
when(openAPIService.getContext()).thenReturn(context);
@@ -215,6 +218,71 @@ void preLoadingModeShouldNotOverwriteServers() throws InterruptedException {
215218
assertThat(after.getServers().get(0).getUrl(), is(customUrl));
216219
}
217220

221+
@Test
222+
void serverBaseUrlCustomisersTest() throws InterruptedException {
223+
when(openAPIService.updateServers(any())).thenCallRealMethod();
224+
when(openAPIService.getCachedOpenAPI(any())).thenCallRealMethod();
225+
doAnswer(new CallsRealMethods()).when(openAPIService).setServerBaseUrl(any());
226+
doAnswer(new CallsRealMethods()).when(openAPIService).setCachedOpenAPI(any(), any());
227+
228+
SpringDocConfigProperties properties = new SpringDocConfigProperties();
229+
properties.setPreLoadingEnabled(true);
230+
231+
resource = new EmptyPathsOpenApiResource(
232+
GROUP_NAME,
233+
openAPIBuilderObjectFactory,
234+
requestBuilder,
235+
responseBuilder,
236+
operationParser,
237+
Optional.empty(),
238+
Optional.empty(),
239+
Optional.empty(),
240+
properties,
241+
springDocProviders
242+
);
243+
244+
// wait for executor to be done
245+
Thread.sleep(1_000);
246+
247+
Locale locale = Locale.US;
248+
249+
// Test that setting generated URL works fine with no customizers present
250+
String generatedUrl = "https://generated-url.com/context-path";
251+
openAPIService.setServerBaseUrl(generatedUrl);
252+
openAPIService.updateServers(openAPI);
253+
OpenAPI after = resource.getOpenApi(locale);
254+
assertThat(after.getServers().get(0).getUrl(), is(generatedUrl));
255+
256+
// Test that adding a serverBaseUrlCustomizer has the desired effect
257+
ServerBaseUrlCustomizer serverBaseUrlCustomizer = serverBaseUrl -> serverBaseUrl.replace("/context-path", "");
258+
List<ServerBaseUrlCustomizer> serverBaseUrlCustomizerList = new ArrayList<>();
259+
serverBaseUrlCustomizerList.add(serverBaseUrlCustomizer);
260+
261+
ReflectionTestUtils.setField(openAPIService, "serverBaseUrlCustomizers", Optional.of(serverBaseUrlCustomizerList));
262+
openAPIService.setServerBaseUrl(generatedUrl);
263+
openAPIService.updateServers(openAPI);
264+
after = resource.getOpenApi(locale);
265+
assertThat(after.getServers().get(0).getUrl(), is("https://generated-url.com"));
266+
267+
// Test that serverBaseUrlCustomisers are performed in order
268+
generatedUrl = "https://generated-url.com/context-path/second-path";
269+
ServerBaseUrlCustomizer serverBaseUrlCustomiser2 = serverBaseUrl -> serverBaseUrl.replace("/context-path/second-path", "");
270+
serverBaseUrlCustomizerList.add(serverBaseUrlCustomiser2);
271+
272+
openAPIService.setServerBaseUrl(generatedUrl);
273+
openAPIService.updateServers(openAPI);
274+
after = resource.getOpenApi(locale);
275+
assertThat(after.getServers().get(0).getUrl(), is("https://generated-url.com/second-path"));
276+
277+
// Test that all serverBaseUrlCustomisers in the List are performed
278+
ServerBaseUrlCustomizer serverBaseUrlCustomiser3 = serverBaseUrl -> serverBaseUrl.replace("/second-path", "");
279+
serverBaseUrlCustomizerList.add(serverBaseUrlCustomiser3);
280+
281+
openAPIService.setServerBaseUrl(generatedUrl);
282+
openAPIService.updateServers(openAPI);
283+
after = resource.getOpenApi(locale);
284+
assertThat(after.getServers().get(0).getUrl(), is("https://generated-url.com"));
285+
}
218286

219287
private static class EmptyPathsOpenApiResource extends AbstractOpenApiResource {
220288

0 commit comments

Comments
 (0)