diff --git a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java index 2db32f00517..d42cdc2cba9 100644 --- a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java +++ b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java @@ -17,40 +17,14 @@ package org.openapitools.codegen.plugin; -import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.*; - +import com.google.common.hash.Hashing; +import com.google.common.io.Files; +import io.swagger.parser.OpenAPIParser; import io.swagger.v3.core.util.Json; import io.swagger.v3.core.util.Yaml; import io.swagger.v3.parser.OpenAPIResolver; import io.swagger.v3.parser.OpenAPIV3Parser; -import io.swagger.v3.parser.core.models.AuthorizationValue; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.URLConnection; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import com.google.common.io.ByteSource; -import com.google.common.io.CharSource; import io.swagger.v3.parser.core.models.ParseOptions; -import io.swagger.v3.parser.util.ClasspathHelper; import lombok.Setter; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; @@ -59,30 +33,28 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.Component; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.annotations.*; import org.apache.maven.project.MavenProject; - import org.apache.maven.project.MavenProjectHelper; -import org.openapitools.codegen.CliOption; -import org.openapitools.codegen.ClientOptInput; -import org.openapitools.codegen.CodegenConfig; -import org.openapitools.codegen.CodegenConstants; -import org.openapitools.codegen.DefaultGenerator; -import org.openapitools.codegen.auth.AuthParser; +import org.openapitools.codegen.*; import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.config.GlobalSettings; import org.openapitools.codegen.config.MergedSpecBuilder; -import org.sonatype.plexus.build.incremental.BuildContext; -import org.sonatype.plexus.build.incremental.DefaultBuildContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonatype.plexus.build.incremental.BuildContext; +import org.sonatype.plexus.build.incremental.DefaultBuildContext; -import com.google.common.hash.Hashing; -import com.google.common.io.Files; +import java.io.File; +import java.io.IOException; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.*; + +import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.*; /** * Goal which generates client/server code from a OpenAPI json/yaml definition. @@ -609,19 +581,11 @@ public class CodeGenMojo extends AbstractMojo { } if (Boolean.TRUE.equals(skipIfSpecIsUnchanged)) { - File storedInputSpecHashFile = getHashFile(inputSpecFile); + final File storedInputSpecHashFile = getHashFile(inputSpecFile); if (storedInputSpecHashFile.exists()) { - String inputSpecHash = null; - try { - inputSpecHash = calculateInputSpecHash(inputSpecFile); - } catch (IOException ex) { - ex.printStackTrace(); - } - @SuppressWarnings("UnstableApiUsage") String storedInputSpecHash = Files.asCharSource(storedInputSpecHashFile, StandardCharsets.UTF_8).read(); - if (storedInputSpecHash.equals(inputSpecHash)) { - getLog().info( - "Code generation is skipped because input was unchanged"); + if (storedInputSpecHash.equals(calculateInputSpecHash(inputSpec))) { + getLog().info("Code generation is skipped because input was unchanged"); return; } } @@ -1010,8 +974,6 @@ public class CodeGenMojo extends AbstractMojo { // Store a checksum of the input spec File storedInputSpecHashFile = getHashFile(inputSpecFile); - String inputSpecHash = calculateInputSpecHash(inputSpecFile); - if (storedInputSpecHashFile.getParent() != null && !new File(storedInputSpecHashFile.getParent()).exists()) { File parent = new File(storedInputSpecHashFile.getParent()); if (!parent.mkdirs()) { @@ -1019,8 +981,8 @@ public class CodeGenMojo extends AbstractMojo { " to store the checksum of the input spec."); } } - Files.asCharSink(storedInputSpecHashFile, StandardCharsets.UTF_8).write(inputSpecHash); + Files.asCharSink(storedInputSpecHashFile, StandardCharsets.UTF_8).write(calculateInputSpecHash(inputSpec)); } catch (Exception e) { // Maven logs exceptions thrown by plugins only if invoked with -e // I find it annoying to jump through hoops to get basic diagnostic information, @@ -1035,45 +997,21 @@ public class CodeGenMojo extends AbstractMojo { } /** - * Calculate openapi specification file hash. If specification is hosted on remote resource it is downloaded first + * Calculate an SHA256 hash for the openapi specification. + * If the specification is hosted on a remote resource it is downloaded first. * - * @param inputSpecFile - Openapi specification input file to calculate its hash. - * Does not take into account if input spec is hosted on remote resource - * @return openapi specification file hash - * @throws IOException + * @param inputSpec - Openapi specification input file. Can denote a URL or file path. + * @return openapi specification hash */ - private String calculateInputSpecHash(File inputSpecFile) throws IOException { - - URL inputSpecRemoteUrl = inputSpecRemoteUrl(); - - File inputSpecTempFile = inputSpecFile; - - if (inputSpecRemoteUrl != null) { - inputSpecTempFile = java.nio.file.Files.createTempFile("openapi-spec", ".tmp").toFile(); - - URLConnection conn = inputSpecRemoteUrl.openConnection(); - if (isNotEmpty(auth)) { - List authList = AuthParser.parse(auth); - for (AuthorizationValue a : authList) { - conn.setRequestProperty(a.getKeyName(), a.getValue()); - } - } - try (ReadableByteChannel readableByteChannel = Channels.newChannel(conn.getInputStream())) { - FileChannel fileChannel; - try (FileOutputStream fileOutputStream = new FileOutputStream(inputSpecTempFile)) { - fileChannel = fileOutputStream.getChannel(); - fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE); - } - } - } - - ByteSource inputSpecByteSource = - inputSpecTempFile.exists() - ? Files.asByteSource(inputSpecTempFile) - : CharSource.wrap(ClasspathHelper.loadFileFromClasspath(inputSpecTempFile.toString().replaceAll("\\\\","/"))) - .asByteSource(StandardCharsets.UTF_8); - - return inputSpecByteSource.hash(Hashing.sha256()).toString(); + private String calculateInputSpecHash(String inputSpec) { + final ParseOptions parseOptions = new ParseOptions(); + parseOptions.setResolve(true); + + final URL remoteUrl = inputSpecRemoteUrl(); + return Hashing.sha256().hashBytes( + new OpenAPIParser().readLocation(remoteUrl == null ? inputSpec : remoteUrl.toString(), null, parseOptions) + .getOpenAPI().toString().getBytes(StandardCharsets.UTF_8) + ).toString(); } /** diff --git a/modules/openapi-generator-maven-plugin/src/test/java/org/openapitools/codegen/plugin/CodeGenMojoTest.java b/modules/openapi-generator-maven-plugin/src/test/java/org/openapitools/codegen/plugin/CodeGenMojoTest.java index e87a391436d..42db5395c25 100644 --- a/modules/openapi-generator-maven-plugin/src/test/java/org/openapitools/codegen/plugin/CodeGenMojoTest.java +++ b/modules/openapi-generator-maven-plugin/src/test/java/org/openapitools/codegen/plugin/CodeGenMojoTest.java @@ -16,17 +16,6 @@ package org.openapitools.codegen.plugin; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.execution.DefaultMavenExecutionRequest; @@ -39,9 +28,24 @@ import org.apache.maven.project.ProjectBuilder; import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.internal.impl.DefaultLocalPathComposer; import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; import org.eclipse.aether.repository.LocalRepository; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class CodeGenMojoTest extends BaseTestCase { @Override protected void setUp() throws Exception { @@ -62,8 +66,7 @@ public class CodeGenMojoTest extends BaseTestCase { @SuppressWarnings("unchecked") private void testCommonConfiguration(String profile) throws Exception { - File folder = Files.createTempDirectory("test").toFile(); - CodeGenMojo mojo = loadMojo(folder, "src/test/resources/default", profile); + CodeGenMojo mojo = loadMojo(newTempFolder(), "src/test/resources/default", profile); mojo.execute(); assertEquals("java", getVariableValueFromObject(mojo, "generatorName")); assertEquals("jersey2", getVariableValueFromObject(mojo, "library")); @@ -79,43 +82,42 @@ public class CodeGenMojoTest extends BaseTestCase { public void testHashGenerationFileContainsExecutionId() throws Exception { // GIVEN - Path folder = Files.createTempDirectory("test"); - CodeGenMojo mojo = loadMojo(folder.toFile(), "src/test/resources/default", "file", "executionId"); + final Path tempDir = newTempFolder(); + CodeGenMojo mojo = loadMojo(tempDir, "src/test/resources/default", "file", "executionId"); // WHEN mojo.execute(); // THEN - Path hashFolder = folder.resolve("target/generated-sources/common-maven/remote-openapi/.openapi-generator"); - assertTrue(hashFolder.resolve("petstore.yaml-executionId.sha256").toFile().exists()); + assertTrue(Files.exists(tempDir.resolve( + "target/generated-sources/common-maven/remote-openapi/.openapi-generator/petstore.yaml-executionId.sha256" + ))); } /** - * For a Pom file which refers to a input file which will be on the classpath, as opposed to a file path, + * For a Pom file which refers to an input file which will be on the classpath, as opposed to a file path, * test that the spec is not regenerated when the hash has not changed. - * - * @throws Exception */ public void testSkipRegenerationForClasspathSpecFileNoChange() throws Exception { - //GIVEN - /* Setup the mojo */ - final Path folder = Files.createTempDirectory("test-classpath"); - final CodeGenMojo mojo = loadMojo(folder.toFile(), "src/test/resources/classpath", null, "executionId"); + /* Set up the mojo */ + final Path tempDir = newTempFolder(); + final CodeGenMojo mojo = loadMojo(tempDir, "src/test/resources/classpath", null, "executionId"); /* Perform an initial generation */ mojo.execute(); /* Check the hash file was created */ - final Path hashFolder = folder.resolve("target/generated-sources/common-maven/remote-openapi/.openapi-generator"); - assertTrue(hashFolder.resolve("petstore-on-classpath.yaml-executionId.sha256").toFile().exists()); + final Path generatedDir = tempDir.resolve("target/generated-sources/common-maven/remote-openapi"); + assertTrue(Files.exists( + generatedDir.resolve(".openapi-generator/petstore-on-classpath.yaml-executionId.sha256") + )); /* Remove the generated source */ - Files.walk(folder.resolve("target/generated-sources/common-maven/remote-openapi/src")) - .sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); - + try (Stream files = Files.walk(generatedDir.resolve("src"))) { + //noinspection ResultOfMethodCallIgnored + files.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); + } // WHEN /* Execute the mojo again */ @@ -123,41 +125,37 @@ public class CodeGenMojoTest extends BaseTestCase { // THEN /* Verify that the source directory has not been repopulated. If it has then we generated code again */ - assertFalse("src directory should not have been regenerated", - folder.resolve("target/generated-sources/common-maven/remote-openapi/src").toFile().exists()); - + assertFalse("src directory should not have been regenerated", Files.exists(generatedDir.resolve("src"))); } /** - * For a Pom file which refers to a input file which will be on the classpath, as opposed to a file path, + * For a Pom file which refers to an input file which will be on the classpath, as opposed to a file path, * test that the generated source is regenerated when the hash has changed. - * - * @throws Exception */ public void testSkipRegenerationForClasspathSpecFileWithChange() throws Exception { - //GIVEN - /* Setup the mojo */ - final Path folder = Files.createTempDirectory("test-classpath"); - final CodeGenMojo mojo = loadMojo(folder.toFile(), "src/test/resources/classpath", null, "executionId"); + /* Set up the mojo */ + final Path tempDir = newTempFolder(); + final CodeGenMojo mojo = loadMojo(tempDir, "src/test/resources/classpath", null, "executionId"); /* Perform an initial generation */ mojo.execute(); /* Check the hash file was created, proving a generation occurred */ - final Path hashFolder = folder.resolve("target/generated-sources/common-maven/remote-openapi/.openapi-generator"); - assertTrue(hashFolder.resolve("petstore-on-classpath.yaml-executionId.sha256").toFile().exists()); + final Path generatedDir = tempDir.resolve("target/generated-sources/common-maven/remote-openapi"); + assertTrue(Files.exists(generatedDir.resolve(".openapi-generator/petstore-on-classpath.yaml-executionId.sha256"))); /* Update the hash contents to be a different value, simulating a spec change */ Files.write( - hashFolder.resolve("petstore-on-classpath.yaml-executionId.sha256"), - Arrays.asList("bd1bf4a953c858f9d47b67ed6029daacf1707e5cbd3d2e4b01383ba30363366f")); + generatedDir.resolve(".openapi-generator/petstore-on-classpath.yaml-executionId.sha256"), + List.of("bd1bf4a953c858f9d47b67ed6029daacf1707e5cbd3d2e4b01383ba30363366f") + ); /* Remove the generated source */ - Files.walk(folder.resolve("target/generated-sources/common-maven/remote-openapi/src")) - .sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); + try(Stream files = Files.walk(generatedDir.resolve("src"))) { + //noinspection ResultOfMethodCallIgnored + files.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); + } // WHEN @@ -165,29 +163,27 @@ public class CodeGenMojoTest extends BaseTestCase { mojo.execute(); // THEN - /* Verify that the source directory has not been repopulated. If it has then we generated code again */ - assertTrue("src directory should have been regenerated", - folder.resolve("target/generated-sources/common-maven/remote-openapi/src").toFile().exists()); - + /* Verify that the source directory has been repopulated. */ + assertTrue("src directory should have been regenerated", Files.exists(generatedDir.resolve("src"))); } public void testCollapsedSpecProduced() throws Exception { // GIVEN - Path folder = Files.createTempDirectory("test"); - CodeGenMojo mojo = loadMojo(folder.toFile(), "src/test/resources/default", "file", "executionId"); + final Path tempDir = newTempFolder(); + CodeGenMojo mojo = loadMojo(tempDir, "src/test/resources/default", "file", "executionId"); // WHEN mojo.execute(); // THEN - File collapseSpecFile = folder.resolve("target/generated-sources/common-maven/remote-openapi/petstore-full-spec.yaml").toFile(); - assertTrue(collapseSpecFile.exists()); + assertTrue(Files.exists( + tempDir.resolve("target/generated-sources/common-maven/remote-openapi/petstore-full-spec.yaml") + )); } public void testCollapsedSpecAddedToArtifacts() throws Exception { // GIVEN - Path folder = Files.createTempDirectory("test"); - CodeGenMojo mojo = loadMojo(folder.toFile(), "src/test/resources/default", "file", "executionId"); + CodeGenMojo mojo = loadMojo(newTempFolder(), "src/test/resources/default", "file", "executionId"); // WHEN mojo.execute(); @@ -201,8 +197,7 @@ public class CodeGenMojoTest extends BaseTestCase { public void testAnyInputSpecMustBeProvided() throws Exception { // GIVEN - Path folder = Files.createTempDirectory("test"); - CodeGenMojo mojo = loadMojo(folder.toFile(), "src/test/resources/default", "file", "executionId"); + CodeGenMojo mojo = loadMojo(newTempFolder(), "src/test/resources/default", "file", "executionId"); mojo.inputSpec = null; mojo.inputSpecRootDirectory = null; @@ -215,8 +210,8 @@ public class CodeGenMojoTest extends BaseTestCase { public void testInputSpecRootDirectoryDoesNotRequireInputSpec() throws Exception { // GIVEN - Path folder = Files.createTempDirectory("test"); - CodeGenMojo mojo = loadMojo(folder.toFile(), "src/test/resources/default", "file", "executionId"); + final Path tempDir = newTempFolder(); + CodeGenMojo mojo = loadMojo(tempDir, "src/test/resources/default", "file", "executionId"); mojo.inputSpec = null; mojo.inputSpecRootDirectory = "src/test/resources/default"; @@ -225,17 +220,43 @@ public class CodeGenMojoTest extends BaseTestCase { // THEN /* Check the hash file was created */ - final Path hashFolder = folder.resolve("target/generated-sources/common-maven/remote-openapi/.openapi-generator"); - assertTrue(hashFolder.resolve("_merged_spec.yaml-executionId.sha256").toFile().exists()); + final Path hashFolder = tempDir.resolve("target/generated-sources/common-maven/remote-openapi/.openapi-generator"); + assertTrue(Files.exists(hashFolder.resolve("_merged_spec.yaml-executionId.sha256"))); } - protected CodeGenMojo loadMojo(File temporaryFolder, String projectRoot, String profile) throws Exception { + /** + * Regression test for #16489 + */ + public void test_skipIfSpecIsUnchanged_recognizesUpdatesInExternalReferencedFile() throws Exception { + + //GIVEN + final Path tempDir = newTempFolder(); + final Path generatedDir = tempDir.resolve("target/generated-sources/issue-16489"); + final Path hashFile = generatedDir.resolve(".openapi-generator/petstore.yaml-default.sha256"); + final CodeGenMojo mojo = loadMojo(tempDir, "src/test/resources/issue-16489", null); + mojo.execute(); // Perform an initial generation + var currentHash = Files.readString(hashFile); // read hash + FileUtils.deleteDirectory(generatedDir.resolve("src").toFile()); // Remove the generated source + Files.writeString( // change schema definition in external file + tempDir.resolve("schemas/Pet.yaml"),"\n wrapped: true", StandardOpenOption.APPEND + ); + + // WHEN + mojo.execute(); // Execute the mojo again + + // THEN + assertNotEquals( + Files.readString(hashFile), currentHash, "Checksum should not be the same after external file change" + ); + assertTrue("Src directory should have been regenerated", Files.exists(generatedDir.resolve("src"))); + } + + protected CodeGenMojo loadMojo(Path temporaryFolder, String projectRoot, String profile) throws Exception { return loadMojo(temporaryFolder, projectRoot, profile, "default"); } - protected CodeGenMojo loadMojo(File temporaryFolder, String projectRoot, String profile, String executionId) throws Exception { - File file = new File(projectRoot); - FileUtils.copyDirectory(file, temporaryFolder); + protected CodeGenMojo loadMojo(Path temporaryFolder, String projectRoot, String profile, String executionId) throws Exception { + FileUtils.copyDirectory(new File(projectRoot), temporaryFolder.toFile()); MavenProject project = readMavenProject(temporaryFolder, profile); MavenSession session = newMavenSession(project); MojoExecution execution = newMojoExecution("generate"); @@ -249,22 +270,29 @@ public class CodeGenMojoTest extends BaseTestCase { return executionWithId; } - protected MavenProject readMavenProject(File basedir, String profile) - throws Exception { - File pom = new File(basedir, "pom.xml"); - LocalRepository localRepo = new LocalRepository(new File(basedir, "local-repo")); + protected MavenProject readMavenProject(Path basedir, String profile) throws Exception { + LocalRepository localRepo = new LocalRepository(basedir.resolve("local-repo").toFile()); DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); - session.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory().newInstance(session, localRepo)); - MavenExecutionRequest request = new DefaultMavenExecutionRequest(); - request.setBaseDirectory(basedir); + session.setLocalRepositoryManager( + new SimpleLocalRepositoryManagerFactory(new DefaultLocalPathComposer()).newInstance(session, localRepo) + ); + MavenExecutionRequest request = new DefaultMavenExecutionRequest().setBaseDirectory(basedir.toFile()); if (profile != null) { request.addActiveProfile(profile); } - ProjectBuildingRequest configuration = request.getProjectBuildingRequest(); - configuration.setRepositorySession(session); - configuration.setResolveDependencies(true); - MavenProject project = lookup(ProjectBuilder.class).build(pom, configuration).getProject(); + ProjectBuildingRequest configuration = request.getProjectBuildingRequest() + .setRepositorySession(session) + .setResolveDependencies(true); + MavenProject project = lookup(ProjectBuilder.class) + .build(basedir.resolve("pom.xml").toFile(), configuration) + .getProject(); assertNotNull(project); return project; } + + static private Path newTempFolder() throws IOException { + final Path tempDir = Files.createTempDirectory("test"); + tempDir.toFile().deleteOnExit(); + return tempDir; + } } diff --git a/modules/openapi-generator-maven-plugin/src/test/resources/issue-16489/petstore.yaml b/modules/openapi-generator-maven-plugin/src/test/resources/issue-16489/petstore.yaml new file mode 100644 index 00000000000..88b99532757 --- /dev/null +++ b/modules/openapi-generator-maven-plugin/src/test/resources/issue-16489/petstore.yaml @@ -0,0 +1,105 @@ +openapi: 3.0.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: Sample file with just two endpoints and one schema (defined in an external file $ref) + version: 1.0.0 + title: OpenAPI Petstore +paths: + /pet: + post: + tags: + - pet + summary: Add a new pet to the store + description: '' + operationId: addPet + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + '/pet/{petId}': + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + delete: + tags: + - pet + summary: Deletes a pet + description: '' + operationId: deletePet + parameters: + - name: api_key + in: header + required: false + schema: + type: string + - name: petId + in: path + description: Pet id to delete + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid pet value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: 'schemas/Pet.yaml' + application/xml: + schema: + $ref: 'schemas/Pet.yaml' + description: Pet object that needs to be added to the store + required: true + schemas: + Pet: + $ref: 'schemas/Pet.yaml' diff --git a/modules/openapi-generator-maven-plugin/src/test/resources/issue-16489/pom.xml b/modules/openapi-generator-maven-plugin/src/test/resources/issue-16489/pom.xml new file mode 100644 index 00000000000..54724ef7fa6 --- /dev/null +++ b/modules/openapi-generator-maven-plugin/src/test/resources/issue-16489/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + common.maven + issue-16489 + jar + 1.0.0-SNAPSHOT + OpenAPI Generator Configuration Test + https://openapi-generator.tech/ + + + + org.openapitools + openapi-generator-maven-plugin + 7.6.0 + + java + + true + + native + ${basedir}/target/generated-sources/issue-16489 + hideGenerationTimestamp=true + ${basedir}/petstore.yaml + false + false + false + false + false + + true + + + + + generate + generate-sources + + generate + + + + + + + \ No newline at end of file diff --git a/modules/openapi-generator-maven-plugin/src/test/resources/issue-16489/schemas/Pet.yaml b/modules/openapi-generator-maven-plugin/src/test/resources/issue-16489/schemas/Pet.yaml new file mode 100644 index 00000000000..8f93f9075f3 --- /dev/null +++ b/modules/openapi-generator-maven-plugin/src/test/resources/issue-16489/schemas/Pet.yaml @@ -0,0 +1,29 @@ +title: a Pet +description: A pet for sale in the pet store +type: object +required: + - name + - photoUrls +properties: + id: + type: integer + format: int64 + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + status: + type: string + description: pet status in the store + enum: + - available + - pending + - sold +xml: + name: Pet \ No newline at end of file