Skip to content
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

feat: new module for generating OpenAPI contract at build-time for SpringMVC applications #10803

Merged
merged 1 commit into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package tech.jhipster.lite.generator.server.springboot.apidocumentation.openapicontract.application;

import org.springframework.stereotype.Service;
import tech.jhipster.lite.generator.server.springboot.apidocumentation.openapicontract.domain.OpenApiContractModuleFactory;
import tech.jhipster.lite.module.domain.JHipsterModule;
import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties;

@Service
public class OpenApiContractApplicationService {

private final OpenApiContractModuleFactory factory;

public OpenApiContractApplicationService() {
factory = new OpenApiContractModuleFactory();
}

public JHipsterModule buildModule(JHipsterModuleProperties properties) {
return factory.buildModule(properties);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package tech.jhipster.lite.generator.server.springboot.apidocumentation.openapicontract.domain;

import static tech.jhipster.lite.module.domain.JHipsterModule.*;

import tech.jhipster.lite.module.domain.JHipsterModule;
import tech.jhipster.lite.module.domain.mavenplugin.MavenPlugin;
import tech.jhipster.lite.module.domain.mavenplugin.MavenPlugin.MavenPluginOptionalBuilder;
import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties;
import tech.jhipster.lite.shared.error.domain.Assert;

public class OpenApiContractModuleFactory {

public JHipsterModule buildModule(JHipsterModuleProperties properties) {
Assert.notNull("properties", properties);

//@formatter:off
return moduleBuilder(properties)
.mavenPlugins()
.pluginManagement(openApiPluginManagement(properties))
.plugin(openApiPlugin().build())
.and()
.build();
//@formatter:on
}

private MavenPluginOptionalBuilder openApiPlugin() {
return mavenPlugin().groupId("io.github.kbuntrock").artifactId("openapi-maven-plugin");
}

private MavenPlugin openApiPluginManagement(JHipsterModuleProperties properties) {
return openApiPlugin()
.versionSlug("openapi-maven-plugin")
.addExecution(pluginExecution().goals("documentation").id("generate-openapi-contract"))
.configuration(
"""
<apiConfiguration>
<library>SPRING_MVC</library>
</apiConfiguration>
<apis>
<api>
<filename>openapi-contract.yml</filename>
<locations>
<location>%s</location>
</locations>
<tag>
<substitutions>
<sub>
<regex>Resource$</regex>
<substitute />
</sub>
</substitutions>
</tag>
</api>
</apis>\
""".formatted(properties.basePackage())
)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package tech.jhipster.lite.generator.server.springboot.apidocumentation.openapicontract.infrastructure.primary;

import static tech.jhipster.lite.generator.slug.domain.JHLiteFeatureSlug.SPRING_MVC_SERVER;
import static tech.jhipster.lite.generator.slug.domain.JHLiteModuleSlug.*;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tech.jhipster.lite.generator.server.springboot.apidocumentation.openapicontract.application.OpenApiContractApplicationService;
import tech.jhipster.lite.module.domain.resource.*;

@Configuration
class OpenApiContractModuleConfiguration {

@Bean
JHipsterModuleResource openApiContractModule(OpenApiContractApplicationService openApiContract) {
return JHipsterModuleResource.builder()
.slug(OPENAPI_CONTRACT)
.propertiesDefinition(JHipsterModulePropertiesDefinition.builder().addBasePackage().build())
.apiDoc("Spring Boot - OpenAPI", "Generates OpenAPI contract at build time using openapi-maven-plugin")
.organization(JHipsterModuleOrganization.builder().addDependency(SPRING_MVC_SERVER).addDependency(MAVEN_JAVA).build())
.tags("server", "spring", "spring-boot", "documentation", "swagger", "openapi")
.factory(openApiContract::buildModule);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@tech.jhipster.lite.BusinessContext
package tech.jhipster.lite.generator.server.springboot.apidocumentation.openapicontract;
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public enum JHLiteModuleSlug implements JHipsterModuleSlugFactory {
MYSQL("mysql"),
NEO4J("neo4j"),
NEO4J_MIGRATIONS("neo4j-migrations"),
OPENAPI_CONTRACT("openapi-contract"),
OPTIONAL_TYPESCRIPT("optional-typescript"),
PAGINATION_DOMAIN("pagination-domain"),
PLAYWRIGHT_COMPONENT_TESTS("playwright-component-tests"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ public String get() {
public String path() {
return basePackage().replace('.', '/');
}

@Override
public String toString() {
return basePackage;
}
}
6 changes: 6 additions & 0 deletions src/main/resources/generator/dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
<surefire-plugin.version>3.5.0</surefire-plugin.version>
<failsafe-plugin.version>3.5.0</failsafe-plugin.version>
<asciidoctor-maven-plugin.version>3.0.0</asciidoctor-maven-plugin.version>
<openapi-maven-plugin.version>0.0.20</openapi-maven-plugin.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -394,6 +395,11 @@
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>${asciidoctor-maven-plugin.version}</version>
</dependency>
<dependency>
<groupId>io.github.kbuntrock</groupId>
<artifactId>openapi-maven-plugin</artifactId>
<version>${openapi-maven-plugin.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
6 changes: 6 additions & 0 deletions src/test/features/server/springboot/openapi-contract.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Feature: OpenAPI contract generation

Scenario: Should apply OpenAPI contract module
When I apply "openapi-contract" module to default project with maven file
| packageName | tech.jhipster.chips |
Then I should have "openapi-maven-plugin" in "pom.xml"
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package tech.jhipster.lite.generator.server.springboot.apidocumentation.openapicontract.domain;

import static tech.jhipster.lite.TestFileUtils.tmpDirForTest;
import static tech.jhipster.lite.module.domain.JHipsterModulesFixture.propertiesBuilder;
import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.assertThatModuleWithFiles;
import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.pomFile;

import org.junit.jupiter.api.Test;
import tech.jhipster.lite.UnitTest;
import tech.jhipster.lite.module.domain.JHipsterModule;
import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties;

@UnitTest
class OpenApiContractModuleFactoryTest {

private static final OpenApiContractModuleFactory factory = new OpenApiContractModuleFactory();

@Test
void shouldBuildModuleOnProjectWithoutDefaultGoal() {
JHipsterModuleProperties properties = propertiesBuilder(tmpDirForTest()).basePackage("tech.jhipster.jhlitest").build();

JHipsterModule module = factory.buildModule(properties);

assertThatModuleWithFiles(module, pomFile())
.hasFile("pom.xml")
.containing(
// language=xml
"""
<plugin>
<groupId>io.github.kbuntrock</groupId>
<artifactId>openapi-maven-plugin</artifactId>
</plugin>\
"""
)
.containing(
// language=xml
"""
<plugin>
<groupId>io.github.kbuntrock</groupId>
<artifactId>openapi-maven-plugin</artifactId>
<version>${openapi-maven-plugin.version}</version>
<executions>
<execution>
<id>generate-openapi-contract</id>
<goals>
<goal>documentation</goal>
</goals>
</execution>
</executions>
<configuration>
<apiConfiguration>
<library>SPRING_MVC</library>
</apiConfiguration>
<apis>
<api>
<filename>openapi-contract.yml</filename>
<locations>
<location>tech.jhipster.jhlitest</location>
</locations>
<tag>
<substitutions>
<sub>
<regex>Resource$</regex>
<substitute />
</sub>
</substitutions>
</tag>
</api>
</apis>
</configuration>
</plugin>\
"""
);
}
}
1 change: 1 addition & 0 deletions tests-ci/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ elif [[ $application == 'fullapp' ]]; then
"jpa-pagination" \
"spring-boot-async" \
"spring-boot-devtools" \
"openapi-contract" \
"logstash" \
"jib" \
"dockerfile-${java_build_tool}" \
Expand Down