Skip to content

Commit

Permalink
feat: new module for generating OpenAPI contract at build-time for Sp…
Browse files Browse the repository at this point in the history
…ringMVC applications
  • Loading branch information
murdos committed Sep 9, 2024
1 parent 159f11b commit fb908e3
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 0 deletions.
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

0 comments on commit fb908e3

Please sign in to comment.