From 9532953d0e80f43b254b15780e5bda226a5a7925 Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Wed, 7 Mar 2018 14:18:01 -0700 Subject: [PATCH 1/2] Factor UnknownNamedObjectException into its own class This moves the inner class `UnknownNamedObjectException` from `NamedXContentRegistry` into a top-level class. This is so that `NamedXContentRegistry` doesn't have to depend on StreamInput and StreamOutput. Relates to #28504 --- .../elasticsearch/ElasticsearchException.java | 5 +- .../cluster/metadata/MetaData.java | 2 +- .../xcontent/NamedXContentRegistry.java | 49 ------------ .../xcontent/UnknownNamedObjectException.java | 75 +++++++++++++++++++ .../common/xcontent/yaml/YamlXContent.java | 3 +- .../index/query/AbstractQueryBuilder.java | 2 +- .../ExceptionSerializationTests.java | 3 +- .../common/xcontent/BaseXContentTestCase.java | 2 +- .../UnknownNamedObjectExceptionTests.java | 1 - .../xcontent/XContentParserUtilsTests.java | 2 +- 10 files changed, 85 insertions(+), 59 deletions(-) create mode 100644 server/src/main/java/org/elasticsearch/common/xcontent/UnknownNamedObjectException.java diff --git a/server/src/main/java/org/elasticsearch/ElasticsearchException.java b/server/src/main/java/org/elasticsearch/ElasticsearchException.java index ab50824f59a4f..7399924384a14 100644 --- a/server/src/main/java/org/elasticsearch/ElasticsearchException.java +++ b/server/src/main/java/org/elasticsearch/ElasticsearchException.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.logging.LoggerMessageFormat; import org.elasticsearch.common.xcontent.ToXContentFragment; +import org.elasticsearch.common.xcontent.UnknownNamedObjectException; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.Index; @@ -984,8 +985,8 @@ private enum ElasticsearchExceptionHandle { org.elasticsearch.tasks.TaskCancelledException::new, 146, Version.V_5_1_1), SHARD_LOCK_OBTAIN_FAILED_EXCEPTION(org.elasticsearch.env.ShardLockObtainFailedException.class, org.elasticsearch.env.ShardLockObtainFailedException::new, 147, Version.V_5_0_2), - UNKNOWN_NAMED_OBJECT_EXCEPTION(org.elasticsearch.common.xcontent.NamedXContentRegistry.UnknownNamedObjectException.class, - org.elasticsearch.common.xcontent.NamedXContentRegistry.UnknownNamedObjectException::new, 148, Version.V_5_2_0), + UNKNOWN_NAMED_OBJECT_EXCEPTION(UnknownNamedObjectException.class, + UnknownNamedObjectException::new, 148, Version.V_5_2_0), TOO_MANY_BUCKETS_EXCEPTION(MultiBucketConsumerService.TooManyBucketsException.class, MultiBucketConsumerService.TooManyBucketsException::new, 149, Version.V_7_0_0_alpha1); diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java b/server/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java index 8c6829ca78734..06aa51f612bcc 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java @@ -43,7 +43,7 @@ import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.NamedXContentRegistry.UnknownNamedObjectException; +import org.elasticsearch.common.xcontent.UnknownNamedObjectException; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContentFragment; import org.elasticsearch.common.xcontent.XContentBuilder; diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/NamedXContentRegistry.java b/server/src/main/java/org/elasticsearch/common/xcontent/NamedXContentRegistry.java index 4fb397dbe1751..c19a667776f2e 100644 --- a/server/src/main/java/org/elasticsearch/common/xcontent/NamedXContentRegistry.java +++ b/server/src/main/java/org/elasticsearch/common/xcontent/NamedXContentRegistry.java @@ -23,8 +23,6 @@ import org.elasticsearch.common.CheckedFunction; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParsingException; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; import java.io.IOException; import java.util.ArrayList; @@ -36,7 +34,6 @@ import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static java.util.Collections.unmodifiableMap; -import static java.util.Objects.requireNonNull; public class NamedXContentRegistry { /** @@ -143,50 +140,4 @@ public T parseNamedObject(Class categoryClass, String name, XContentPa return categoryClass.cast(entry.parser.parse(parser, context)); } - /** - * Thrown when {@link NamedXContentRegistry#parseNamedObject(Class, String, XContentParser, Object)} is called with an unregistered - * name. When this bubbles up to the rest layer it is converted into a response with {@code 400 BAD REQUEST} status. - */ - public static class UnknownNamedObjectException extends ParsingException { - private final String categoryClass; - private final String name; - - public UnknownNamedObjectException(XContentLocation contentLocation, Class categoryClass, - String name) { - super(contentLocation, "Unknown " + categoryClass.getSimpleName() + " [" + name + "]"); - this.categoryClass = requireNonNull(categoryClass, "categoryClass is required").getName(); - this.name = requireNonNull(name, "name is required"); - } - - /** - * Read from a stream. - */ - public UnknownNamedObjectException(StreamInput in) throws IOException { - super(in); - categoryClass = in.readString(); - name = in.readString(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(categoryClass); - out.writeString(name); - } - - /** - * Category class that was missing a parser. This is a String instead of a class because the class might not be on the classpath - * of all nodes or it might be exclusive to a plugin or something. - */ - public String getCategoryClass() { - return categoryClass; - } - - /** - * Name of the missing parser. - */ - public String getName() { - return name; - } - } } diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/UnknownNamedObjectException.java b/server/src/main/java/org/elasticsearch/common/xcontent/UnknownNamedObjectException.java new file mode 100644 index 0000000000000..bbba6221c45ec --- /dev/null +++ b/server/src/main/java/org/elasticsearch/common/xcontent/UnknownNamedObjectException.java @@ -0,0 +1,75 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.common.xcontent; + +import org.elasticsearch.common.ParsingException; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; + +import java.io.IOException; + +import static java.util.Objects.requireNonNull; + +/** + * Thrown when {@link NamedXContentRegistry#parseNamedObject(Class, String, XContentParser, Object)} is called with an unregistered + * name. When this bubbles up to the rest layer it is converted into a response with {@code 400 BAD REQUEST} status. + */ +public class UnknownNamedObjectException extends ParsingException { + private final String categoryClass; + private final String name; + + public UnknownNamedObjectException(XContentLocation contentLocation, Class categoryClass, + String name) { + super(contentLocation, "Unknown " + categoryClass.getSimpleName() + " [" + name + "]"); + this.categoryClass = requireNonNull(categoryClass, "categoryClass is required").getName(); + this.name = requireNonNull(name, "name is required"); + } + + /** + * Read from a stream. + */ + public UnknownNamedObjectException(StreamInput in) throws IOException { + super(in); + categoryClass = in.readString(); + name = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(categoryClass); + out.writeString(name); + } + + /** + * Category class that was missing a parser. This is a String instead of a class because the class might not be on the classpath + * of all nodes or it might be exclusive to a plugin or something. + */ + public String getCategoryClass() { + return categoryClass; + } + + /** + * Name of the missing parser. + */ + public String getName() { + return name; + } +} diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/yaml/YamlXContent.java b/server/src/main/java/org/elasticsearch/common/xcontent/yaml/YamlXContent.java index 3547440eb8b32..28d4594052daa 100644 --- a/server/src/main/java/org/elasticsearch/common/xcontent/yaml/YamlXContent.java +++ b/server/src/main/java/org/elasticsearch/common/xcontent/yaml/YamlXContent.java @@ -22,7 +22,6 @@ import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.FastStringReader; import org.elasticsearch.common.xcontent.DeprecationHandler; @@ -67,7 +66,7 @@ public XContentType type() { @Override public byte streamSeparator() { - throw new ElasticsearchParseException("yaml does not support stream parsing..."); + throw new UnsupportedOperationException("yaml does not support stream parsing..."); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java b/server/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java index d1337d5258aa9..d272bb29fbfa6 100644 --- a/server/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java +++ b/server/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java @@ -31,7 +31,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.xcontent.AbstractObjectParser; -import org.elasticsearch.common.xcontent.NamedXContentRegistry.UnknownNamedObjectException; +import org.elasticsearch.common.xcontent.UnknownNamedObjectException; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentLocation; import org.elasticsearch.common.xcontent.XContentParser; diff --git a/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java b/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java index d4864867902d2..b794ded7f8d03 100644 --- a/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java +++ b/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java @@ -53,6 +53,7 @@ import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.util.CancellableThreadsTests; import org.elasticsearch.common.util.set.Sets; +import org.elasticsearch.common.xcontent.UnknownNamedObjectException; import org.elasticsearch.common.xcontent.XContentLocation; import org.elasticsearch.discovery.DiscoverySettings; import org.elasticsearch.env.ShardLockObtainFailedException; @@ -813,7 +814,7 @@ public void testIds() { ids.put(145, org.elasticsearch.ElasticsearchStatusException.class); ids.put(146, org.elasticsearch.tasks.TaskCancelledException.class); ids.put(147, org.elasticsearch.env.ShardLockObtainFailedException.class); - ids.put(148, org.elasticsearch.common.xcontent.NamedXContentRegistry.UnknownNamedObjectException.class); + ids.put(148, UnknownNamedObjectException.class); ids.put(149, MultiBucketConsumerService.TooManyBucketsException.class); Map, Integer> reverse = new HashMap<>(); diff --git a/server/src/test/java/org/elasticsearch/common/xcontent/BaseXContentTestCase.java b/server/src/test/java/org/elasticsearch/common/xcontent/BaseXContentTestCase.java index 609c12fb6d874..dbb47764158c9 100644 --- a/server/src/test/java/org/elasticsearch/common/xcontent/BaseXContentTestCase.java +++ b/server/src/test/java/org/elasticsearch/common/xcontent/BaseXContentTestCase.java @@ -1023,7 +1023,7 @@ public void testNamedObject() throws IOException { { p.nextToken(); assertEquals("test", p.namedObject(Object.class, "str", null)); - NamedXContentRegistry.UnknownNamedObjectException e = expectThrows(NamedXContentRegistry.UnknownNamedObjectException.class, + UnknownNamedObjectException e = expectThrows(UnknownNamedObjectException.class, () -> p.namedObject(Object.class, "unknown", null)); assertEquals("Unknown Object [unknown]", e.getMessage()); assertEquals("java.lang.Object", e.getCategoryClass()); diff --git a/server/src/test/java/org/elasticsearch/common/xcontent/UnknownNamedObjectExceptionTests.java b/server/src/test/java/org/elasticsearch/common/xcontent/UnknownNamedObjectExceptionTests.java index 4fcc16416b56f..c623e4a196b50 100644 --- a/server/src/test/java/org/elasticsearch/common/xcontent/UnknownNamedObjectExceptionTests.java +++ b/server/src/test/java/org/elasticsearch/common/xcontent/UnknownNamedObjectExceptionTests.java @@ -21,7 +21,6 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.xcontent.NamedXContentRegistry.UnknownNamedObjectException; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ESTestCase; diff --git a/server/src/test/java/org/elasticsearch/common/xcontent/XContentParserUtilsTests.java b/server/src/test/java/org/elasticsearch/common/xcontent/XContentParserUtilsTests.java index f550e26024d06..e31a1ce72025c 100644 --- a/server/src/test/java/org/elasticsearch/common/xcontent/XContentParserUtilsTests.java +++ b/server/src/test/java/org/elasticsearch/common/xcontent/XContentParserUtilsTests.java @@ -187,7 +187,7 @@ public void testParseTypedKeysObject() throws IOException { ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation); ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.nextToken(), parser::getTokenLocation); ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation); - NamedXContentRegistry.UnknownNamedObjectException e = expectThrows(NamedXContentRegistry.UnknownNamedObjectException.class, + UnknownNamedObjectException e = expectThrows(UnknownNamedObjectException.class, () -> parseTypedKeysObject(parser, delimiter, Boolean.class, a -> {})); assertEquals("Unknown Boolean [type]", e.getMessage()); assertEquals("type", e.getName()); From 6132f28001c6a0fba41e7e3363a36131745355df Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Thu, 8 Mar 2018 09:50:15 -0700 Subject: [PATCH 2/2] Use fq name and un-newline line --- .../main/java/org/elasticsearch/ElasticsearchException.java | 5 ++--- .../common/xcontent/UnknownNamedObjectException.java | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/ElasticsearchException.java b/server/src/main/java/org/elasticsearch/ElasticsearchException.java index 7399924384a14..ed20f52754dd4 100644 --- a/server/src/main/java/org/elasticsearch/ElasticsearchException.java +++ b/server/src/main/java/org/elasticsearch/ElasticsearchException.java @@ -29,7 +29,6 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.logging.LoggerMessageFormat; import org.elasticsearch.common.xcontent.ToXContentFragment; -import org.elasticsearch.common.xcontent.UnknownNamedObjectException; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.Index; @@ -985,8 +984,8 @@ private enum ElasticsearchExceptionHandle { org.elasticsearch.tasks.TaskCancelledException::new, 146, Version.V_5_1_1), SHARD_LOCK_OBTAIN_FAILED_EXCEPTION(org.elasticsearch.env.ShardLockObtainFailedException.class, org.elasticsearch.env.ShardLockObtainFailedException::new, 147, Version.V_5_0_2), - UNKNOWN_NAMED_OBJECT_EXCEPTION(UnknownNamedObjectException.class, - UnknownNamedObjectException::new, 148, Version.V_5_2_0), + UNKNOWN_NAMED_OBJECT_EXCEPTION(org.elasticsearch.common.xcontent.UnknownNamedObjectException.class, + org.elasticsearch.common.xcontent.UnknownNamedObjectException::new, 148, Version.V_5_2_0), TOO_MANY_BUCKETS_EXCEPTION(MultiBucketConsumerService.TooManyBucketsException.class, MultiBucketConsumerService.TooManyBucketsException::new, 149, Version.V_7_0_0_alpha1); diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/UnknownNamedObjectException.java b/server/src/main/java/org/elasticsearch/common/xcontent/UnknownNamedObjectException.java index bbba6221c45ec..0475ab334d388 100644 --- a/server/src/main/java/org/elasticsearch/common/xcontent/UnknownNamedObjectException.java +++ b/server/src/main/java/org/elasticsearch/common/xcontent/UnknownNamedObjectException.java @@ -35,8 +35,7 @@ public class UnknownNamedObjectException extends ParsingException { private final String categoryClass; private final String name; - public UnknownNamedObjectException(XContentLocation contentLocation, Class categoryClass, - String name) { + public UnknownNamedObjectException(XContentLocation contentLocation, Class categoryClass, String name) { super(contentLocation, "Unknown " + categoryClass.getSimpleName() + " [" + name + "]"); this.categoryClass = requireNonNull(categoryClass, "categoryClass is required").getName(); this.name = requireNonNull(name, "name is required");