Avoid certgen status logger error message

Today when running the certgen command, an error message is output by
the status logger. This is due to a logger instance being created before
logging is configured. This happens because the class initializer for
CertificateTool runs the class initializer for ParseField which creates
a deprecation logger which creates a logger. This commit fixes this
issue by wrapping the parser in another class so that we can defer class
initialization until it's actually needed, thus deferring creating the
logger instance until after logging is initialized.

Relates elastic/elasticsearch#4831

Original commit: elastic/x-pack-elasticsearch@00f978c878
This commit is contained in:
Jason Tedor 2017-02-04 16:07:36 -05:00 committed by GitHub
parent 6675f6bc8d
commit 65ddba8585
1 changed files with 22 additions and 12 deletions

View File

@ -74,18 +74,28 @@ public class CertificateTool extends EnvironmentAwareCommand {
Pattern.compile("[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1," + MAX_FILENAME_LENGTH + "}");
private static final int DEFAULT_KEY_SIZE = 2048;
private static final ObjectParser<List<CertificateInformation>, Void> PARSER = new ObjectParser<>("certgen");
static {
ConstructingObjectParser<CertificateInformation, Void> instanceParser =
new ConstructingObjectParser<>("instances",
a -> new CertificateInformation((String) a[0], (String) (a[1] == null ? a[0] : a[1]),
(List<String>) a[2], (List<String>) a[3]));
instanceParser.declareString(ConstructingObjectParser.constructorArg(), new ParseField("name"));
instanceParser.declareString(ConstructingObjectParser.optionalConstructorArg(), new ParseField("filename"));
instanceParser.declareStringArray(ConstructingObjectParser.optionalConstructorArg(), new ParseField("ip"));
instanceParser.declareStringArray(ConstructingObjectParser.optionalConstructorArg(), new ParseField("dns"));
/**
* Wraps the certgen object parser.
*/
private static class CertificateToolParser {
private static final ObjectParser<List<CertificateInformation>, Void> PARSER = new ObjectParser<>("certgen");
PARSER.declareObjectArray(List::addAll, instanceParser, new ParseField("instances"));
// if the class initializer here runs before the main method, logging will not have been configured; this will lead to status logger
// error messages from the class initializer for ParseField since it creates Logger instances; therefore, we bury the initialization
// of the parser in this class so that we can defer initialization until after logging has been initialized
static {
@SuppressWarnings("unchecked") final ConstructingObjectParser<CertificateInformation, Void> instanceParser =
new ConstructingObjectParser<>(
"instances",
a -> new CertificateInformation(
(String) a[0], (String) (a[1] == null ? a[0] : a[1]), (List<String>) a[2], (List<String>) a[3]));
instanceParser.declareString(ConstructingObjectParser.constructorArg(), new ParseField("name"));
instanceParser.declareString(ConstructingObjectParser.optionalConstructorArg(), new ParseField("filename"));
instanceParser.declareStringArray(ConstructingObjectParser.optionalConstructorArg(), new ParseField("ip"));
instanceParser.declareStringArray(ConstructingObjectParser.optionalConstructorArg(), new ParseField("dns"));
PARSER.declareObjectArray(List::addAll, instanceParser, new ParseField("instances"));
}
}
private final OptionSpec<String> outputPathSpec;
@ -242,7 +252,7 @@ public class CertificateTool extends EnvironmentAwareCommand {
try (Reader reader = Files.newBufferedReader(file)) {
// EMPTY is safe here because we never use namedObject
XContentParser xContentParser = XContentType.YAML.xContent().createParser(NamedXContentRegistry.EMPTY, reader);
return PARSER.parse(xContentParser, new ArrayList<>(), null);
return CertificateToolParser.PARSER.parse(xContentParser, new ArrayList<>(), null);
}
}