- DefaultGenerator now communicates failures by throwing exceptions

rather than setting a status flag in a public field
- DefaultGenerator now decorates exceptions to record where a failure
occured (which api, model or operation?)
- CodeGenMojo now propagates this exception to maven to abort the build
This commit is contained in:
Adrian Moos 2015-09-22 18:01:29 +02:00
parent 98ff2d231f
commit d4a94fbf52
3 changed files with 136 additions and 128 deletions

View File

@ -162,7 +162,16 @@ public class CodeGenMojo extends AbstractMojo {
ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger); ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger);
input.setConfig(config); input.setConfig(config);
new DefaultGenerator().opts(input).generate();
try {
new DefaultGenerator().opts(input).generate();
} 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,
// so let's log it in any case:
getLog().error(e);
throw new MojoExecutionException("Code generation failed. See above for the full exception.");
}
if (addCompileSourceRoot) { if (addCompileSourceRoot) {
project.addCompileSourceRoot(output.toString()); project.addCompileSourceRoot(output.toString());

View File

@ -5,7 +5,6 @@ import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import com.samskivert.mustache.Mustache; import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template; import com.samskivert.mustache.Template;
import io.swagger.codegen.languages.CodeGenStatus;
import io.swagger.models.ComposedModel; import io.swagger.models.ComposedModel;
import io.swagger.models.Contact; import io.swagger.models.Contact;
import io.swagger.models.Info; import io.swagger.models.Info;
@ -47,8 +46,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
protected ClientOptInput opts = null; protected ClientOptInput opts = null;
protected Swagger swagger = null; protected Swagger swagger = null;
public CodeGenStatus status = CodeGenStatus.UNRUN;
@Override @Override
public Generator opts(ClientOptInput opts) { public Generator opts(ClientOptInput opts) {
this.opts = opts; this.opts = opts;
@ -69,76 +66,76 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
Json.prettyPrint(swagger); Json.prettyPrint(swagger);
} }
List<File> files = new ArrayList<File>(); List<File> files = new ArrayList<File>();
try { config.processOpts();
config.processOpts(); config.preprocessSwagger(swagger);
config.preprocessSwagger(swagger);
config.additionalProperties().put("generatedDate", DateTime.now().toString()); config.additionalProperties().put("generatedDate", DateTime.now().toString());
config.additionalProperties().put("generatorClass", config.getClass().toString()); config.additionalProperties().put("generatorClass", config.getClass().toString());
if (swagger.getInfo() != null) { if (swagger.getInfo() != null) {
Info info = swagger.getInfo(); Info info = swagger.getInfo();
if (info.getTitle() != null) { if (info.getTitle() != null) {
config.additionalProperties().put("appName", info.getTitle()); config.additionalProperties().put("appName", info.getTitle());
} }
if (info.getVersion() != null) { if (info.getVersion() != null) {
config.additionalProperties().put("appVersion", info.getVersion()); config.additionalProperties().put("appVersion", info.getVersion());
} }
if (info.getDescription() != null) { if (info.getDescription() != null) {
config.additionalProperties().put("appDescription", config.additionalProperties().put("appDescription",
config.escapeText(info.getDescription())); config.escapeText(info.getDescription()));
} }
if (info.getContact() != null) { if (info.getContact() != null) {
Contact contact = info.getContact(); Contact contact = info.getContact();
config.additionalProperties().put("infoUrl", contact.getUrl()); config.additionalProperties().put("infoUrl", contact.getUrl());
if (contact.getEmail() != null) { if (contact.getEmail() != null) {
config.additionalProperties().put("infoEmail", contact.getEmail()); config.additionalProperties().put("infoEmail", contact.getEmail());
}
}
if (info.getLicense() != null) {
License license = info.getLicense();
if (license.getName() != null) {
config.additionalProperties().put("licenseInfo", license.getName());
}
if (license.getUrl() != null) {
config.additionalProperties().put("licenseUrl", license.getUrl());
}
}
if (info.getVersion() != null) {
config.additionalProperties().put("version", info.getVersion());
} }
} }
if (info.getLicense() != null) {
StringBuilder hostBuilder = new StringBuilder(); License license = info.getLicense();
String scheme; if (license.getName() != null) {
if (swagger.getSchemes() != null && swagger.getSchemes().size() > 0) { config.additionalProperties().put("licenseInfo", license.getName());
scheme = swagger.getSchemes().get(0).toValue(); }
} else { if (license.getUrl() != null) {
scheme = "https"; config.additionalProperties().put("licenseUrl", license.getUrl());
}
} }
hostBuilder.append(scheme); if (info.getVersion() != null) {
hostBuilder.append("://"); config.additionalProperties().put("version", info.getVersion());
if (swagger.getHost() != null) {
hostBuilder.append(swagger.getHost());
} else {
hostBuilder.append("localhost");
} }
if (swagger.getBasePath() != null) { }
hostBuilder.append(swagger.getBasePath());
} StringBuilder hostBuilder = new StringBuilder();
String contextPath = swagger.getBasePath() == null ? "" : swagger.getBasePath(); String scheme;
String basePath = hostBuilder.toString(); if (swagger.getSchemes() != null && swagger.getSchemes().size() > 0) {
scheme = swagger.getSchemes().get(0).toValue();
} else {
scheme = "https";
}
hostBuilder.append(scheme);
hostBuilder.append("://");
if (swagger.getHost() != null) {
hostBuilder.append(swagger.getHost());
} else {
hostBuilder.append("localhost");
}
if (swagger.getBasePath() != null) {
hostBuilder.append(swagger.getBasePath());
}
String contextPath = swagger.getBasePath() == null ? "" : swagger.getBasePath();
String basePath = hostBuilder.toString();
List<Object> allOperations = new ArrayList<Object>(); List<Object> allOperations = new ArrayList<Object>();
List<Object> allModels = new ArrayList<Object>(); List<Object> allModels = new ArrayList<Object>();
// models // models
Map<String, Model> definitions = swagger.getDefinitions(); Map<String, Model> definitions = swagger.getDefinitions();
if (definitions != null) { if (definitions != null) {
List<String> sortedModelKeys = sortModelsByInheritance(definitions); List<String> sortedModelKeys = sortModelsByInheritance(definitions);
for (String name : sortedModelKeys) { for (String name : sortedModelKeys) {
try {
//dont generate models that have an import mapping //dont generate models that have an import mapping
if(config.importMapping().containsKey(name)) { if(config.importMapping().containsKey(name)) {
@ -173,16 +170,20 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
writeToFile(filename, tmpl.execute(models)); writeToFile(filename, tmpl.execute(models));
files.add(new File(filename)); files.add(new File(filename));
} }
} catch (Exception e) {
throw new RuntimeException("Could not generate model '" + name + "'", e);
} }
} }
if (System.getProperty("debugModels") != null) { }
System.out.println("############ Model info ############"); if (System.getProperty("debugModels") != null) {
Json.prettyPrint(allModels); System.out.println("############ Model info ############");
} Json.prettyPrint(allModels);
}
// apis // apis
Map<String, List<CodegenOperation>> paths = processPaths(swagger.getPaths()); Map<String, List<CodegenOperation>> paths = processPaths(swagger.getPaths());
for (String tag : paths.keySet()) { for (String tag : paths.keySet()) {
try {
List<CodegenOperation> ops = paths.get(tag); List<CodegenOperation> ops = paths.get(tag);
Map<String, Object> operation = processOperations(config, tag, ops); Map<String, Object> operation = processOperations(config, tag, ops);
@ -207,7 +208,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
} }
for (String templateName : config.apiTemplateFiles().keySet()) { for (String templateName : config.apiTemplateFiles().keySet()) {
String filename = config.apiFilename(templateName, tag); String filename = config.apiFilename(templateName, tag);
if (!config.shouldOverwrite(filename) && new File(filename).exists()) { if (!config.shouldOverwrite(filename) && new File(filename).exists()) {
continue; continue;
@ -228,51 +228,55 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
writeToFile(filename, tmpl.execute(operation)); writeToFile(filename, tmpl.execute(operation));
files.add(new File(filename)); files.add(new File(filename));
} }
} } catch (Exception e) {
if (System.getProperty("debugOperations") != null) { throw new RuntimeException("Could not generate api file for '" + tag + "'", e);
System.out.println("############ Operation info ############"); }
Json.prettyPrint(allOperations); }
} if (System.getProperty("debugOperations") != null) {
System.out.println("############ Operation info ############");
Json.prettyPrint(allOperations);
}
// supporting files // supporting files
Map<String, Object> bundle = new HashMap<String, Object>(); Map<String, Object> bundle = new HashMap<String, Object>();
bundle.putAll(config.additionalProperties()); bundle.putAll(config.additionalProperties());
bundle.put("apiPackage", config.apiPackage()); bundle.put("apiPackage", config.apiPackage());
Map<String, Object> apis = new HashMap<String, Object>(); Map<String, Object> apis = new HashMap<String, Object>();
apis.put("apis", allOperations); apis.put("apis", allOperations);
if (swagger.getHost() != null) { if (swagger.getHost() != null) {
bundle.put("host", swagger.getHost()); bundle.put("host", swagger.getHost());
} }
bundle.put("basePath", basePath); bundle.put("basePath", basePath);
bundle.put("scheme", scheme); bundle.put("scheme", scheme);
bundle.put("contextPath", contextPath); bundle.put("contextPath", contextPath);
bundle.put("apiInfo", apis); bundle.put("apiInfo", apis);
bundle.put("models", allModels); bundle.put("models", allModels);
bundle.put("apiFolder", config.apiPackage().replace('.', File.separatorChar)); bundle.put("apiFolder", config.apiPackage().replace('.', File.separatorChar));
bundle.put("modelPackage", config.modelPackage()); bundle.put("modelPackage", config.modelPackage());
List<CodegenSecurity> authMethods = config.fromSecurity(swagger.getSecurityDefinitions()); List<CodegenSecurity> authMethods = config.fromSecurity(swagger.getSecurityDefinitions());
if (authMethods != null && !authMethods.isEmpty()) { if (authMethods != null && !authMethods.isEmpty()) {
bundle.put("authMethods", authMethods); bundle.put("authMethods", authMethods);
bundle.put("hasAuthMethods", true); bundle.put("hasAuthMethods", true);
} }
if (swagger.getExternalDocs() != null) { if (swagger.getExternalDocs() != null) {
bundle.put("externalDocs", swagger.getExternalDocs()); bundle.put("externalDocs", swagger.getExternalDocs());
} }
for (int i = 0; i < allModels.size() - 1; i++) { for (int i = 0; i < allModels.size() - 1; i++) {
HashMap<String, CodegenModel> cm = (HashMap<String, CodegenModel>) allModels.get(i); HashMap<String, CodegenModel> cm = (HashMap<String, CodegenModel>) allModels.get(i);
CodegenModel m = cm.get("model"); CodegenModel m = cm.get("model");
m.hasMoreModels = true; m.hasMoreModels = true;
} }
config.postProcessSupportingFileData(bundle); config.postProcessSupportingFileData(bundle);
if (System.getProperty("debugSupportingFiles") != null) { if (System.getProperty("debugSupportingFiles") != null) {
System.out.println("############ Supporting file info ############"); System.out.println("############ Supporting file info ############");
Json.prettyPrint(bundle); Json.prettyPrint(bundle);
} }
for (SupportingFile support : config.supportingFiles()) { for (SupportingFile support : config.supportingFiles()) {
try {
String outputFolder = config.outputFolder(); String outputFolder = config.outputFolder();
if (isNotEmpty(support.folder)) { if (isNotEmpty(support.folder)) {
outputFolder += File.separator + support.folder; outputFolder += File.separator + support.folder;
@ -329,14 +333,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
files.add(outputFile); files.add(outputFile);
} }
} catch (Exception e) {
throw new RuntimeException("Could not generate supporting file '" + support + "'", e);
} }
config.processSwagger(swagger);
status = CodeGenStatus.SUCCESSFUL;
} catch (Exception e) {
status = CodeGenStatus.FAILED;
} }
config.processSwagger(swagger);
return files; return files;
} }
@ -508,11 +511,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
} }
} }
catch (Exception ex) { catch (Exception ex) {
LOGGER.error("Error while trying to get Config from Operation for tag(" + tag + ")\n" // String msg = "Could not process operation:\n" //
+ "\tResource: " + httpMethod + " " + resourcePath + "\n"// + " Tag: " + tag + "\n"//
+ "\tOperation:" + operation + "\n" // + " Operation: " + operation.getOperationId() + "\n" //
+ "\tDefinitions: " + swagger.getDefinitions() + "\n"); + " Resource: " + httpMethod + " " + resourcePath + "\n"//
ex.printStackTrace(); + " Definitions: " + swagger.getDefinitions();
throw new RuntimeException(msg, ex);
} }
} }
} }

View File

@ -1,5 +0,0 @@
package io.swagger.codegen.languages;
public enum CodeGenStatus {
UNRUN, SUCCESSFUL, FAILED
}