/*
* 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;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParseException;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.apache.lucene.util.Constants;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.RoutingMissingException;
import org.elasticsearch.action.TimestampParsingException;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.client.AbstractClientHeadersTestCase;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.metadata.SnapshotId;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.*;
import org.elasticsearch.common.breaker.CircuitBreakingException;
import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.util.CancellableThreadsTests;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentLocation;
import org.elasticsearch.discovery.DiscoverySettings;
import org.elasticsearch.index.AlreadyExpiredException;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.engine.CreateFailedEngineException;
import org.elasticsearch.index.engine.IndexFailedEngineException;
import org.elasticsearch.index.engine.RecoveryEngineException;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.query.QueryParsingException;
import org.elasticsearch.index.shard.IllegalIndexShardStateException;
import org.elasticsearch.index.shard.IndexShardState;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.shard.TranslogRecoveryPerformer;
import org.elasticsearch.indices.IndexTemplateAlreadyExistsException;
import org.elasticsearch.indices.IndexTemplateMissingException;
import org.elasticsearch.indices.InvalidIndexTemplateException;
import org.elasticsearch.indices.recovery.RecoverFilesRecoveryException;
import org.elasticsearch.percolator.PercolateException;
import org.elasticsearch.repositories.RepositoryException;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.admin.indices.alias.delete.AliasesNotFoundException;
import org.elasticsearch.search.SearchContextMissingException;
import org.elasticsearch.search.SearchException;
import org.elasticsearch.search.SearchParseException;
import org.elasticsearch.search.SearchShardTarget;
import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.search.warmer.IndexWarmerMissingException;
import org.elasticsearch.snapshots.SnapshotException;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.TestSearchContext;
import org.elasticsearch.test.VersionUtils;
import org.elasticsearch.test.hamcrest.ElasticsearchAssertions;
import org.elasticsearch.transport.ActionNotFoundTransportException;
import org.elasticsearch.transport.ActionTransportException;
import org.elasticsearch.transport.ConnectTransportException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class ExceptionSerializationTests extends ESTestCase {
public void testExceptionRegistration()
throws ClassNotFoundException, IOException, URISyntaxException {
final Set<Class> notRegistered = new HashSet<>();
final Set<Class> hasDedicatedWrite = new HashSet<>();
final Set<Class> registered = new HashSet<>();
final String path = "/org/elasticsearch";
final Path startPath = PathUtils.get(ElasticsearchException.class.getProtectionDomain().getCodeSource().getLocation().toURI()).resolve("org").resolve("elasticsearch");
final Set<? extends Class> ignore = Sets.newHashSet(
org.elasticsearch.test.rest.parser.RestTestParseException.class,
org.elasticsearch.index.query.TestQueryParsingException.class,
org.elasticsearch.test.rest.client.RestException.class,
CancellableThreadsTests.CustomException.class,
org.elasticsearch.rest.BytesRestResponseTests.WithHeadersException.class,
AbstractClientHeadersTestCase.InternalException.class);
FileVisitor<Path> visitor = new FileVisitor<Path>() {
private Path pkgPrefix = PathUtils.get(path).getParent();
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
Path next = pkgPrefix.resolve(dir.getFileName());
if (ignore.contains(next)) {
return FileVisitResult.SKIP_SUBTREE;
}
pkgPrefix = next;
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
try {
String filename = file.getFileName().toString();
if (filename.endsWith(".class")) {
Class<?> clazz = loadClass(filename);
if (ignore.contains(clazz) == false) {
if (Modifier.isAbstract(clazz.getModifiers()) == false && Modifier.isInterface(clazz.getModifiers()) == false && isEsException(clazz)) {
if (ElasticsearchException.isRegistered((Class<? extends Throwable>)clazz) == false && ElasticsearchException.class.equals(clazz.getEnclosingClass()) == false) {
notRegistered.add(clazz);
} else if (ElasticsearchException.isRegistered((Class<? extends Throwable>)clazz)) {
registered.add(clazz);
try {
if (clazz.getDeclaredMethod("writeTo", StreamOutput.class) != null) {
hasDedicatedWrite.add(clazz);
}
} catch (Exception e) {
// fair enough
}
}
}
}
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return FileVisitResult.CONTINUE;
}
private boolean isEsException(Class<?> clazz) {
return ElasticsearchException.class.isAssignableFrom(clazz);
}
private Class<?> loadClass(String filename) throws ClassNotFoundException {
StringBuilder pkg = new StringBuilder();
for (Path p : pkgPrefix) {
pkg.append(p.getFileName().toString()).append(".");
}
pkg.append(filename.substring(0, filename.length() - 6));
return getClass().getClassLoader().loadClass(pkg.toString());
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
throw exc;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
pkgPrefix = pkgPrefix.getParent();
return FileVisitResult.CONTINUE;
}
};
Files.walkFileTree(startPath, visitor);
final Path testStartPath = PathUtils.get(ExceptionSerializationTests.class.getResource(path).toURI());
Files.walkFileTree(testStartPath, visitor);
assertTrue(notRegistered.remove(TestException.class));
assertTrue(notRegistered.remove(UnknownHeaderException.class));
assertTrue("Classes subclassing ElasticsearchException must be registered \n" + notRegistered.toString(),
notRegistered.isEmpty());
assertTrue(registered.removeAll(ElasticsearchException.getRegisteredKeys())); // check
assertEquals(registered.toString(), 0, registered.size());
}
public static final class TestException extends ElasticsearchException {
public TestException(StreamInput in) throws IOException{
super(in);
}
}
private <T extends Throwable> T serialize(T exception) throws IOException {
ElasticsearchAssertions.assertVersionSerializable(VersionUtils.randomVersion(random()), exception);
BytesStreamOutput out = new BytesStreamOutput();
out.writeThrowable(exception);
StreamInput in = StreamInput.wrap(out.bytes());
return in.readThrowable();
}
public void testIllegalShardRoutingStateException() throws IOException {
final ShardRouting routing = TestShardRouting.newShardRouting("test", 0, "xyz", "def", false, ShardRoutingState.STARTED, 0);
final String routingAsString = routing.toString();
IllegalShardRoutingStateException serialize = serialize(new IllegalShardRoutingStateException(routing, "foo", new NullPointerException()));
assertNotNull(serialize.shard());
assertEquals(routing, serialize.shard());
assertEquals(routingAsString + ": foo", serialize.getMessage());
assertTrue(serialize.getCause() instanceof NullPointerException);
serialize = serialize(new IllegalShardRoutingStateException(routing, "bar", null));
assertNotNull(serialize.shard());
assertEquals(routing, serialize.shard());
assertEquals(routingAsString + ": bar", serialize.getMessage());
assertNull(serialize.getCause());
}
public void testQueryParsingException() throws IOException {
QueryParsingException ex = serialize(new QueryParsingException(new Index("foo"), 1, 2, "fobar", null));
assertEquals(ex.getIndex(), "foo");
assertEquals(ex.getMessage(), "fobar");
assertEquals(ex.getLineNumber(),1);
assertEquals(ex.getColumnNumber(), 2);
ex = serialize(new QueryParsingException(null, 1, 2, null, null));
assertNull(ex.getIndex());
assertNull(ex.getMessage());
assertEquals(ex.getLineNumber(), 1);
assertEquals(ex.getColumnNumber(), 2);
}
public void testSearchException() throws IOException {
SearchShardTarget target = new SearchShardTarget("foo", "bar", 1);
SearchException ex = serialize(new SearchException(target, "hello world"));
assertEquals(target, ex.shard());
assertEquals(ex.getMessage(), "hello world");
ex = serialize(new SearchException(null, "hello world", new NullPointerException()));
assertNull(ex.shard());
assertEquals(ex.getMessage(), "hello world");
assertTrue(ex.getCause() instanceof NullPointerException);
}
public void testAlreadyExpiredException() throws IOException {
AlreadyExpiredException alreadyExpiredException = serialize(new AlreadyExpiredException("index", "type", "id", 1, 2, 3));
assertEquals("index", alreadyExpiredException.getIndex());
assertEquals("type", alreadyExpiredException.type());
assertEquals("id", alreadyExpiredException.id());
assertEquals(2, alreadyExpiredException.ttl());
assertEquals(1, alreadyExpiredException.timestamp());
assertEquals(3, alreadyExpiredException.now());
alreadyExpiredException = serialize(new AlreadyExpiredException(null, null, null, -1, -2, -3));
assertNull(alreadyExpiredException.getIndex());
assertNull(alreadyExpiredException.type());
assertNull(alreadyExpiredException.id());
assertEquals(-2, alreadyExpiredException.ttl());
assertEquals(-1, alreadyExpiredException.timestamp());
assertEquals(-3, alreadyExpiredException.now());
}
public void testCreateFailedEngineException() throws IOException {
CreateFailedEngineException ex = serialize(new CreateFailedEngineException(new ShardId("idx", 2), "type", "id", null));
assertEquals(ex.getShardId(), new ShardId("idx", 2));
assertEquals("type", ex.type());
assertEquals("id", ex.id());
assertNull(ex.getCause());
ex = serialize(new CreateFailedEngineException(null, "type", "id", new NullPointerException()));
assertNull(ex.getShardId());
assertEquals("type", ex.type());
assertEquals("id", ex.id());
assertTrue(ex.getCause() instanceof NullPointerException);
}
public void testMergeMappingException() throws IOException {
MergeMappingException ex = serialize(new MergeMappingException(new String[] {"one", "two"}));
assertArrayEquals(ex.failures(), new String[]{"one", "two"});
}
public void testActionNotFoundTransportException() throws IOException {
ActionNotFoundTransportException ex = serialize(new ActionNotFoundTransportException("AACCCTION"));
assertEquals("AACCCTION", ex.action());
assertEquals("No handler for action [AACCCTION]", ex.getMessage());
}
public void testSnapshotException() throws IOException {
SnapshotException ex = serialize(new SnapshotException(new SnapshotId("repo", "snap"), "no such snapshot", new NullPointerException()));
assertEquals(ex.snapshot(), new SnapshotId("repo", "snap"));
assertEquals(ex.getMessage(), "[repo:snap] no such snapshot");
assertTrue(ex.getCause() instanceof NullPointerException);
ex = serialize(new SnapshotException(null, "no such snapshot", new NullPointerException()));
assertEquals(ex.snapshot(), null);
assertEquals(ex.getMessage(), "[_na] no such snapshot");
assertTrue(ex.getCause() instanceof NullPointerException);
}
public void testRecoverFilesRecoveryException() throws IOException {
ShardId id = new ShardId("foo", 1);
ByteSizeValue bytes = new ByteSizeValue(randomIntBetween(0, 10000));
RecoverFilesRecoveryException ex = serialize(new RecoverFilesRecoveryException(id, 10, bytes, null));
assertEquals(ex.getShardId(), id);
assertEquals(ex.numberOfFiles(), 10);
assertEquals(ex.totalFilesSize(), bytes);
assertEquals(ex.getMessage(), "Failed to transfer [10] files with total size of [" + bytes + "]");
assertNull(ex.getCause());
ex = serialize(new RecoverFilesRecoveryException(null, 10, bytes, new NullPointerException()));
assertNull(ex.getShardId());
assertEquals(ex.numberOfFiles(), 10);
assertEquals(ex.totalFilesSize(), bytes);
assertEquals(ex.getMessage(), "Failed to transfer [10] files with total size of [" + bytes + "]");
assertTrue(ex.getCause() instanceof NullPointerException);
}
public void testIndexTemplateAlreadyExistsException() throws IOException {
IndexTemplateAlreadyExistsException ex = serialize(new IndexTemplateAlreadyExistsException("the dude abides!"));
assertEquals("the dude abides!", ex.name());
assertEquals("index_template [the dude abides!] already exists", ex.getMessage());
ex = serialize(new IndexTemplateAlreadyExistsException((String)null));
assertNull(ex.name());
assertEquals("index_template [null] already exists", ex.getMessage());
}
public void testBatchOperationException() throws IOException {
ShardId id = new ShardId("foo", 1);
TranslogRecoveryPerformer.BatchOperationException ex = serialize(new TranslogRecoveryPerformer.BatchOperationException(id, "batched the fucker", 666, null));
assertEquals(ex.getShardId(), id);
assertEquals(666, ex.completedOperations());
assertEquals("batched the fucker", ex.getMessage());
assertNull(ex.getCause());
ex = serialize(new TranslogRecoveryPerformer.BatchOperationException(null, "batched the fucker", -1, new NullPointerException()));
assertNull(ex.getShardId());
assertEquals(-1, ex.completedOperations());
assertEquals("batched the fucker", ex.getMessage());
assertTrue(ex.getCause() instanceof NullPointerException);
}
public void testInvalidIndexTemplateException() throws IOException {
InvalidIndexTemplateException ex = serialize(new InvalidIndexTemplateException("foo", "bar"));
assertEquals(ex.getMessage(), "index_template [foo] invalid, cause [bar]");
assertEquals(ex.name(), "foo");
ex = serialize(new InvalidIndexTemplateException(null, "bar"));
assertEquals(ex.getMessage(), "index_template [null] invalid, cause [bar]");
assertEquals(ex.name(), null);
}
public void testActionTransportException() throws IOException {
ActionTransportException ex = serialize(new ActionTransportException("name?", new LocalTransportAddress("dead.end:666"), "ACTION BABY!", "message?", null));
assertEquals("ACTION BABY!", ex.action());
assertEquals(new LocalTransportAddress("dead.end:666"), ex.address());
assertEquals("[name?][local[dead.end:666]][ACTION BABY!] message?", ex.getMessage());
}
public void testSearchContextMissingException() throws IOException {
long id = randomLong();
SearchContextMissingException ex = serialize(new SearchContextMissingException(id));
assertEquals(id, ex.id());
}
public void testPercolateException() throws IOException {
ShardId id = new ShardId("foo", 1);
PercolateException ex = serialize(new PercolateException(id, "percolate my ass", null));
assertEquals(id, ex.getShardId());
assertEquals("percolate my ass", ex.getMessage());
assertNull(ex.getCause());
ex = serialize(new PercolateException(id, "percolate my ass", new NullPointerException()));
assertEquals(id, ex.getShardId());
assertEquals("percolate my ass", ex.getMessage());
assertTrue(ex.getCause() instanceof NullPointerException);
}
public void testRoutingValidationException() throws IOException {
RoutingTableValidation validation = new RoutingTableValidation();
validation.addIndexFailure("foo", "bar");
RoutingValidationException ex = serialize(new RoutingValidationException(validation));
assertEquals("[Index [foo]: bar]", ex.getMessage());
assertEquals(validation.toString(), ex.validation().toString());
}
public void testCircuitBreakingException() throws IOException {
CircuitBreakingException ex = serialize(new CircuitBreakingException("I hate to say I told you so...", 0, 100));
assertEquals("I hate to say I told you so...", ex.getMessage());
assertEquals(100, ex.getByteLimit());
assertEquals(0, ex.getBytesWanted());
}
public void testTimestampParsingException() throws IOException {
TimestampParsingException ex = serialize(new TimestampParsingException("TIMESTAMP", null));
assertEquals("failed to parse timestamp [TIMESTAMP]", ex.getMessage());
assertEquals("TIMESTAMP", ex.timestamp());
}
public void testIndexFailedEngineException() throws IOException {
ShardId id = new ShardId("foo", 1);
IndexFailedEngineException ex = serialize(new IndexFailedEngineException(id, "type", "id", null));
assertEquals(ex.getShardId(), new ShardId("foo", 1));
assertEquals("type", ex.type());
assertEquals("id", ex.id());
assertNull(ex.getCause());
ex = serialize(new IndexFailedEngineException(null, "type", "id", new NullPointerException()));
assertNull(ex.getShardId());
assertEquals("type", ex.type());
assertEquals("id", ex.id());
assertTrue(ex.getCause() instanceof NullPointerException);
}
public void testAliasesMissingException() throws IOException {
AliasesNotFoundException ex = serialize(new AliasesNotFoundException("one", "two", "three"));
assertEquals("aliases [one, two, three] missing", ex.getMessage());
assertEquals("aliases", ex.getResourceType());
assertArrayEquals(new String[]{"one", "two", "three"}, ex.getResourceId().toArray(new String[0]));
}
public void testSearchParseException() throws IOException {
SearchContext ctx = new TestSearchContext();
SearchParseException ex = serialize(new SearchParseException(ctx, "foo", new XContentLocation(66, 666)));
assertEquals("foo", ex.getMessage());
assertEquals(66, ex.getLineNumber());
assertEquals(666, ex.getColumnNumber());
assertEquals(ctx.shardTarget(), ex.shard());
}
public void testIllegalIndexShardStateException()throws IOException {
ShardId id = new ShardId("foo", 1);
IndexShardState state = randomFrom(IndexShardState.values());
IllegalIndexShardStateException ex = serialize(new IllegalIndexShardStateException(id, state, "come back later buddy"));
assertEquals(id, ex.getShardId());
assertEquals("CurrentState[" + state.name() + "] come back later buddy", ex.getMessage());
assertEquals(state, ex.currentState());
}
public void testConnectTransportException() throws IOException {
DiscoveryNode node = new DiscoveryNode("thenode", new LocalTransportAddress("dead.end:666"), Version.CURRENT);
ConnectTransportException ex = serialize(new ConnectTransportException(node, "msg", "action", null));
assertEquals("[][local[dead.end:666]][action] msg", ex.getMessage());
assertEquals(node, ex.node());
assertEquals("action", ex.action());
assertNull(ex.getCause());
ex = serialize(new ConnectTransportException(node, "msg", "action", new NullPointerException()));
assertEquals("[][local[dead.end:666]][action] msg", ex.getMessage());
assertEquals(node, ex.node());
assertEquals("action", ex.action());
assertTrue(ex.getCause() instanceof NullPointerException);
}
public void testSearchPhaseExecutionException() throws IOException {
ShardSearchFailure[] empty = new ShardSearchFailure[0];
SearchPhaseExecutionException ex = serialize(new SearchPhaseExecutionException("boom", "baam", new NullPointerException(), empty));
assertEquals("boom", ex.getPhaseName());
assertEquals("baam", ex.getMessage());
assertTrue(ex.getCause() instanceof NullPointerException);
assertEquals(empty.length, ex.shardFailures().length);
ShardSearchFailure[] one = new ShardSearchFailure[] {
new ShardSearchFailure(new IllegalArgumentException("nono!"))
};
ex = serialize(new SearchPhaseExecutionException("boom", "baam", new NullPointerException(), one));
assertEquals("boom", ex.getPhaseName());
assertEquals("baam", ex.getMessage());
assertTrue(ex.getCause() instanceof NullPointerException);
assertEquals(one.length, ex.shardFailures().length);
assertTrue(ex.shardFailures()[0].getCause() instanceof IllegalArgumentException);
}
public void testRoutingMissingException() throws IOException {
RoutingMissingException ex = serialize(new RoutingMissingException("idx", "type", "id"));
assertEquals("idx", ex.getIndex());
assertEquals("type", ex.getType());
assertEquals("id", ex.getId());
assertEquals("routing is required for [idx]/[type]/[id]", ex.getMessage());
}
public void testRepositoryException() throws IOException {
RepositoryException ex = serialize(new RepositoryException("repo", "msg"));
assertEquals("repo", ex.repository());
assertEquals("[repo] msg", ex.getMessage());
ex = serialize(new RepositoryException(null, "msg"));
assertNull(ex.repository());
assertEquals("[_na] msg", ex.getMessage());
}
public void testIndexWarmerMissingException() throws IOException {
IndexWarmerMissingException ex = serialize(new IndexWarmerMissingException("w1", "w2"));
assertEquals("index_warmer [w1, w2] missing", ex.getMessage());
assertArrayEquals(new String[]{"w1", "w2"}, ex.names());
}
public void testIndexTemplateMissingException() throws IOException {
IndexTemplateMissingException ex = serialize(new IndexTemplateMissingException("name"));
assertEquals("index_template [name] missing", ex.getMessage());
assertEquals("name", ex.name());
ex = serialize(new IndexTemplateMissingException((String)null));
assertEquals("index_template [null] missing", ex.getMessage());
assertNull(ex.name());
}
public void testRecoveryEngineException() throws IOException {
ShardId id = new ShardId("foo", 1);
RecoveryEngineException ex = serialize(new RecoveryEngineException(id, 10, "total failure", new NullPointerException()));
assertEquals(id, ex.getShardId());
assertEquals("Phase[10] total failure", ex.getMessage());
assertEquals(10, ex.phase());
ex = serialize(new RecoveryEngineException(null, -1, "total failure", new NullPointerException()));
assertNull(ex.getShardId());
assertEquals(-1, ex.phase());
assertTrue(ex.getCause() instanceof NullPointerException);
}
public void testFailedNodeException() throws IOException {
FailedNodeException ex = serialize(new FailedNodeException("the node", "the message", null));
assertEquals("the node", ex.nodeId());
assertEquals("the message", ex.getMessage());
}
public void testClusterBlockException() throws IOException {
ClusterBlockException ex = serialize(new ClusterBlockException(ImmutableSet.of(DiscoverySettings.NO_MASTER_BLOCK_WRITES)));
assertEquals("blocked by: [SERVICE_UNAVAILABLE/2/no master];", ex.getMessage());
assertTrue(ex.blocks().contains(DiscoverySettings.NO_MASTER_BLOCK_WRITES));
assertEquals(1, ex.blocks().size());
}
private String toXContent(ToXContent x) {
try {
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
x.toXContent(builder, ToXContent.EMPTY_PARAMS);
builder.endObject();
return builder.string();
} catch (IOException e) {
return "{ \"error\" : \"" + e.getMessage() + "\"}";
}
}
public void testNotSerializableExceptionWrapper() throws IOException {
NotSerializableExceptionWrapper ex = serialize(new NotSerializableExceptionWrapper(new NullPointerException()));
assertEquals("{\"type\":\"null_pointer_exception\",\"reason\":\"null_pointer_exception: null\"}", toXContent(ex));
ex = serialize(new NotSerializableExceptionWrapper(new IllegalArgumentException("nono!")));
assertEquals("{\"type\":\"illegal_argument_exception\",\"reason\":\"illegal_argument_exception: nono!\"}", toXContent(ex));
Throwable[] unknowns = new Throwable[] {
new JsonParseException("foobar", new JsonLocation(new Object(), 1,2,3,4)),
new ClassCastException("boom boom boom"),
new IOException("booom")
};
for (Throwable t : unknowns) {
if (randomBoolean()) {
t.addSuppressed(new IOException("suppressed"));
t.addSuppressed(new NullPointerException());
}
Throwable deserialized = serialize(t);
assertTrue(deserialized instanceof NotSerializableExceptionWrapper);
assertArrayEquals(t.getStackTrace(), deserialized.getStackTrace());
assertEquals(t.getSuppressed().length, deserialized.getSuppressed().length);
if (t.getSuppressed().length > 0) {
assertTrue(deserialized.getSuppressed()[0] instanceof NotSerializableExceptionWrapper);
assertArrayEquals(t.getSuppressed()[0].getStackTrace(), deserialized.getSuppressed()[0].getStackTrace());
assertTrue(deserialized.getSuppressed()[1] instanceof NullPointerException);
}
}
}
public void testWithRestHeadersException() throws IOException {
ElasticsearchException ex = new ElasticsearchException("msg");
ex.addHeader("foo", "foo", "bar");
ex = serialize(ex);
assertEquals("msg", ex.getMessage());
assertEquals(2, ex.getHeader("foo").size());
assertEquals("foo", ex.getHeader("foo").get(0));
assertEquals("bar", ex.getHeader("foo").get(1));
RestStatus status = randomFrom(RestStatus.values());
// ensure we are carrying over the headers even if not serialized
UnknownHeaderException uhe = new UnknownHeaderException("msg", status);
uhe.addHeader("foo", "foo", "bar");
ElasticsearchException serialize = serialize((ElasticsearchException)uhe);
assertTrue(serialize instanceof NotSerializableExceptionWrapper);
NotSerializableExceptionWrapper e = (NotSerializableExceptionWrapper) serialize;
assertEquals("unknown_header_exception: msg", e.getMessage());
assertEquals(2, e.getHeader("foo").size());
assertEquals("foo", e.getHeader("foo").get(0));
assertEquals("bar", e.getHeader("foo").get(1));
assertSame(status, e.status());
}
public static class UnknownHeaderException extends ElasticsearchException {
private final RestStatus status;
public UnknownHeaderException(String msg, RestStatus status) {
super(msg);
this.status = status;
}
@Override
public RestStatus status() {
return status;
}
}
public void testElasticsearchSecurityException() throws IOException {
ElasticsearchSecurityException ex = new ElasticsearchSecurityException("user [{}] is not allowed", RestStatus.UNAUTHORIZED, "foo");
ElasticsearchSecurityException e = serialize(ex);
assertEquals(ex.status(), e.status());
assertEquals(RestStatus.UNAUTHORIZED, e.status());
}
public void testInterruptedException() throws IOException {
InterruptedException orig = randomBoolean() ? new InterruptedException("boom") : new InterruptedException();
InterruptedException ex = serialize(orig);
assertEquals(orig.getMessage(), ex.getMessage());
}
public static class UnknownException extends Exception {
public UnknownException(String message) {
super(message);
}
public UnknownException(String message, Throwable cause) {
super(message, cause);
}
}
public void testIds() {
Map<Integer, Class<? extends ElasticsearchException>> ids = new HashMap<>();
ids.put(0, org.elasticsearch.index.snapshots.IndexShardSnapshotFailedException.class);
ids.put(1, org.elasticsearch.search.dfs.DfsPhaseExecutionException.class);
ids.put(2, org.elasticsearch.common.util.CancellableThreads.ExecutionCancelledException.class);
ids.put(3, org.elasticsearch.discovery.MasterNotDiscoveredException.class);
ids.put(4, org.elasticsearch.ElasticsearchSecurityException.class);
ids.put(5, org.elasticsearch.index.snapshots.IndexShardRestoreException.class);
ids.put(6, org.elasticsearch.indices.IndexClosedException.class);
ids.put(7, org.elasticsearch.http.BindHttpException.class);
ids.put(8, org.elasticsearch.action.search.ReduceSearchPhaseException.class);
ids.put(9, org.elasticsearch.node.NodeClosedException.class);
ids.put(10, org.elasticsearch.index.engine.SnapshotFailedEngineException.class);
ids.put(11, org.elasticsearch.index.shard.ShardNotFoundException.class);
ids.put(12, org.elasticsearch.transport.ConnectTransportException.class);
ids.put(13, org.elasticsearch.transport.NotSerializableTransportException.class);
ids.put(14, org.elasticsearch.transport.ResponseHandlerFailureTransportException.class);
ids.put(15, org.elasticsearch.indices.IndexCreationException.class);
ids.put(16, org.elasticsearch.index.IndexNotFoundException.class);
ids.put(17, org.elasticsearch.cluster.routing.IllegalShardRoutingStateException.class);
ids.put(18, org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException.class);
ids.put(19, org.elasticsearch.ResourceNotFoundException.class);
ids.put(20, org.elasticsearch.transport.ActionTransportException.class);
ids.put(21, org.elasticsearch.ElasticsearchGenerationException.class);
ids.put(22, org.elasticsearch.index.engine.CreateFailedEngineException.class);
ids.put(23, org.elasticsearch.index.shard.IndexShardStartedException.class);
ids.put(24, org.elasticsearch.search.SearchContextMissingException.class);
ids.put(25, org.elasticsearch.script.ScriptException.class);
ids.put(26, org.elasticsearch.index.shard.TranslogRecoveryPerformer.BatchOperationException.class);
ids.put(27, org.elasticsearch.snapshots.SnapshotCreationException.class);
ids.put(28, org.elasticsearch.index.engine.DeleteFailedEngineException.class);
ids.put(29, org.elasticsearch.index.engine.DocumentMissingException.class);
ids.put(30, org.elasticsearch.snapshots.SnapshotException.class);
ids.put(31, org.elasticsearch.indices.InvalidAliasNameException.class);
ids.put(32, org.elasticsearch.indices.InvalidIndexNameException.class);
ids.put(33, org.elasticsearch.indices.IndexPrimaryShardNotAllocatedException.class);
ids.put(34, org.elasticsearch.transport.TransportException.class);
ids.put(35, org.elasticsearch.ElasticsearchParseException.class);
ids.put(36, org.elasticsearch.search.SearchException.class);
ids.put(37, org.elasticsearch.index.mapper.MapperException.class);
ids.put(38, org.elasticsearch.indices.InvalidTypeNameException.class);
ids.put(39, org.elasticsearch.snapshots.SnapshotRestoreException.class);
ids.put(40, org.elasticsearch.index.query.QueryParsingException.class);
ids.put(41, org.elasticsearch.index.shard.IndexShardClosedException.class);
ids.put(42, org.elasticsearch.indices.recovery.RecoverFilesRecoveryException.class);
ids.put(43, org.elasticsearch.index.translog.TruncatedTranslogException.class);
ids.put(44, org.elasticsearch.indices.recovery.RecoveryFailedException.class);
ids.put(45, org.elasticsearch.index.shard.IndexShardRelocatedException.class);
ids.put(46, org.elasticsearch.transport.NodeShouldNotConnectException.class);
ids.put(47, org.elasticsearch.indices.IndexTemplateAlreadyExistsException.class);
ids.put(48, org.elasticsearch.index.translog.TranslogCorruptedException.class);
ids.put(49, org.elasticsearch.cluster.block.ClusterBlockException.class);
ids.put(50, org.elasticsearch.search.fetch.FetchPhaseExecutionException.class);
ids.put(51, org.elasticsearch.index.IndexShardAlreadyExistsException.class);
ids.put(52, org.elasticsearch.index.engine.VersionConflictEngineException.class);
ids.put(53, org.elasticsearch.index.engine.EngineException.class);
ids.put(54, org.elasticsearch.index.engine.DocumentAlreadyExistsException.class);
ids.put(55, org.elasticsearch.action.NoSuchNodeException.class);
ids.put(56, org.elasticsearch.common.settings.SettingsException.class);
ids.put(57, org.elasticsearch.indices.IndexTemplateMissingException.class);
ids.put(58, org.elasticsearch.transport.SendRequestTransportException.class);
ids.put(59, org.elasticsearch.common.util.concurrent.EsRejectedExecutionException.class);
ids.put(60, org.elasticsearch.common.lucene.Lucene.EarlyTerminationException.class);
ids.put(61, org.elasticsearch.cluster.routing.RoutingValidationException.class);
ids.put(62, org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper.class);
ids.put(63, org.elasticsearch.indices.AliasFilterParsingException.class);
ids.put(64, org.elasticsearch.index.engine.DeleteByQueryFailedEngineException.class);
ids.put(65, org.elasticsearch.gateway.GatewayException.class);
ids.put(66, org.elasticsearch.index.shard.IndexShardNotRecoveringException.class);
ids.put(67, org.elasticsearch.http.HttpException.class);
ids.put(68, org.elasticsearch.ElasticsearchException.class);
ids.put(69, org.elasticsearch.snapshots.SnapshotMissingException.class);
ids.put(70, org.elasticsearch.action.PrimaryMissingActionException.class);
ids.put(71, org.elasticsearch.action.FailedNodeException.class);
ids.put(72, org.elasticsearch.search.SearchParseException.class);
ids.put(73, org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException.class);
ids.put(74, org.elasticsearch.common.blobstore.BlobStoreException.class);
ids.put(75, org.elasticsearch.cluster.IncompatibleClusterStateVersionException.class);
ids.put(76, org.elasticsearch.index.engine.RecoveryEngineException.class);
ids.put(77, org.elasticsearch.common.util.concurrent.UncategorizedExecutionException.class);
ids.put(78, org.elasticsearch.action.TimestampParsingException.class);
ids.put(79, org.elasticsearch.action.RoutingMissingException.class);
ids.put(80, org.elasticsearch.index.engine.IndexFailedEngineException.class);
ids.put(81, org.elasticsearch.index.snapshots.IndexShardRestoreFailedException.class);
ids.put(82, org.elasticsearch.repositories.RepositoryException.class);
ids.put(83, org.elasticsearch.transport.ReceiveTimeoutTransportException.class);
ids.put(84, org.elasticsearch.transport.NodeDisconnectedException.class);
ids.put(85, org.elasticsearch.index.AlreadyExpiredException.class);
ids.put(86, org.elasticsearch.search.aggregations.AggregationExecutionException.class);
ids.put(87, org.elasticsearch.index.mapper.MergeMappingException.class);
ids.put(88, org.elasticsearch.indices.InvalidIndexTemplateException.class);
ids.put(89, org.elasticsearch.percolator.PercolateException.class);
ids.put(90, org.elasticsearch.index.engine.RefreshFailedEngineException.class);
ids.put(91, org.elasticsearch.search.aggregations.AggregationInitializationException.class);
ids.put(92, org.elasticsearch.indices.recovery.DelayRecoveryException.class);
ids.put(93, org.elasticsearch.search.warmer.IndexWarmerMissingException.class);
ids.put(94, org.elasticsearch.client.transport.NoNodeAvailableException.class);
ids.put(95, org.elasticsearch.script.groovy.GroovyScriptCompilationException.class);
ids.put(96, org.elasticsearch.snapshots.InvalidSnapshotNameException.class);
ids.put(97, org.elasticsearch.index.shard.IllegalIndexShardStateException.class);
ids.put(98, org.elasticsearch.index.snapshots.IndexShardSnapshotException.class);
ids.put(99, org.elasticsearch.index.shard.IndexShardNotStartedException.class);
ids.put(100, org.elasticsearch.action.search.SearchPhaseExecutionException.class);
ids.put(101, org.elasticsearch.transport.ActionNotFoundTransportException.class);
ids.put(102, org.elasticsearch.transport.TransportSerializationException.class);
ids.put(103, org.elasticsearch.transport.RemoteTransportException.class);
ids.put(104, org.elasticsearch.index.engine.EngineCreationFailureException.class);
ids.put(105, org.elasticsearch.cluster.routing.RoutingException.class);
ids.put(106, org.elasticsearch.index.shard.IndexShardRecoveryException.class);
ids.put(107, org.elasticsearch.repositories.RepositoryMissingException.class);
ids.put(108, org.elasticsearch.index.percolator.PercolatorException.class);
ids.put(109, org.elasticsearch.index.engine.DocumentSourceMissingException.class);
ids.put(110, org.elasticsearch.index.engine.FlushNotAllowedEngineException.class);
ids.put(111, org.elasticsearch.common.settings.NoClassSettingsException.class);
ids.put(112, org.elasticsearch.transport.BindTransportException.class);
ids.put(113, org.elasticsearch.rest.action.admin.indices.alias.delete.AliasesNotFoundException.class);
ids.put(114, org.elasticsearch.index.shard.IndexShardRecoveringException.class);
ids.put(115, org.elasticsearch.index.translog.TranslogException.class);
ids.put(116, org.elasticsearch.cluster.metadata.ProcessClusterEventTimeoutException.class);
ids.put(117, org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnPrimaryException.class);
ids.put(118, org.elasticsearch.ElasticsearchTimeoutException.class);
ids.put(119, org.elasticsearch.search.query.QueryPhaseExecutionException.class);
ids.put(120, org.elasticsearch.repositories.RepositoryVerificationException.class);
ids.put(121, org.elasticsearch.search.aggregations.InvalidAggregationPathException.class);
ids.put(122, org.elasticsearch.script.groovy.GroovyScriptExecutionException.class);
ids.put(123, org.elasticsearch.indices.IndexAlreadyExistsException.class);
ids.put(124, org.elasticsearch.script.Script.ScriptParseException.class);
ids.put(125, org.elasticsearch.transport.netty.SizeHeaderFrameDecoder.HttpOnTransportException.class);
ids.put(126, org.elasticsearch.index.mapper.MapperParsingException.class);
ids.put(127, org.elasticsearch.search.SearchContextException.class);
ids.put(128, org.elasticsearch.search.builder.SearchSourceBuilderException.class);
ids.put(129, org.elasticsearch.index.engine.EngineClosedException.class);
ids.put(130, org.elasticsearch.action.NoShardAvailableActionException.class);
ids.put(131, org.elasticsearch.action.UnavailableShardsException.class);
ids.put(132, org.elasticsearch.index.engine.FlushFailedEngineException.class);
ids.put(133, org.elasticsearch.common.breaker.CircuitBreakingException.class);
ids.put(134, org.elasticsearch.transport.NodeNotConnectedException.class);
ids.put(135, org.elasticsearch.index.mapper.StrictDynamicMappingException.class);
ids.put(136, org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnReplicaException.class);
ids.put(137, org.elasticsearch.indices.TypeMissingException.class);
ids.put(138, org.elasticsearch.script.expression.ExpressionScriptCompilationException.class);
ids.put(139, org.elasticsearch.script.expression.ExpressionScriptExecutionException.class);
Map<Class<? extends ElasticsearchException>, Integer> reverse = new HashMap<>();
for (Map.Entry<Integer, Class<? extends ElasticsearchException>> entry : ids.entrySet()) {
if (entry.getValue() != null) {
reverse.put(entry.getValue(), entry.getKey());
}
}
for (Map.Entry<Integer, Constructor<? extends ElasticsearchException>> entry : ElasticsearchException.ID_TO_SUPPLIER.entrySet()) {
assertNotNull(Integer.toString(entry.getKey()), reverse.get(entry.getValue().getDeclaringClass()));
assertEquals(reverse.get(entry.getValue().getDeclaringClass()), entry.getKey());
}
for (Map.Entry<Integer, Class<? extends ElasticsearchException>> entry : ids.entrySet()) {
if (entry.getValue() != null) {
assertEquals((int) entry.getKey(), ElasticsearchException.getId(entry.getValue()));
}
}
}
}