Skip to content

Commit 60e458e

Browse files
committed
Initial support for spring-native:
- Added property springdoc.enable-native-image-support to enable support of native images. Add feature to display the swagger-ui by default in the root path using the property springdoc.swagger-ui.use-root-path
1 parent c065481 commit 60e458e

25 files changed

+763
-10
lines changed

pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
<jaxb-impl.version>2.1</jaxb-impl.version>
7676
<javax.jws-api.version>1.1</javax.jws-api.version>
7777
<jjwt.version>0.9.1</jjwt.version>
78+
<spring-native.version>0.9.2</spring-native.version>
7879
</properties>
7980

8081
<dependencyManagement>
@@ -145,6 +146,11 @@
145146
<version>${jjwt.version}</version>
146147
<scope>test</scope>
147148
</dependency>
149+
<dependency>
150+
<groupId>org.springframework.experimental</groupId>
151+
<artifactId>spring-native</artifactId>
152+
<version>${spring-native.version}</version>
153+
</dependency>
148154
</dependencies>
149155
</dependencyManagement>
150156
<dependencies>

springdoc-openapi-common/pom.xml

+11
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,19 @@
4646
<artifactId>spring-boot-starter-actuator</artifactId>
4747
<optional>true</optional>
4848
</dependency>
49+
<dependency>
50+
<groupId>org.springframework.experimental</groupId>
51+
<artifactId>spring-native</artifactId>
52+
<optional>true</optional>
53+
</dependency>
4954
</dependencies>
5055
<build>
56+
<resources>
57+
<resource>
58+
<directory>src/main/resources</directory>
59+
<filtering>true</filtering>
60+
</resource>
61+
</resources>
5162
<plugins>
5263
<plugin>
5364
<groupId>org.apache.maven.plugins</groupId>

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

+27-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ public final class Constants {
100100
*/
101101
public static final String SPRINGDOC_SWAGGER_UI_ENABLED = "springdoc.swagger-ui.enabled";
102102

103+
/**
104+
* The constant SPRINGDOC_ENABLE_NATIVE_IMAGE_SUPPORT.
105+
*/
106+
public static final String SPRINGDOC_ENABLE_NATIVE_IMAGE_SUPPORT = "springdoc.enable-native-image-support";
107+
103108
/**
104109
* The constant NULL.
105110
*/
@@ -150,15 +155,30 @@ public final class Constants {
150155
*/
151156
public static final String CLASSPATH_RESOURCE_LOCATION = ResourceUtils.CLASSPATH_URL_PREFIX + "/META-INF/resources";
152157

158+
/**
159+
* The constant SPRINGDOC_CONFIG_FILE.
160+
*/
161+
public static final String SPRINGDOC_CONFIG_FILE = ResourceUtils.CLASSPATH_URL_PREFIX + "springdoc.swagger-ui.config";
162+
163+
/**
164+
* The constant SWAGGER_UI_VERSION.
165+
*/
166+
public static final String SWAGGER_UI_VERSION= "${springdoc.swagger-ui.version}";
167+
153168
/**
154169
* The constant SWAGGER_UI_PREFIX.
155170
*/
156171
public static final String SWAGGER_UI_PREFIX = "/swagger-ui";
157172

173+
/**
174+
* The constant INDEX_PAGE.
175+
*/
176+
public static final String INDEX_PAGE = "/index.html";
177+
158178
/**
159179
* The constant SWAGGER_UI_URL.
160180
*/
161-
public static final String SWAGGER_UI_URL = SWAGGER_UI_PREFIX + "/index.html";
181+
public static final String SWAGGER_UI_URL = SWAGGER_UI_PREFIX + INDEX_PAGE;
162182

163183
/**
164184
* The constant SWAGGER_UI_OAUTH_REDIRECT_URL.
@@ -310,6 +330,11 @@ public final class Constants {
310330
*/
311331
public static final String SPRINGDOC_USE_MANAGEMENT_PORT = "springdoc.use-management-port";
312332

333+
/**
334+
* The constant SPRINGDOC_USE_ROOT_PATH.
335+
*/
336+
public static final String SPRINGDOC_USE_ROOT_PATH ="springdoc.swagger-ui.use-root-path";
337+
313338
/**
314339
* The constant DEFAULT_SWAGGER_UI_ACTUATOR_PATH.
315340
*/
@@ -334,6 +359,7 @@ public final class Constants {
334359
* The constant LINKS_SCHEMA_CUSTOMISER.
335360
*/
336361
public static final String LINKS_SCHEMA_CUSTOMISER = "linksSchemaCustomiser";
362+
337363
/**
338364
* Instantiates a new Constants.
339365
*/

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

+25
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,29 @@ public class SpringDocConfigProperties {
162162
*/
163163
private boolean useManagementPort;
164164

165+
/**
166+
* The Enable native support.
167+
*/
168+
protected boolean enableNativeImageSupport;
169+
170+
/**
171+
* Is enable native image support boolean.
172+
*
173+
* @return the boolean
174+
*/
175+
public boolean isEnableNativeImageSupport() {
176+
return enableNativeImageSupport;
177+
}
178+
179+
/**
180+
* Sets enable native image support.
181+
*
182+
* @param enableNativeImageSupport the enable native image support
183+
*/
184+
public void setEnableNativeImageSupport(boolean enableNativeImageSupport) {
185+
this.enableNativeImageSupport = enableNativeImageSupport;
186+
}
187+
165188
/**
166189
* Is use management port boolean.
167190
*
@@ -614,6 +637,7 @@ public boolean isPreLoadingEnabled() {
614637

615638
/**
616639
* The type Model converters.
640+
* @author bnasslashen
617641
*/
618642
public static class ModelConverters {
619643

@@ -642,6 +666,7 @@ public void setDeprecatingConverter(DeprecatingConverter deprecatingConverter) {
642666

643667
/**
644668
* The type Deprecating converter.
669+
* @author bnasslashen
645670
*/
646671
public static class DeprecatingConverter {
647672

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package org.springdoc.core;
2+
3+
import io.swagger.v3.core.converter.ModelConverter;
4+
import io.swagger.v3.core.converter.ModelConverters;
5+
import io.swagger.v3.core.filter.SpecFilter;
6+
import io.swagger.v3.core.jackson.ApiResponsesSerializer;
7+
import io.swagger.v3.core.jackson.PathsSerializer;
8+
import io.swagger.v3.core.jackson.mixin.ComponentsMixin;
9+
import io.swagger.v3.core.jackson.mixin.ExtensionsMixin;
10+
import io.swagger.v3.core.jackson.mixin.OpenAPIMixin;
11+
import io.swagger.v3.core.jackson.mixin.OperationMixin;
12+
import io.swagger.v3.core.jackson.mixin.SchemaMixin;
13+
import io.swagger.v3.oas.annotations.ExternalDocumentation;
14+
import io.swagger.v3.oas.annotations.Hidden;
15+
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
16+
import io.swagger.v3.oas.annotations.Operation;
17+
import io.swagger.v3.oas.annotations.Parameter;
18+
import io.swagger.v3.oas.annotations.callbacks.Callbacks;
19+
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
20+
import io.swagger.v3.oas.annotations.extensions.Extension;
21+
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
22+
import io.swagger.v3.oas.annotations.headers.Header;
23+
import io.swagger.v3.oas.annotations.info.Info;
24+
import io.swagger.v3.oas.annotations.links.Link;
25+
import io.swagger.v3.oas.annotations.links.LinkParameter;
26+
import io.swagger.v3.oas.annotations.media.ArraySchema;
27+
import io.swagger.v3.oas.annotations.media.Content;
28+
import io.swagger.v3.oas.annotations.media.DiscriminatorMapping;
29+
import io.swagger.v3.oas.annotations.media.Encoding;
30+
import io.swagger.v3.oas.annotations.media.ExampleObject;
31+
import io.swagger.v3.oas.annotations.media.Schema;
32+
import io.swagger.v3.oas.annotations.parameters.RequestBody;
33+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
34+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
35+
import io.swagger.v3.oas.annotations.security.OAuthFlow;
36+
import io.swagger.v3.oas.annotations.security.OAuthFlows;
37+
import io.swagger.v3.oas.annotations.security.OAuthScope;
38+
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
39+
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
40+
import io.swagger.v3.oas.annotations.security.SecurityScheme;
41+
import io.swagger.v3.oas.annotations.security.SecuritySchemes;
42+
import io.swagger.v3.oas.annotations.servers.Server;
43+
import io.swagger.v3.oas.annotations.servers.ServerVariable;
44+
import io.swagger.v3.oas.annotations.tags.Tag;
45+
import io.swagger.v3.oas.models.Components;
46+
import io.swagger.v3.oas.models.OpenAPI;
47+
import io.swagger.v3.oas.models.PathItem;
48+
import io.swagger.v3.oas.models.Paths;
49+
import io.swagger.v3.oas.models.media.BooleanSchema;
50+
import io.swagger.v3.oas.models.media.DateTimeSchema;
51+
import io.swagger.v3.oas.models.media.Discriminator;
52+
import io.swagger.v3.oas.models.media.FileSchema;
53+
import io.swagger.v3.oas.models.media.IntegerSchema;
54+
import io.swagger.v3.oas.models.media.MapSchema;
55+
import io.swagger.v3.oas.models.media.MediaType;
56+
import io.swagger.v3.oas.models.media.ObjectSchema;
57+
import io.swagger.v3.oas.models.media.StringSchema;
58+
import io.swagger.v3.oas.models.media.UUIDSchema;
59+
import io.swagger.v3.oas.models.media.XML;
60+
import io.swagger.v3.oas.models.security.Scopes;
61+
import io.swagger.v3.oas.models.servers.ServerVariables;
62+
63+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
64+
import org.springframework.context.annotation.Configuration;
65+
import org.springframework.context.annotation.PropertySource;
66+
import org.springframework.nativex.hint.AccessBits;
67+
import org.springframework.nativex.hint.ProxyHint;
68+
import org.springframework.nativex.hint.ResourceHint;
69+
import org.springframework.nativex.hint.TypeHint;
70+
71+
import static org.springdoc.core.Constants.SPRINGDOC_ENABLE_NATIVE_IMAGE_SUPPORT;
72+
73+
@ProxyHint(typeNames = "javax.servlet.http.HttpServletRequest")
74+
75+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.RestController", "org.springframework.core.annotation.SynthesizedAnnotation" })
76+
@ProxyHint(typeNames = { "org.springframework.stereotype.Controller", "org.springframework.core.annotation.SynthesizedAnnotation" })
77+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.SessionAttribute", "org.springframework.core.annotation.SynthesizedAnnotation" })
78+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.RestControllerAdvice", "org.springframework.core.annotation.SynthesizedAnnotation" })
79+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.ResponseStatus", "org.springframework.core.annotation.SynthesizedAnnotation" })
80+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.ResponseBody", "org.springframework.core.annotation.SynthesizedAnnotation" })
81+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.RequestPart", "org.springframework.core.annotation.SynthesizedAnnotation" })
82+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.RequestPart", "org.springframework.core.annotation.SynthesizedAnnotation" })
83+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.RequestMapping", "org.springframework.core.annotation.SynthesizedAnnotation" })
84+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.GetMapping", "org.springframework.core.annotation.SynthesizedAnnotation" })
85+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.PostMapping", "org.springframework.core.annotation.SynthesizedAnnotation" })
86+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.PutMapping", "org.springframework.core.annotation.SynthesizedAnnotation" })
87+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.PatchMapping", "org.springframework.core.annotation.SynthesizedAnnotation" })
88+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.DeleteMapping", "org.springframework.core.annotation.SynthesizedAnnotation" })
89+
@ProxyHint(typeNames = { "org.springframework.web.bind.annotation.ControllerAdvice", "org.springframework.core.annotation.SynthesizedAnnotation" })
90+
@ProxyHint(typeNames = {"org.springframework.web.bind.annotation.RequestParam", "org.springframework.core.annotation.SynthesizedAnnotation"})
91+
@ProxyHint(typeNames = {"org.springframework.web.bind.annotation.RequestHeader", "org.springframework.core.annotation.SynthesizedAnnotation"})
92+
@ProxyHint(typeNames = {"org.springframework.web.bind.annotation.RequestBody", "org.springframework.core.annotation.SynthesizedAnnotation"})
93+
@ProxyHint(typeNames = {"org.springframework.web.bind.annotation.PathVariable", "org.springframework.core.annotation.SynthesizedAnnotation"})
94+
@ProxyHint(typeNames = {"org.springframework.web.bind.annotation.ModelAttribute", "org.springframework.core.annotation.SynthesizedAnnotation"})
95+
@ProxyHint(typeNames = {"org.springframework.stereotype.Controller", "org.springframework.core.annotation.SynthesizedAnnotation"})
96+
@ProxyHint(typeNames = {"org.springframework.web.bind.annotation.ControllerAdvice", "org.springframework.core.annotation.SynthesizedAnnotation"})
97+
98+
@TypeHint(typeNames = { "org.springdoc.core.CacheOrGroupedOpenApiCondition$OnCacheDisabled", "io.swagger.v3.oas.models.parameters.Parameter$StyleEnum",
99+
"io.swagger.v3.oas.models.security.SecurityScheme$In" , "io.swagger.v3.oas.models.security.SecurityScheme$Type",
100+
"org.springdoc.core.CacheOrGroupedOpenApiCondition$OnMultipleOpenApiSupportCondition" }, access = AccessBits.ALL)
101+
102+
@TypeHint(types = { Constants.class, ModelConverter.class , ModelConverters.class})
103+
@TypeHint(types = { SecurityRequirements.class, SecurityRequirement.class, ApiResponses.class, Callbacks.class, PropertySource.class, ExternalDocumentation.class, Hidden.class,
104+
Operation.class, Parameter.class, Callbacks.class, Extension.class, ExtensionProperty.class, Header.class, Link.class, LinkParameter.class,
105+
ArraySchema.class, Content.class, DiscriminatorMapping.class, Encoding.class, ExampleObject.class, Schema.class, RequestBody.class, ApiResponse.class,
106+
Info.class, Server.class, ServerVariable.class, OpenAPIDefinition.class, Tag.class, SecuritySchemes.class, SecurityScheme.class, SecuritySchemeType.class,
107+
OAuthFlow.class, OAuthFlows.class, OAuthScope.class })
108+
109+
@TypeHint(types = {
110+
SpecFilter.class,
111+
MediaType.class,
112+
ApiResponsesSerializer.class,
113+
PathsSerializer.class,
114+
ComponentsMixin.class,
115+
ExtensionsMixin.class,
116+
OpenAPIMixin.class,
117+
OperationMixin.class,
118+
SchemaMixin.class,
119+
Paths.class,
120+
XML.class,
121+
UUIDSchema.class,
122+
PathItem.class,
123+
ServerVariables.class,
124+
OpenAPI.class,
125+
Components.class,
126+
StringSchema.class,
127+
DateTimeSchema.class,
128+
Discriminator.class,
129+
BooleanSchema.class,
130+
FileSchema.class,
131+
IntegerSchema.class,
132+
MapSchema.class,
133+
ObjectSchema.class,
134+
Scopes.class,
135+
io.swagger.v3.oas.models.security.OAuthFlow.class, io.swagger.v3.oas.models.security.OAuthFlows.class,
136+
io.swagger.v3.oas.models.security.SecurityScheme.class,
137+
io.swagger.v3.oas.models.tags.Tag.class,
138+
io.swagger.v3.oas.models.servers.ServerVariable.class,
139+
io.swagger.v3.oas.models.servers.Server.class,
140+
io.swagger.v3.oas.models.security.SecurityRequirement.class,
141+
io.swagger.v3.oas.models.info.Info.class,
142+
io.swagger.v3.oas.models.parameters.RequestBody.class,
143+
io.swagger.v3.oas.models.media.Schema.class,
144+
io.swagger.v3.oas.models.media.Content.class,
145+
io.swagger.v3.oas.models.media.ArraySchema.class,
146+
io.swagger.v3.oas.models.responses.ApiResponse.class,
147+
io.swagger.v3.oas.models.responses.ApiResponses.class,
148+
io.swagger.v3.oas.models.ExternalDocumentation.class,
149+
io.swagger.v3.oas.models.links.LinkParameter.class,
150+
io.swagger.v3.oas.models.links.Link.class,
151+
io.swagger.v3.oas.models.parameters.Parameter.class,
152+
io.swagger.v3.oas.models.Operation.class,
153+
})
154+
155+
@ResourceHint(patterns = "springdoc.swagger-ui.config")
156+
@Configuration(proxyBeanMethods = false)
157+
@ConditionalOnProperty(name = SPRINGDOC_ENABLE_NATIVE_IMAGE_SUPPORT, havingValue = "true")
158+
public class SpringDocHints {}

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

+29
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,18 @@
3131

3232
import org.apache.commons.lang3.StringUtils;
3333

34+
import org.springframework.beans.factory.annotation.Value;
3435
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3536
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3637
import org.springframework.context.annotation.Configuration;
3738
import org.springframework.context.annotation.Lazy;
39+
import org.springframework.context.annotation.PropertySource;
3840
import org.springframework.util.CollectionUtils;
3941

42+
import static org.springdoc.core.Constants.SPRINGDOC_CONFIG_FILE;
4043
import static org.springdoc.core.Constants.SPRINGDOC_SWAGGER_UI_ENABLED;
4144
import static org.springdoc.core.Constants.SWAGGER_UI_OAUTH_REDIRECT_URL;
45+
import static org.springdoc.core.Constants.SWAGGER_UI_VERSION;
4246
import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;
4347

4448
/**
@@ -49,6 +53,7 @@
4953
@Configuration(proxyBeanMethods = false)
5054
@ConditionalOnProperty(name = SPRINGDOC_SWAGGER_UI_ENABLED, matchIfMissing = true)
5155
@ConditionalOnBean(SpringDocConfiguration.class)
56+
@PropertySource(SPRINGDOC_CONFIG_FILE)
5257
public class SwaggerUiConfigParameters extends AbstractSwaggerUiConfigProperties {
5358

5459
/**
@@ -86,6 +91,12 @@ public class SwaggerUiConfigParameters extends AbstractSwaggerUiConfigProperties
8691
*/
8792
private final SwaggerUiConfigProperties swaggerUiConfig;
8893

94+
/**
95+
* The Swagger ui version.
96+
*/
97+
@Value(SWAGGER_UI_VERSION)
98+
private String swaggerUiVersion;
99+
89100
/**
90101
* Instantiates a new Swagger ui config parameters.
91102
*
@@ -121,6 +132,24 @@ public SwaggerUiConfigParameters(SwaggerUiConfigProperties swaggerUiConfig) {
121132
this.persistAuthorization = swaggerUiConfig.getPersistAuthorization();
122133
}
123134

135+
/**
136+
* Gets swagger ui version.
137+
*
138+
* @return the swagger ui version
139+
*/
140+
public String getSwaggerUiVersion() {
141+
return swaggerUiVersion;
142+
}
143+
144+
/**
145+
* Sets swagger ui version.
146+
*
147+
* @param swaggerUiVersion the swagger ui version
148+
*/
149+
public void setSwaggerUiVersion(String swaggerUiVersion) {
150+
this.swaggerUiVersion = swaggerUiVersion;
151+
}
152+
124153
/**
125154
* Add group.
126155
*

0 commit comments

Comments
 (0)