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

Add server extension #482

Merged
merged 11 commits into from
Feb 20, 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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/build_website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Store PR id
if: github.event_name == 'pull_request'
run: |
echo ${{ github.event.number }} > ./docs/target/generated-docs/pr-id.txt
echo ${{ github.event.number }} > ./client/docs/target/generated-docs/pr-id.txt

- name: Publishing directory for PR preview
if: github.event_name == 'pull_request'
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@

> **⚠️** Check versions 1.x.x if you're still using Quarkus 2. But be aware that we no longer support Quarkus 2. That means there are no updates planned for those versions.

Quarkus' extension for generation of [Rest Clients](https://quarkus.io/guides/rest-client) based on OpenAPI specification files.
Quarkus' extensions for generation of [Rest Clients](https://quarkus.io/guides/rest-client) and server stubs generation based on the [Apicurio Codegen](https://github.com/Apicurio/apicurio-codegen) capabilities based on OpenAPI specification files.

This extension is based on the [OpenAPI Generator Tool](https://openapi-generator.tech/). Please consider donation to help them maintain the
This client-side extension is based on the [OpenAPI Generator Tool](https://openapi-generator.tech/). Please consider donation to help them maintain the
project: https://opencollective.com/openapi_generator/donate

This extension is for REST code generation for client side only. If you're looking for code generation for the server side, please take a look at the [Quarkus Apicurio Extension](https://github.com/Apicurio/apicurio-codegen/tree/main/quarkus-extension).
This repository holds two Quarkus extensions. The one located on the client folder is for REST code generation for client side only. The extension located in the server folder can be used for server stubs generation.

**Want to contribute? Great!** We try to make it easy, and all contributions, even the smaller ones, are more than welcome. This includes bug reports, fixes, documentation, examples... But first, read [this page](CONTRIBUTING.md).

Expand Down
3 changes: 2 additions & 1 deletion deployment/pom.xml → client/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.quarkiverse.openapi.generator</groupId>
<artifactId>quarkus-openapi-generator-parent</artifactId>
<artifactId>quarkus-openapi-generator-client-parent</artifactId>
fjtirado marked this conversation as resolved.
Show resolved Hide resolved
<version>3.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>quarkus-openapi-generator-deployment</artifactId>
<name>Quarkus - Openapi Generator - Deployment</name>
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions client/docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* xref:index.adoc[Quarkus - Openapi Generator - Client]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
= Quarkus - Openapi Generator
= Quarkus - Openapi Generator - Client
:extension-status: preview


Expand Down
6 changes: 3 additions & 3 deletions docs/pom.xml → client/docs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

<parent>
<groupId>io.quarkiverse.openapi.generator</groupId>
<artifactId>quarkus-openapi-generator-parent</artifactId>
<artifactId>quarkus-openapi-generator-client-parent</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>quarkus-openapi-generator-docs</artifactId>
<name>Quarkus - Openapi Generator - Documentation</name>
<name>Quarkus - Openapi Generator - Client - Documentation</name>

<dependencies>
<!-- Make sure the doc is built after the other artifacts -->
Expand All @@ -33,7 +33,7 @@
</goals>
<configuration>
<files>
<file>${project.basedir}/../.github/project.yml</file>
<file>${project.basedir}/../../.github/project.yml</file>
ricardozanini marked this conversation as resolved.
Show resolved Hide resolved
</files>
</configuration>
</execution>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.quarkiverse.openapi.generator</groupId>
<artifactId>quarkus-openapi-generator-parent</artifactId>
<artifactId>quarkus-openapi-generator-client-parent</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>quarkus-openapi-generator-integration-tests</artifactId>
<name>Quarkus - Openapi Generator - Integration Tests</name>
<packaging>pom</packaging>
<modules>
<module>additional-properties</module>
<module>array-enum</module>
<module>beanparam</module>
<module>change-directory</module>
Expand All @@ -33,7 +35,6 @@
<module>type-mapping</module>
<module>config-key</module>
<module>github</module>
<module>additional-properties</module>
</modules>
<dependencyManagement>
<dependencies>
Expand Down
22 changes: 22 additions & 0 deletions client/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-openapi-generator-parent</artifactId>
<groupId>io.quarkiverse.openapi.generator</groupId>
<version>3.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-openapi-generator-client-parent</artifactId>
<name>Quarkus - Openapi Generator - Client - Parent</name>
<packaging>pom</packaging>

<modules>
<module>deployment</module>
<module>runtime</module>
<module>docs</module>
<module>test-utils</module>
</modules>
</project>
3 changes: 2 additions & 1 deletion runtime/pom.xml → client/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.quarkiverse.openapi.generator</groupId>
<artifactId>quarkus-openapi-generator-parent</artifactId>
<artifactId>quarkus-openapi-generator-client-parent</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>quarkus-openapi-generator</artifactId>
<name>Quarkus - Openapi Generator - Runtime</name>
Expand Down
3 changes: 2 additions & 1 deletion test-utils/pom.xml → client/test-utils/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>quarkus-openapi-generator-parent</artifactId>
<artifactId>quarkus-openapi-generator-client-parent</artifactId>
<groupId>io.quarkiverse.openapi.generator</groupId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>quarkus-openapi-generator-test-utils</artifactId>
<name>Quarkus - Openapi Generator - Test Utils</name>
Expand Down
1 change: 0 additions & 1 deletion docs/modules/ROOT/nav.adoc

This file was deleted.

20 changes: 15 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
<packaging>pom</packaging>
<name>Quarkus - Openapi Generator - Parent</name>
<modules>
<module>deployment</module>
<module>runtime</module>
<module>test-utils</module>
<module>docs</module>
<module>client</module>
<module>server</module>
</modules>
<scm>
<connection>:git:git@github.com:quarkiverse/quarkus-openapi-generator.git</connection>
Expand All @@ -29,6 +27,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.version>3.7.3</quarkus.version>
<apicurio.version>1.1.0.Final</apicurio.version>
<version.com.github.javaparser>3.25.8</version.com.github.javaparser>
<version.org.assertj>3.25.3</version.org.assertj>
<version.org.eclipse.microprofile.fault-tolerance>4.0.2</version.org.eclipse.microprofile.fault-tolerance>
Expand All @@ -53,6 +52,16 @@
<artifactId>quarkus-openapi-generator</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkiverse.openapi.generator</groupId>
<artifactId>quarkus-openapi-generator-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.apicurio</groupId>
<artifactId>apicurio-codegen</artifactId>
<version>${apicurio.version}</version>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
Expand Down Expand Up @@ -115,7 +124,8 @@
</property>
</activation>
<modules>
<module>integration-tests</module>
<module>client/integration-tests</module>
<module>server/integration-tests</module>
</modules>
</profile>
</profiles>
Expand Down
44 changes: 44 additions & 0 deletions server/deployment/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-openapi-generator-server-parent</artifactId>
<groupId>io.quarkiverse.openapi.generator</groupId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-openapi-generator-server-deployment</artifactId>
<name>Quarkus - Openapi Generator - Server - Deployment</name>

<dependencies>
<!-- Quarkus -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.openapi.generator</groupId>
<artifactId>quarkus-openapi-generator-server</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${quarkus.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.quarkiverse.openapi.server.generator.deployment;

import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;

@ConfigRoot(name = CodegenConfig.CODEGEN_TIME_CONFIG_PREFIX, phase = ConfigPhase.BUILD_TIME)
public class CodegenConfig {

static final String CODEGEN_TIME_CONFIG_PREFIX = "quarkus.openapi.generator";
private static final String CODEGEN_BASE_PACKAGE = CODEGEN_TIME_CONFIG_PREFIX + ".base-package";
private static final String CODEGEN_SPEC = CODEGEN_TIME_CONFIG_PREFIX + ".spec";

public static String getBasePackagePropertyName() {
return CODEGEN_BASE_PACKAGE;
}

public static String getSpecPropertyName() {
return CODEGEN_SPEC;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package io.quarkiverse.openapi.server.generator.deployment.codegen;

import static io.quarkiverse.openapi.server.generator.deployment.CodegenConfig.getBasePackagePropertyName;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.io.IOUtils;
import org.eclipse.microprofile.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.apicurio.hub.api.codegen.JaxRsProjectSettings;
import io.apicurio.hub.api.codegen.OpenApi2JaxRs;
import io.quarkus.bootstrap.prebuild.CodeGenException;

public class ApicurioCodegenWrapper {

private static final Logger log = LoggerFactory.getLogger(ApicurioCodegenWrapper.class);
private static final String DEFAULT_PACKAGE = "io.apicurio.api";

private final File outdir;
private final JaxRsProjectSettings projectSettings;

public ApicurioCodegenWrapper(Config config, File outdir) {
this(config, outdir, defaultProjectSettings());
}

public ApicurioCodegenWrapper(Config config, File outdir, JaxRsProjectSettings projectSettings) {
this.outdir = outdir;
this.projectSettings = projectSettings;
this.projectSettings.setJavaPackage(getBasePackage(config));
}

public void generate(Path openApiResource) throws CodeGenException {
final File openApiFile = openApiResource.toFile();

log.info("Generating JAX-RS interfaces and beans from: {}", openApiResource);

if (outdir.isFile()) {
throw new CodeGenException(
"Output directory is unexpectedly a file (should be a directory or non-existent).");
}

if (!outdir.exists()) {
outdir.mkdirs();
}

// Generate code - output a ZIP file.
File zipFile = new File(outdir, "generated-code.zip");

try (FileOutputStream fos = new FileOutputStream(zipFile);
FileInputStream openApiStream = new FileInputStream(openApiFile)) {
OpenApi2JaxRs generator = new OpenApi2JaxRs();
generator.setSettings(projectSettings);
generator.setUpdateOnly(true);
generator.setOpenApiDocument(openApiStream);
log.info("Generating code...");
generator.generate(fos);
} catch (Exception e) {
log.error("Error generating code from openapi spec", e);
throw new CodeGenException(e);
}

// Unpack the temporary ZIP file
log.info("Code generated, unpacking the output ZIP.");
try {
unzip(zipFile, outdir);
} catch (IOException e) {
log.error("Error generating code from openapi spec", e);
throw new CodeGenException(e);
} finally {
// Delete the temporary ZIP file
zipFile.delete();
}

log.info("Code successfully generated.");
}

private void unzip(File fromZipFile, File toOutputDir) throws IOException {
try (java.util.zip.ZipFile zipFile = new ZipFile(fromZipFile)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
File entryDestination = new File(toOutputDir, entry.getName());
Dismissed Show dismissed Hide dismissed
if (entry.isDirectory()) {
entryDestination.mkdirs();
} else {
entryDestination.getParentFile().mkdirs();
try (InputStream in = zipFile.getInputStream(entry);
OutputStream out = new FileOutputStream(entryDestination)) {
IOUtils.copy(in, out);
}
}
}
}
}

private String getBasePackage(final Config config) {
return config
.getOptionalValue(getBasePackagePropertyName(), String.class)
.orElse(DEFAULT_PACKAGE);
}

private static JaxRsProjectSettings defaultProjectSettings() {
JaxRsProjectSettings projectSettings = new JaxRsProjectSettings();
projectSettings.setJavaPackage(DEFAULT_PACKAGE);

projectSettings.setReactive(false);
projectSettings.setCodeOnly(true);
projectSettings.setCliGenCI(false);
projectSettings.setMavenFileStructure(false);
projectSettings.setIncludeSpec(false);
projectSettings.setCliGenCI(false);
return projectSettings;
}
}
Loading
Loading