diff --git a/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java b/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java index 59b62b583edb2..58dde24f27c31 100644 --- a/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java +++ b/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java @@ -36,8 +36,7 @@ import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse; import org.elasticsearch.cluster.block.ClusterBlock; import org.elasticsearch.cluster.block.ClusterBlocks; -import org.elasticsearch.cluster.metadata.IndexMetaData.Custom; -import org.elasticsearch.cluster.metadata.IndexMetaData.State; +import org.elasticsearch.cluster.metadata.IndexMetaData.*; import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.routing.RoutingTable; import org.elasticsearch.cluster.routing.allocation.AllocationService; @@ -72,6 +71,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.util.Comparator; import java.util.List; import java.util.Locale; @@ -87,6 +87,8 @@ */ public class MetaDataCreateIndexService extends AbstractComponent { + public final static int MAX_INDEX_NAME_BYTES = 100; + private final Environment environment; private final ThreadPool threadPool; private final ClusterService clusterService; @@ -172,6 +174,18 @@ public void validateIndexName(String index, ClusterState state) throws Elasticse if (!index.toLowerCase(Locale.ROOT).equals(index)) { throw new InvalidIndexNameException(new Index(index), index, "must be lowercase"); } + int byteCount = 0; + try { + byteCount = index.getBytes("UTF-8").length; + } catch (UnsupportedEncodingException e) { + // UTF-8 should always be supported, but rethrow this if it is not for some reason + throw new ElasticsearchException("Unable to determine length of index name", e); + } + if (byteCount > MAX_INDEX_NAME_BYTES) { + throw new InvalidIndexNameException(new Index(index), index, + "index name is too long, (" + byteCount + + " > " + MAX_INDEX_NAME_BYTES + ")"); + } if (state.metaData().aliases().containsKey(index)) { throw new InvalidIndexNameException(new Index(index), index, "already exists as alias"); } diff --git a/src/test/java/org/elasticsearch/indexing/IndexActionTests.java b/src/test/java/org/elasticsearch/indexing/IndexActionTests.java index d27052d1ca81c..5dca1e2f8d4b9 100644 --- a/src/test/java/org/elasticsearch/indexing/IndexActionTests.java +++ b/src/test/java/org/elasticsearch/indexing/IndexActionTests.java @@ -21,13 +21,16 @@ import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.cluster.metadata.MetaDataCreateIndexService; import org.elasticsearch.index.VersionType; +import org.elasticsearch.indices.InvalidIndexNameException; import org.elasticsearch.test.ElasticsearchIntegrationTest; import org.elasticsearch.test.junit.annotations.TestLogging; import org.junit.Test; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -177,4 +180,39 @@ public void testCreateFlagWithBulk() { IndexResponse indexResponse = bulkResponse.getItems()[0].getResponse(); assertTrue(indexResponse.isCreated()); } + + @Test + public void testCreateIndexWithLongName() { + int min = MetaDataCreateIndexService.MAX_INDEX_NAME_BYTES + 1; + int max = MetaDataCreateIndexService.MAX_INDEX_NAME_BYTES * 2; + try { + createIndex(randomAsciiOfLengthBetween(min, max).toLowerCase(Locale.ROOT)); + fail("exception should have been thrown on too-long index name"); + } catch (InvalidIndexNameException e) { + assertThat("exception contains message about index name too long: " + e.getMessage(), + e.getMessage().contains("index name is too long,"), equalTo(true)); + } + + try { + client().prepareIndex(randomAsciiOfLengthBetween(min, max).toLowerCase(Locale.ROOT), "mytype").setSource("foo", "bar").get(); + fail("exception should have been thrown on too-long index name"); + } catch (InvalidIndexNameException e) { + assertThat("exception contains message about index name too long: " + e.getMessage(), + e.getMessage().contains("index name is too long,"), equalTo(true)); + } + + try { + // Catch chars that are more than a single byte + client().prepareIndex(randomAsciiOfLength(MetaDataCreateIndexService.MAX_INDEX_NAME_BYTES -1).toLowerCase(Locale.ROOT) + + "Ϟ".toLowerCase(Locale.ROOT), + "mytype").setSource("foo", "bar").get(); + fail("exception should have been thrown on too-long index name"); + } catch (InvalidIndexNameException e) { + assertThat("exception contains message about index name too long: " + e.getMessage(), + e.getMessage().contains("index name is too long,"), equalTo(true)); + } + + // we can create an index of max length + createIndex(randomAsciiOfLength(MetaDataCreateIndexService.MAX_INDEX_NAME_BYTES).toLowerCase(Locale.ROOT)); + } }