Skip to content

Commit

Permalink
Added test suite for micronaut-openapi with spring-boot application. (#…
Browse files Browse the repository at this point in the history
…1770)

* Added test suite for micronaut-openapi with spring-boot application.
Added documentation how to use micronaut-openapi with Spring applications

* don’t define spring-boot version

---------

Co-authored-by: Sergio del Amo <[email protected]>
  • Loading branch information
altro3 and sdelamo authored Oct 3, 2024
1 parent 47b9836 commit 14ca0fa
Show file tree
Hide file tree
Showing 26 changed files with 609 additions and 7 deletions.
7 changes: 6 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ micronaut-kotlin = "4.4.0"
micronaut-logging = "1.4.0"
micronaut-session = "4.4.0"
micronaut-grpc = "4.7.1"
micronaut-spring = "5.8.0"
micronaut-docs = "2.0.0"

[libraries]
Expand Down Expand Up @@ -73,6 +74,7 @@ micronaut-data = { module = "io.micronaut.data:micronaut-data-bom", version.ref
micronaut-test = { module = "io.micronaut.test:micronaut-test-bom", version.ref = "micronaut-test" }
micronaut-kotlin = { module = "io.micronaut.kotlin:micronaut-kotlin-bom", version.ref = "micronaut-kotlin" }
micronaut-grpc = { module = "io.micronaut.grpc:micronaut-grpc-bom", version.ref = "micronaut-grpc" }
micronaut-spring = { module = "io.micronaut.spring:micronaut-spring-bom", version.ref = "micronaut-spring" }
micronaut-platform = { module = "io.micronaut.platform:micronaut-platform", version.ref = "micronaut-platform"}
micronaut-gradle-plugin = { module = "io.micronaut.gradle:micronaut-minimal-plugin", version.ref = "micronaut-gradle-plugin"}

Expand All @@ -88,7 +90,10 @@ commons-lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "co
commons-text = { module = "org.apache.commons:commons-text", version.ref = "commons-text" }
guava = { module = "com.google.guava:guava", version.ref = "guava" }
commonmark = { module = "org.commonmark:commonmark", version.ref = "commonmark" }

spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web" }
spring-boot-starter-validation = { module = "org.springframework.boot:spring-boot-starter-validation" }
spring-boot-starter-data-rest = { module = "org.springframework.boot:spring-boot-starter-data-rest" }
spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test" }
openapi-generator = { module = "org.openapitools:openapi-generator", version.ref = "openapi-generator" }
swagger-parser = { module = "io.swagger:swagger-parser", version.ref = "swagger-parser" }
swagger-parser-v3 = { module = "io.swagger.parser.v3:swagger-parser-v3", version.ref = "swagger-parser-v3" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Header;
import io.micronaut.http.annotation.RequestAttribute;
import io.micronaut.http.multipart.FileUpload;
import io.micronaut.inject.annotation.AnnotationMetadataHierarchy;
import io.micronaut.inject.ast.ClassElement;
Expand Down Expand Up @@ -246,8 +247,10 @@ public static boolean isIgnoredParameter(TypedElement parameter) {
|| parameter.isAnnotationPresent(Hidden.class)
|| parameter.isAnnotationPresent(JsonIgnore.class)
|| parameter.isAnnotationPresent(Header.class) && parameter.getType().isAssignable(Map.class)
|| parameter.isAnnotationPresent(RequestAttribute.class)
|| parameter.booleanValue(Parameter.class, PROP_HIDDEN).orElse(false)
|| parameter.hasAnnotation("io.micronaut.session.annotation.SessionValue")
|| parameter.hasAnnotation("org.springframework.web.bind.annotation.RequestAttribute")
|| parameter.hasAnnotation("org.springframework.web.bind.annotation.SessionAttribute")
|| parameter.hasAnnotation("org.springframework.web.bind.annotation.SessionAttributes")
|| parameter.hasAnnotation("jakarta.ws.rs.core.Context")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2481,10 +2481,10 @@ private static void processPropertyElements(OpenAPI openAPI, VisitorContext cont

if (publicField instanceof MemberElement memberEl && (memberEl.getDeclaringType().getType().getName().equals(type.getName()) || isGetterOverridden)) {

ClassElement fieldType = publicField.getGenericType();
if (withJsonView && !allowedByJsonView(publicField, classLvlJsonViewClasses, jsonViewClass, context)) {
continue;
}
ClassElement fieldType = publicField.getGenericType();

Schema<?> propertySchema = resolveSchema(openAPI, publicField, fieldType, context, mediaTypes, jsonViewClass, fieldJavadoc, classJavadoc);

Expand Down
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ include 'docs-examples:example-java'
include 'docs-examples:example-kotlin'
include 'test-suite-java-client-generator'
include 'test-suite-java-jaxrs'
include 'test-suite-java-spring'
include 'test-suite-java-server-generator'
include 'test-suite-kotlin-kapt-client-generator'
include 'test-suite-kotlin-kapt-server-generator'
Expand Down Expand Up @@ -52,4 +53,5 @@ micronautBuild {
importMicronautCatalog("micronaut-session")
importMicronautCatalog("micronaut-jaxrs")
importMicronautCatalog("micronaut-grpc")
importMicronautCatalog("micronaut-spring")
}
1 change: 1 addition & 0 deletions src/main/docs/guide/spring.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You can use `micronaut-openapi` to build openapi specification for `Spring` / `Spring Boot` applications. In this case, you do not need to change anything in the code. You can continue to use spring, and use micronaut as a replacement for such libraries as `springdoc-openapi`, `springfox`, `swagger` etc.
24 changes: 24 additions & 0 deletions src/main/docs/guide/spring/springWithGradle.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
To use micronaut-openapi with spring in gradle add this code to you `build.gradle`:

.build.gradle
[source,groovy]
----
dependencies {
// add to annotationProcessor and compileOnly blocks next libraries:
annotationProcessor("io.micronaut:micronaut-inject-java:$micronautCoreVersion")
annotationProcessor(platfom("io.micronaut.spring:micronaut-spring-bom:$micronautSpringVersion"))
annotationProcessor("io.micronaut.spring:micronaut-spring-annotation")
annotationProcessor("io.micronaut.spring:micronaut-spring-web-annotation")
annotationProcessor("io.micronaut.spring:micronaut-spring-boot-annotation")
annotationProcessor("io.micronaut.openapi:micronaut-openapi:$micronautOpenapiVersion")
compileOnly("io.micronaut:micronaut-inject-java:$micronautCoreVersion")
compileOnly("io.micronaut.openapi:micronaut-openapi-annotations:$micronautOpenapiVersion")
compileOnly("io.micronaut.serde:micronaut-serde-api:$micronautSerdeVersion")
}
----

For kotlin just change block `annotationProcessor` to `kapt` or `ksp`.
131 changes: 131 additions & 0 deletions src/main/docs/guide/spring/springWithMaven.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
To use micronaut-openapi with spring in maven add this code to your `pom.xml`

.pom.xml
[source,xml]
----
<dependencies>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject-java</artifactId>
<version>${micronaut.core.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.micronaut.openapi</groupId>
<artifactId>micronaut-openapi-annotations</artifactId>
<version>${micronaut.openapi.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.micronaut.serde</groupId>
<artifactId>micronaut-serde-api</artifactId>
<version>${micronaut.serde.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths combine.children="append">
<path>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject-java</artifactId>
<version>${micronaut.core.version}</version>
</path>
<path>
<groupId>io.micronaut.spring</groupId>
<artifactId>micronaut-spring-annotation</artifactId>
<version>${micronaut.spring.version}</version>
</path>
<path>
<groupId>io.micronaut.spring</groupId>
<artifactId>micronaut-spring-web-annotation</artifactId>
<version>${micronaut.spring.version}</version>
</path>
<path>
<groupId>io.micronaut.spring</groupId>
<artifactId>micronaut-spring-boot-annotation</artifactId>
<version>${micronaut.spring.version}</version>
</path>
<path>
<groupId>io.micronaut.openapi</groupId>
<artifactId>micronaut-openapi</artifactId>
<version>${micronaut.openapi.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
----

For kotlin
.pom.xml
[source,xml]
----
<dependencies>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject-java</artifactId>
<version>${micronaut.core.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.micronaut.openapi</groupId>
<artifactId>micronaut-openapi-annotations</artifactId>
<version>${micronaut.openapi.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.micronaut.serde</groupId>
<artifactId>micronaut-serde-api</artifactId>
<version>${micronaut.serde.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>

<executions>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
</sourceDirs>
<annotationProcessorPaths combine.self="override">
<annotationProcessorPath>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject-java</artifactId>
<version>${micronaut.core.version}</version>
</annotationProcessorPath>
<annotationProcessorPath>
<groupId>io.micronaut.spring</groupId>
<artifactId>micronaut-spring-annotation</artifactId>
<version>${micronaut.spring.version}</version>
</annotationProcessorPath>
<annotationProcessorPath>
<groupId>io.micronaut.spring</groupId>
<artifactId>micronaut-spring-web-annotation</artifactId>
<version>${micronaut.spring.version}</version>
</annotationProcessorPath>
<annotationProcessorPath>
<groupId>io.micronaut.spring</groupId>
<artifactId>micronaut-spring-boot-annotation</artifactId>
<version>${micronaut.spring.version}</version>
</annotationProcessorPath>
<annotationProcessorPath>
<groupId>io.micronaut.openapi</groupId>
<artifactId>micronaut-openapi</artifactId>
<version>${micronaut.openapi.version}</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
</executions>
----
4 changes: 4 additions & 0 deletions src/main/docs/guide/spring/springWithOpenApiView.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To use micronaut openapi views (Swagger UI, OpenAPi Explorer, Redoc, RapiDoc) you need to add static resources to Spring configuration like this:

.Example Swagger UI resources routing config
snippet::io.micronaut.openapi.spring.WebConfig[tags="imports,clazz", project-base="test-suite-java-spring"]
4 changes: 4 additions & 0 deletions src/main/docs/guide/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ serverContext:
compileResolution: Compile Time Resolution
serverFilter: HttpServerFilter
urlParameter: URL Parameter
spring:
title: Micronaut OpenAPI with Spring
springWithGradle: Spring with Gradle
springWithMaven: Spring with Maven
openApiGuides: Guides
repository: Repository
breaks: Breaking Changes
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.micronaut.open.jaxrs;
package io.micronaut.openapi.jaxrs;

import io.micronaut.runtime.Micronaut;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.micronaut.open.jaxrs;
package io.micronaut.openapi.jaxrs;

import io.micronaut.http.client.BlockingHttpClient;
import io.micronaut.http.client.HttpClient;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.micronaut.open.jaxrs;
package io.micronaut.openapi.jaxrs;

import io.micronaut.core.io.ResourceLoader;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.micronaut.open.jaxrs;
package io.micronaut.openapi.jaxrs;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.micronaut.open.jaxrs;
package io.micronaut.openapi.jaxrs;

import io.micronaut.http.client.BlockingHttpClient;
import io.micronaut.http.client.HttpClient;
Expand Down
54 changes: 54 additions & 0 deletions test-suite-java-spring/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
plugins {
id("io.micronaut.build.internal.openapi-test-java")
}

sourceSets {
test {
java {
srcDirs += "$buildDir/classes/java"
}
}
}

dependencies {

annotationProcessor(mnSpring.micronaut.spring.annotation)
annotationProcessor(mnSpring.micronaut.spring.web.annotation)
annotationProcessor(mnSpring.micronaut.spring.boot.annotation)
annotationProcessor(mn.micronaut.inject.java)
annotationProcessor(projects.micronautOpenapi)

compileOnly(projects.micronautOpenapiAnnotations)
compileOnly(mn.jackson.annotations)
compileOnly(mn.micronaut.inject.java)
compileOnly(mnSerde.micronaut.serde.api)

implementation(platform("org.springframework.boot:spring-boot-dependencies:${mnSpring.versions.spring.boot.get()}"))
implementation(libs.spring.boot.starter.web)
implementation(libs.spring.boot.starter.validation)
implementation(libs.spring.boot.starter.data.rest)

testCompileOnly(projects.micronautOpenapiAnnotations)
testCompileOnly(mn.jackson.annotations)
testCompileOnly(mn.micronaut.inject.java)
testCompileOnly(mnSerde.micronaut.serde.api)

testImplementation("org.springframework.boot:spring-boot-dependencies:${mnSpring.versions.spring.boot.get()}" )
testImplementation(libs.spring.boot.starter.test)
testImplementation(mnTest.junit.jupiter.api)
testImplementation(projects.micronautOpenapiCommon)

testRuntimeOnly(mnLogging.logback.classic)
testRuntimeOnly(mnTest.junit.jupiter.engine)
}

tasks.withType(JavaCompile).configureEach {
options.encoding = "UTF-8"
options.incremental = true
options.fork = true
options.compilerArgs = [
'-parameters',
'-Xlint:unchecked',
'-Xlint:deprecation'
]
}
1 change: 1 addition & 0 deletions test-suite-java-spring/openapi.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
micronaut.openapi.views.spec=swagger-ui.enabled=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.micronaut.openapi.spring;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@OpenAPIDefinition(
info = @Info(
title = "demo",
version = "0.0"
)
)
public class Application {

public static void main(String[] args) {
var application = new SpringApplication(Application.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.micronaut.openapi.spring;
// tag::imports[]
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

// end::imports[]
// tag::clazz[]
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/swagger/views/swagger-ui/");
registry.addResourceHandler("/swagger/**")
.addResourceLocations("classpath:/META-INF/swagger/");
}
}
//end::clazz[]
Loading

0 comments on commit 14ca0fa

Please sign in to comment.