Skip to content

Commit

Permalink
Add server extension (#482)
Browse files Browse the repository at this point in the history
  • Loading branch information
carlesarnal authored Feb 20, 2024
1 parent e12553d commit f61a588
Show file tree
Hide file tree
Showing 305 changed files with 4,579 additions and 19 deletions.
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>
<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>
</files>
</configuration>
</execution>
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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());
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

0 comments on commit f61a588

Please sign in to comment.