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
Added documentation how to use micronaut-openapi with Spring applications
  • Loading branch information
altro3 committed Sep 20, 2024
1 parent 067fd50 commit 510dd37
Show file tree
Hide file tree
Showing 27 changed files with 621 additions and 6 deletions.
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ swagger-parser-v3 = "2.1.22"
javaparser = "3.26.2"
commons-codec = "1.17.1"
guava = "33.3.0-jre"
spring-boot = "3.3.3"

micronaut = "4.6.5"
micronaut-platform = "4.6.2"
Expand All @@ -36,6 +37,7 @@ micronaut-kotlin = "4.4.0"
micronaut-logging = "1.4.0"
micronaut-session = "4.4.0"
micronaut-grpc = "4.7.0"
micronaut-spring = "5.8.0"
micronaut-docs = "2.0.0"

[libraries]
Expand Down Expand Up @@ -68,6 +70,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 @@ -79,6 +82,7 @@ android-annotation = { module = "androidx.annotation:annotation", version.ref =
javaparser = { module = "com.github.javaparser:javaparser-symbol-solver-core", version.ref = "javaparser" }
commons-codec = { module = "commons-codec:commons-codec", version.ref = "commons-codec" }
guava = { module = "com.google.guava:guava", version.ref = "guava" }
spring-boot-dependencies = { module = "org.springframework.boot:spring-boot-dependencies", version.ref = "spring-boot" }

openapi-generator = { module = "org.openapitools:openapi-generator", version.ref = "openapi-generator" }
swagger-parser = { module = "io.swagger:swagger-parser", version.ref = "swagger-parser" }
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 @@ -2479,10 +2479,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
6 changes: 6 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pluginManagement {

plugins {
id 'io.micronaut.build.shared.settings' version '7.2.1'
id "dev.aga.gradle.version-catalog-generator" version "1.5.0"
}
enableFeaturePreview 'TYPESAFE_PROJECT_ACCESSORS'

Expand All @@ -24,6 +25,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 All @@ -35,6 +37,9 @@ dependencyResolutionManagement {
repositories {
mavenCentral()
}
versionCatalogs {
generator.generate("spring") { from(toml("spring-boot-dependencies")) }
}
}

micronautBuild {
Expand All @@ -52,4 +57,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.
23 changes: 23 additions & 0 deletions src/main/docs/guide/spring/springWithGradle.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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 "io.micronaut.spring:micronaut-spring-annotation:$micronautSpringVersion"
annotationProcessor "io.micronaut.spring:micronaut-spring-web-annotation:$micronautSpringVersion"
annotationProcessor "io.micronaut.spring:micronaut-spring-boot-annotation:$micronautSpringVersion"
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 @@ -30,6 +30,10 @@ endpoints:
endpointservers: Endpoints Servers
endpointssecurityrequirements: Endpoints Security Requirements
endpointspath: Endpoints Path
spring:
title: Micronaut OpenAPI with Spring
springWithGradle: Spring with Gradle
springWithMaven: Spring with Maven
micronautOpenApiAnnotations:
title: Micronaut OpenAPI annotations
openapidecorator: '@OpenAPIDecorator'
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.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
52 changes: 52 additions & 0 deletions test-suite-java-spring/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
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(spring.spring.springBootStarterWeb)
implementation(spring.spring.springBootStarterValidation)
implementation(spring.spring.springBootStarterDataRest)

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

testImplementation(spring.spring.springBootStarterTest)
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);
}
}
Loading

0 comments on commit 510dd37

Please sign in to comment.