Factor UnknownNamedObjectException into its own class (#28931)

* 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
This commit is contained in:
Lee Hinman 2018-03-08 15:32:41 -07:00 committed by GitHub
parent 7d434c16f9
commit 697f3f1a3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 83 additions and 59 deletions

View File

@ -984,8 +984,8 @@ public class ElasticsearchException extends RuntimeException implements ToXConte
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(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);

View File

@ -43,7 +43,7 @@ import org.elasticsearch.common.regex.Regex;
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;

View File

@ -23,8 +23,6 @@ import org.elasticsearch.ElasticsearchException;
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 java.util.Objects;
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 class NamedXContentRegistry {
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;
}
}
}

View File

@ -0,0 +1,74 @@
/*
* 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;
}
}

View File

@ -22,7 +22,6 @@ package org.elasticsearch.common.xcontent.yaml;
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.io.FastStringReader;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
@ -66,7 +65,7 @@ public class YamlXContent implements XContent {
@Override
public byte streamSeparator() {
throw new ElasticsearchParseException("yaml does not support stream parsing...");
throw new UnsupportedOperationException("yaml does not support stream parsing...");
}
@Override

View File

@ -31,7 +31,7 @@ import org.elasticsearch.common.io.stream.StreamInput;
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;

View File

@ -53,6 +53,7 @@ import org.elasticsearch.common.transport.TransportAddress;
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 class ExceptionSerializationTests extends ESTestCase {
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<Class<? extends ElasticsearchException>, Integer> reverse = new HashMap<>();

View File

@ -1023,7 +1023,7 @@ public abstract class BaseXContentTestCase extends ESTestCase {
{
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());

View File

@ -21,7 +21,6 @@ package org.elasticsearch.common.xcontent;
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;

View File

@ -187,7 +187,7 @@ public class XContentParserUtilsTests extends ESTestCase {
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());