Merge remote-tracking branch 'origin/master' into 5.0-sync-master

This commit is contained in:
William Cheng
2020-04-17 15:51:00 +08:00
4730 changed files with 208746 additions and 53119 deletions

View File

@@ -4,7 +4,11 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<<<<<<< HEAD
<version>5.0.0-SNAPSHOT</version>
=======
<version>4.3.1-SNAPSHOT</version>
>>>>>>> origin/master
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -0,0 +1,9 @@
package org.openapitools.codegen;
public class Constants {
private Constants(){ }
public static final String CLI_NAME = "openapi-generator-cli";
public static final String GIT_REPO = "https://github.com/openapitools/openapi-generator";
public static final String SITE = "https://openapi-generator.tech/";
}

View File

@@ -18,7 +18,6 @@
package org.openapitools.codegen;
import io.airlift.airline.Cli;
import io.airlift.airline.Help;
import io.airlift.airline.ParseArgumentsUnexpectedException;
import io.airlift.airline.ParseOptionMissingException;
import io.airlift.airline.ParseOptionMissingValueException;
@@ -26,30 +25,31 @@ import org.openapitools.codegen.cmd.*;
import java.util.Locale;
import static org.openapitools.codegen.Constants.CLI_NAME;
/**
* User: lanwen Date: 24.03.15 Time: 17:56
* <p>
* Command line interface for OpenAPI Generator use `openapi-generator-cli.jar help` for more info
*
* @since 2.1.3-M1
*/
public class OpenAPIGenerator {
public static void main(String[] args) {
String version = Version.readVersionFromResources();
Cli.CliBuilder<Runnable> builder =
Cli.<Runnable>builder("openapi-generator-cli")
BuildInfo buildInfo = new BuildInfo();
Cli.CliBuilder<OpenApiGeneratorCommand> builder =
Cli.<OpenApiGeneratorCommand>builder(CLI_NAME)
.withDescription(
String.format(
Locale.ROOT,
"OpenAPI generator CLI (version %s).",
version))
.withDefaultCommand(ListGenerators.class)
"OpenAPI Generator CLI %s (%s).",
buildInfo.getVersion(),
buildInfo.getSha()))
.withDefaultCommand(HelpCommand.class)
.withCommands(
ListGenerators.class,
Generate.class,
Meta.class,
Help.class,
HelpCommand.class,
ConfigHelp.class,
Validate.class,
Version.class,
@@ -60,7 +60,7 @@ public class OpenAPIGenerator {
try {
builder.build().parse(args).run();
// If CLI is run without a command, consider this an error. This exists after initial parse/run
// If CLI runs without a command, consider this an error. This exists after initial parse/run
// so we can present the configured "default command".
// We can check against empty args because unrecognized arguments/commands result in an exception.
// This is useful to exit with status 1, for example, so that misconfigured scripts fail fast.
@@ -71,10 +71,10 @@ public class OpenAPIGenerator {
System.exit(1);
}
} catch (ParseArgumentsUnexpectedException e) {
System.err.printf(Locale.ROOT,"[error] %s%n%nSee 'openapi-generator help' for usage.%n", e.getMessage());
System.err.printf(Locale.ROOT, "[error] %s%n%nSee '%s help' for usage.%n", e.getMessage(), CLI_NAME);
System.exit(1);
} catch (ParseOptionMissingException | ParseOptionMissingValueException e) {
System.err.printf(Locale.ROOT,"[error] %s%n", e.getMessage());
System.err.printf(Locale.ROOT, "[error] %s%n", e.getMessage());
System.exit(1);
}
}

View File

@@ -0,0 +1,90 @@
package org.openapitools.codegen.cmd;
import java.io.IOException;
import java.io.InputStream;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;
import java.util.Properties;
import static org.openapitools.codegen.Constants.*;
/**
* Presents build-time information
*/
@SuppressWarnings({"java:S108"})
public class BuildInfo {
private static final String VERSION_PLACEHOLDER = "${project.version}";
private static final String UNSET = "unset";
private static final String UNKNOWN = "unknown";
private static final Properties properties = new Properties();
static {
try (InputStream is = BuildInfo.class.getResourceAsStream("/version.properties")) {
Properties versionProps = new Properties();
versionProps.load(is);
properties.putAll(versionProps);
} catch (IOException ignored) {
}
try (InputStream is = BuildInfo.class.getResourceAsStream("/openapi-generator-git.properties")) {
Properties gitProps = new Properties();
gitProps.load(is);
properties.putAll(gitProps);
} catch (IOException ignored) {
}
}
/**
* Gets the version of the toolset.
*
* @return A semver string
*/
public String getVersion() {
String version = (String) properties.getOrDefault("version", UNKNOWN);
if (VERSION_PLACEHOLDER.equals(version)) {
return UNSET;
} else {
return version;
}
}
/**
* Gets the git commit SHA1 hash. Useful for differentiating between SNAPSHOT builds.
*
* @return A short git SHA
*/
public String getSha() {
return (String) properties.getOrDefault("git.commit.id.abbrev", UNKNOWN);
}
/**
* Gets the time when this tool was built.
*
* @return The time as {@link OffsetDateTime}, or {@link OffsetDateTime#MIN} if metadata cannot be parsed.
*/
public OffsetDateTime getBuildTime() {
try {
String time = (String) properties.getOrDefault("git.build.time", "");
return OffsetDateTime.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ROOT));
} catch (DateTimeParseException e) {
return OffsetDateTime.MIN;
}
}
/**
* Gets the full version display text, as one would expect from a '--version' CLI option
*
* @return Human-readable version display information
*/
public String versionDisplayText() {
StringBuilder sb = new StringBuilder(CLI_NAME);
sb.append(" ").append(this.getVersion()).append(System.lineSeparator());
sb.append(" commit : ").append(this.getSha()).append(System.lineSeparator());
sb.append(" built : ").append(this.getBuildTime().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)).append(System.lineSeparator());
sb.append(" source : ").append(GIT_REPO).append(System.lineSeparator());
sb.append(" docs : ").append(SITE).append(System.lineSeparator());
return sb.toString();
}
}

View File

@@ -36,8 +36,9 @@ import java.util.concurrent.Callable;
import static com.google.common.collect.Lists.newArrayList;
import static io.airlift.airline.ParserUtil.createInstance;
@SuppressWarnings({"java:S106"})
@Command(name = "completion", description = "Complete commands (for using in tooling such as Bash Completions).", hidden = true)
public class CompletionCommand
public class CompletionCommand extends OpenApiGeneratorCommand
implements Runnable, Callable<Void> {
private static final Map<Context, Class<? extends Suggester>> BUILTIN_SUGGESTERS = ImmutableMap.<Context, Class<? extends Suggester>>builder()
.put(Context.GLOBAL, GlobalSuggester.class)
@@ -95,7 +96,7 @@ public class CompletionCommand
}
@Override
public void run() {
void execute() {
System.out.println(Joiner.on("\n").join(generateSuggestions()));
}
}

View File

@@ -39,9 +39,9 @@ import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
import static org.apache.commons.lang3.StringUtils.isEmpty;
@SuppressWarnings("unused")
@SuppressWarnings({"unused","java:S106"})
@Command(name = "config-help", description = "Config help for chosen lang")
public class ConfigHelp implements Runnable {
public class ConfigHelp extends OpenApiGeneratorCommand {
private static final Logger LOGGER = LoggerFactory.getLogger(Generate.class);
@@ -91,7 +91,7 @@ public class ConfigHelp implements Runnable {
private String newline = System.lineSeparator();
@Override
public void run() {
public void execute() {
if (isEmpty(generatorName)) {
LOGGER.error("[error] A generator name (--generator-name / -g) is required.");
System.exit(1);
@@ -196,7 +196,7 @@ public class ConfigHelp implements Runnable {
sb.append("<dd>").append(escapeHtml4(entry.getValue())).append("</dd>");
}
sb.append("<dl>");
sb.append("</dl>");
} else {
sb.append(" ");
}
@@ -246,7 +246,7 @@ public class ConfigHelp implements Runnable {
if (Boolean.TRUE.equals(languageSpecificPrimitives)) {
sb.append(newline).append("## LANGUAGE PRIMITIVES").append(newline).append(newline);
sb.append("<ul data-columns=\"2\" style=\"list-style-type: disc;-webkit-columns:2;-moz-columns:2;columns:2;-moz-column-fill:auto;column-fill:auto\">");
sb.append("<ul class=\"column-ul\">").append(newline);
config.languageSpecificPrimitives()
.stream()
.sorted(String::compareTo)
@@ -257,7 +257,7 @@ public class ConfigHelp implements Runnable {
if (Boolean.TRUE.equals(reservedWords)) {
sb.append(newline).append("## RESERVED WORDS").append(newline).append(newline);
sb.append("<ul data-columns=\"2\" style=\"list-style-type: disc;-webkit-columns:2;-moz-columns:2;columns:2;-moz-column-fill:auto;column-fill:auto\">");
sb.append("<ul class=\"column-ul\">").append(newline);
config.reservedWords()
.stream()
.sorted(String::compareTo)
@@ -268,7 +268,7 @@ public class ConfigHelp implements Runnable {
if (Boolean.TRUE.equals(featureSets)) {
sb.append(newline).append("## FEATURE SET").append(newline).append(newline);
List<FeatureSet.FeatureSetFlattened> flattened = config.getFeatureSet().flatten();
List<FeatureSet.FeatureSetFlattened> flattened = config.getGeneratorMetadata().getFeatureSet().flatten();
flattened.sort(Comparator.comparing(FeatureSet.FeatureSetFlattened::getFeatureCategory));
AtomicReference<String> lastCategory = new AtomicReference<>();
@@ -320,6 +320,7 @@ public class ConfigHelp implements Runnable {
}
}
@SuppressWarnings({"java:S1117"})
private void generatePlainTextHelp(StringBuilder sb, CodegenConfig config) {
sb.append(newline).append("CONFIG OPTIONS");
if (Boolean.TRUE.equals(namedHeader)) {
@@ -385,7 +386,7 @@ public class ConfigHelp implements Runnable {
if (Boolean.TRUE.equals(featureSets)) {
sb.append(newline).append("FEATURE SET").append(newline);
List<FeatureSet.FeatureSetFlattened> flattened = config.getFeatureSet().flatten();
List<FeatureSet.FeatureSetFlattened> flattened = config.getGeneratorMetadata().getFeatureSet().flatten();
flattened.sort(Comparator.comparing(FeatureSet.FeatureSetFlattened::getFeatureCategory));
AtomicReference<String> lastCategory = new AtomicReference<>();
@@ -418,6 +419,7 @@ public class ConfigHelp implements Runnable {
}
}
@SuppressWarnings({"java:S1117"})
private void writePlainTextFromMap(
StringBuilder sb,
Map<String, String> map,
@@ -449,6 +451,7 @@ public class ConfigHelp implements Runnable {
}
}
@SuppressWarnings({"java:S1117"})
private void writePlainTextFromArray(StringBuilder sb, String[] arr, String optIndent) {
if (arr.length > 0) {
// target a width of 20, then take the max up to 40.

View File

@@ -34,8 +34,9 @@ import org.openapitools.codegen.config.CodegenConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"java:S106"})
@Command(name = "generate", description = "Generate code with the specified generator.")
public class Generate implements Runnable {
public class Generate extends OpenApiGeneratorCommand {
CodegenConfigurator configurator;
Generator generator;
@@ -70,20 +71,21 @@ public class Generate implements Runnable {
+ "Pass in a URL-encoded string of name:header with a comma separating multiple values")
private String auth;
// TODO: Remove -D short option in 5.0
@Option(
name = {"-D"},
title = "system properties",
description = "sets specified system properties in "
name = {"-D", "--global-property"},
title = "global properties",
description = "sets specified global properties (previously called 'system properties') in "
+ "the format of name=value,name=value (or multiple options, each with name=value)")
private List<String> systemProperties = new ArrayList<>();
private List<String> globalProperties = new ArrayList<>();
@Option(
name = {"-c", "--config"},
title = "configuration file",
description = "Path to configuration file configuration file. It can be json or yaml."
+ "If file is json, the content should have the format {\"optionKey\":\"optionValue\", \"optionKey1\":\"optionValue1\"...}."
+ "If file is yaml, the content should have the format optionKey: optionValue"
+ "Supported options can be different for each language. Run config-help -g {generator name} command for language specific config options.")
description = "Path to configuration file. It can be JSON or YAML. "
+ "If file is JSON, the content should have the format {\"optionKey\":\"optionValue\", \"optionKey1\":\"optionValue1\"...}. "
+ "If file is YAML, the content should have the format optionKey: optionValue. "
+ "Supported options can be different for each language. Run config-help -g {generator name} command for language-specific config options.")
private String configFile;
@Option(name = {"-s", "--skip-overwrite"}, title = "skip overwrite",
@@ -91,6 +93,9 @@ public class Generate implements Runnable {
+ "overwritten during the generation.")
private Boolean skipOverwrite;
@Option(name = { "--dry-run" }, title = "Dry run",
description = "Try things out and report on potential changes (without actually making changes).")
private Boolean isDryRun;
@Option(name = {"--package-name"}, title = "package name",
description = CodegenConstants.PACKAGE_NAME_DESC)
@@ -229,7 +234,7 @@ public class Generate implements Runnable {
+ " Useful for piping the JSON output of debug options (e.g. `-DdebugOperations`) to an external parser directly while testing a generator.")
private Boolean logToStderr;
@Option(name = {"--enable-post-process-file"}, title = "enable post-process file", description = CodegenConstants.ENABLE_POST_PROCESS_FILE)
@Option(name = {"--enable-post-process-file"}, title = "enable post-process file", description = CodegenConstants.ENABLE_POST_PROCESS_FILE_DESC)
private Boolean enablePostProcessFile;
@Option(name = {"--generate-alias-as-model"}, title = "generate alias (array, map) as model", description = CodegenConstants.GENERATE_ALIAS_AS_MODEL_DESC)
@@ -241,7 +246,7 @@ public class Generate implements Runnable {
private Boolean minimalUpdate;
@Override
public void run() {
public void execute() {
if (logToStderr != null) {
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
Stream.of(Logger.ROOT_LOGGER_NAME, "io.swagger", "org.openapitools")
@@ -399,9 +404,9 @@ public class Generate implements Runnable {
configurator.setStrictSpecBehavior(strictSpecBehavior);
}
if (systemProperties != null && !systemProperties.isEmpty()) {
System.err.println("[DEPRECATED] -D arguments after 'generate' are application arguments and not Java System Properties, please consider changing to -p, or apply your options to JAVA_OPTS, or move the -D arguments before the jar option.");
applySystemPropertiesKvpList(systemProperties, configurator);
if (globalProperties != null && !globalProperties.isEmpty()) {
System.err.println("[DEPRECATED] -D arguments after 'generate' are application arguments and not Java System Properties, please consider changing to --global-property, apply your system properties to JAVA_OPTS, or move the -D arguments before the jar option.");
applyGlobalPropertiesKvpList(globalProperties, configurator);
}
applyInstantiationTypesKvpList(instantiationTypes, configurator);
applyImportMappingsKvpList(importMappings, configurator);
@@ -416,7 +421,7 @@ public class Generate implements Runnable {
// this null check allows us to inject for unit testing.
if (generator == null) {
generator = new DefaultGenerator();
generator = new DefaultGenerator(isDryRun);
}
generator.opts(clientOptInput);

View File

@@ -50,9 +50,9 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection"})
@SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection", "java:S106"})
@Command(name = "batch", description = "Generate code in batch via external configs.", hidden = true)
public class GenerateBatch implements Runnable {
public class GenerateBatch extends OpenApiGeneratorCommand {
private static final Logger LOGGER = LoggerFactory.getLogger(GenerateBatch.class);
@@ -89,7 +89,7 @@ public class GenerateBatch implements Runnable {
* @see Thread#run()
*/
@Override
public void run() {
public void execute() {
if (configs.size() < 1) {
LOGGER.error("No configuration file inputs specified");
System.exit(1);

View File

@@ -0,0 +1,13 @@
package org.openapitools.codegen.cmd;
import io.airlift.airline.Option;
import static io.airlift.airline.OptionType.GLOBAL;
public class GlobalOptions {
@Option(type = GLOBAL, name = "--version", description = "Display full version output", hidden = true)
public boolean version;
@Option(type = GLOBAL, name = "--help", description = "Display help about the tool", hidden = true)
public boolean help;
}

View File

@@ -0,0 +1,18 @@
package org.openapitools.codegen.cmd;
import io.airlift.airline.Command;
import io.airlift.airline.Help;
import javax.inject.Inject;
@Command(name = "help", description = "Display help information about openapi-generator")
public class HelpCommand extends OpenApiGeneratorCommand {
@Inject
public Help help;
@Override
public void execute() {
help.call();
}
}

View File

@@ -16,8 +16,9 @@ import java.util.*;
import java.util.stream.Collectors;
// NOTE: List can later have subcommands such as list languages, list types, list frameworks, etc.
@SuppressWarnings({"java:S106"})
@Command(name = "list", description = "Lists the available generators")
public class ListGenerators implements Runnable {
public class ListGenerators extends OpenApiGeneratorCommand {
@Option(name = {"-s", "--short" }, description = "shortened output (suitable for scripting)")
private Boolean shortened = false;
@@ -34,7 +35,7 @@ public class ListGenerators implements Runnable {
private String include = "stable,beta,experimental";
@Override
public void run() {
public void execute() {
List<CodegenConfig> generators = new ArrayList<>();
List<Stability> stabilities = Arrays.asList(Stability.values());

View File

@@ -49,7 +49,7 @@ import ch.lambdaj.function.convert.Converter;
@Command(name = "meta", description = "MetaGenerator. Generator for creating a new template set "
+ "and configuration for Codegen. The output will be based on the language you "
+ "specify, and includes default templates to include.")
public class Meta implements Runnable {
public class Meta extends OpenApiGeneratorCommand {
private static final Logger LOGGER = LoggerFactory.getLogger(Meta.class);
@@ -80,7 +80,7 @@ public class Meta implements Runnable {
private String language = "java";
@Override
public void run() {
public void execute() {
final File targetDir = new File(outputFolder);
LOGGER.info("writing to folder [{}]", targetDir.getAbsolutePath());
@@ -110,7 +110,7 @@ public class Meta implements Runnable {
new SupportingFile("myFile.template", String.join(File.separator, "src", "main", "resources", name), "myFile.mustache"),
new SupportingFile("services.mustache", "src/main/resources/META-INF/services", CodegenConfig.class.getCanonicalName()));
String currentVersion = Version.readVersionFromResources();
String currentVersion = buildInfo.getVersion();
Map<String, Object> data =
new ImmutableMap.Builder<String, Object>()

View File

@@ -0,0 +1,39 @@
package org.openapitools.codegen.cmd;
import io.airlift.airline.Help;
import io.airlift.airline.model.GlobalMetadata;
import javax.inject.Inject;
@SuppressWarnings({"java:S106"})
public abstract class OpenApiGeneratorCommand implements Runnable {
@Inject
public GlobalOptions globalOptions = new GlobalOptions();
@Inject
public GlobalMetadata global;
protected BuildInfo buildInfo = new BuildInfo();
@Override
public void run() {
if (globalOptions.version) {
System.out.println(buildInfo.versionDisplayText());
return;
}
if (globalOptions.help) {
Help help = new Help();
help.global = global;
help.call();
return;
}
execute();
}
/**
* Logic to be executed by implementing commands
*/
abstract void execute();
}

View File

@@ -22,6 +22,7 @@ import io.airlift.airline.Option;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.core.models.ParseOptions;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import org.apache.commons.lang3.text.WordUtils;
import org.openapitools.codegen.validation.ValidationResult;
@@ -32,8 +33,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
@SuppressWarnings({"unused","java:S106"})
@Command(name = "validate", description = "Validate specification")
public class Validate implements Runnable {
public class Validate extends OpenApiGeneratorCommand {
@Option(name = {"-i", "--input-spec"}, title = "spec file", required = true,
description = "location of the OpenAPI spec, as URL or file (required)")
@@ -43,10 +45,11 @@ public class Validate implements Runnable {
private Boolean recommend;
@Override
public void run() {
public void execute() {
System.out.println("Validating spec (" + spec + ")");
SwaggerParseResult result = new OpenAPIParser().readLocation(spec, null, null);
ParseOptions options = new ParseOptions();
options.setResolve(true);
SwaggerParseResult result = new OpenAPIParser().readLocation(spec, null, options);
List<String> messageList = result.getMessages();
Set<String> errors = new HashSet<>(messageList);
Set<String> warnings = new HashSet<>();
@@ -55,7 +58,9 @@ public class Validate implements Runnable {
OpenAPI specification = result.getOpenAPI();
RuleConfiguration ruleConfiguration = new RuleConfiguration();
ruleConfiguration.setEnableRecommendations(recommend != null ? recommend : false);
if (recommend != null) ruleConfiguration.setEnableRecommendations(recommend);
else ruleConfiguration.setEnableRecommendations(false);
OpenApiEvaluator evaluator = new OpenApiEvaluator(ruleConfiguration);
ValidationResult validationResult = evaluator.validate(specification);

View File

@@ -17,45 +17,30 @@
package org.openapitools.codegen.cmd;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import io.airlift.airline.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.airlift.airline.Option;
@Command(name = "version", description = "Show version information")
public class Version implements Runnable {
@SuppressWarnings({"unused", "java:S106"})
@Command(name = "version", description = "Show version information used in tooling")
public class Version extends OpenApiGeneratorCommand {
private static final Logger LOGGER = LoggerFactory.getLogger(Meta.class);
@Option(name = {"--sha"}, description = "Git commit SHA version")
private Boolean sha;
private static final String VERSION_PLACEHOLDER = "${project.version}";
private static final String UNREADABLE_VERSION = "unreadable";
private static final String UNSET_VERSION = "unset";
private static final String UNKNOWN_VERSION = "unknown";
public static String readVersionFromResources() {
Properties versionProperties = new Properties();
try (InputStream is = Version.class.getResourceAsStream("/version.properties")) {
versionProperties.load(is);
} catch (IOException ex) {
LOGGER.error("Error loading version properties", ex);
return UNREADABLE_VERSION;
}
String version = versionProperties.getProperty("version", UNKNOWN_VERSION).trim();
if (VERSION_PLACEHOLDER.equals(version)) {
return UNSET_VERSION;
} else {
return version;
}
}
@Option(name = {"--full"}, description = "Full version details")
private Boolean full;
@Override
public void run() {
String version = readVersionFromResources();
public void execute() {
String version;
if (Boolean.TRUE.equals(full)) {
version = buildInfo.versionDisplayText();
} else if (Boolean.TRUE.equals(sha)) {
version = buildInfo.getSha();
} else {
version = buildInfo.getVersion();
}
System.out.println(version);
}

View File

@@ -53,16 +53,6 @@
<level>ERROR</level>
</filter>
</appender>
<appender name="ONCELOGGER_COLOR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<withJansi>true</withJansi>
<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>ONCE</marker>
</evaluator>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>[%thread] %highlight(%-5level) %logger{36} - %red(%msg)%n</pattern>
</encoder>
</appender>
<logger name="io.swagger" level="warn">
<!-- Colorize by passing -Dcolor -->