Skip to content
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -59,30 +33,28 @@
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.
Expand Down Expand Up @@ -609,19 +581,11 @@ public void execute() throws MojoExecutionException {
}

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;
}
}
Expand Down Expand Up @@ -1010,17 +974,15 @@ public void execute() throws MojoExecutionException {

// 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()) {
throw new RuntimeException("Failed to create the folder " + parent.getAbsolutePath() +
" 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,
Expand All @@ -1035,45 +997,21 @@ public void execute() throws MojoExecutionException {
}

/**
* 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<AuthorizationValue> 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();
}

/**
Expand Down
Loading