/* * 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.cluster.metadata; import org.elasticsearch.Version; import org.elasticsearch.cluster.ClusterModule; import org.elasticsearch.common.UUIDs; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.index.Index; import org.elasticsearch.test.ESTestCase; import java.io.IOException; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; public class MetaDataTests extends ESTestCase { public void testIndexAndAliasWithSameName() { IndexMetaData.Builder builder = IndexMetaData.builder("index") .settings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)) .numberOfShards(1) .numberOfReplicas(0) .putAlias(AliasMetaData.builder("index").build()); try { MetaData.builder().put(builder).build(); fail("exception should have been thrown"); } catch (IllegalStateException e) { assertThat(e.getMessage(), equalTo("index and alias names need to be unique, but alias [index] and index [index] have the same name")); } } public void testResolveIndexRouting() { IndexMetaData.Builder builder = IndexMetaData.builder("index") .settings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)) .numberOfShards(1) .numberOfReplicas(0) .putAlias(AliasMetaData.builder("alias0").build()) .putAlias(AliasMetaData.builder("alias1").routing("1").build()) .putAlias(AliasMetaData.builder("alias2").routing("1,2").build()); MetaData metaData = MetaData.builder().put(builder).build(); // no alias, no index assertEquals(metaData.resolveIndexRouting(null, null, null), null); assertEquals(metaData.resolveIndexRouting(null, "0", null), "0"); assertEquals(metaData.resolveIndexRouting("32", "0", null), "0"); assertEquals(metaData.resolveIndexRouting("32", null, null), "32"); // index, no alias assertEquals(metaData.resolveIndexRouting("32", "0", "index"), "0"); assertEquals(metaData.resolveIndexRouting("32", null, "index"), "32"); assertEquals(metaData.resolveIndexRouting(null, null, "index"), null); assertEquals(metaData.resolveIndexRouting(null, "0", "index"), "0"); // alias with no index routing assertEquals(metaData.resolveIndexRouting(null, null, "alias0"), null); assertEquals(metaData.resolveIndexRouting(null, "0", "alias0"), "0"); assertEquals(metaData.resolveIndexRouting("32", null, "alias0"), "32"); assertEquals(metaData.resolveIndexRouting("32", "0", "alias0"), "0"); // alias with index routing. assertEquals(metaData.resolveIndexRouting(null, null, "alias1"), "1"); assertEquals(metaData.resolveIndexRouting("32", null, "alias1"), "1"); assertEquals(metaData.resolveIndexRouting("32", "1", "alias1"), "1"); try { metaData.resolveIndexRouting(null, "0", "alias1"); fail("should fail"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(), is("Alias [alias1] has index routing associated with it [1], and was provided with routing value [0], rejecting operation")); } try { metaData.resolveIndexRouting("32", "0", "alias1"); fail("should fail"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(), is("Alias [alias1] has index routing associated with it [1], and was provided with routing value [0], rejecting operation")); } // alias with invalid index routing. try { metaData.resolveIndexRouting(null, null, "alias2"); fail("should fail"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(), is("index/alias [alias2] provided with routing value [1,2] that resolved to several routing values, rejecting operation")); } try { metaData.resolveIndexRouting(null, "1", "alias2"); fail("should fail"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(), is("index/alias [alias2] provided with routing value [1,2] that resolved to several routing values, rejecting operation")); } try { metaData.resolveIndexRouting("32", null, "alias2"); fail("should fail"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(), is("index/alias [alias2] provided with routing value [1,2] that resolved to several routing values, rejecting operation")); } } public void testUnknownFieldClusterMetaData() throws IOException { BytesReference metadata = JsonXContent.contentBuilder() .startObject() .startObject("meta-data") .field("random", "value") .endObject() .endObject().bytes(); XContentParser parser = createParser(JsonXContent.jsonXContent, metadata); try { MetaData.Builder.fromXContent(parser); fail(); } catch (IllegalArgumentException e) { assertEquals("Unexpected field [random]", e.getMessage()); } } public void testUnknownFieldIndexMetaData() throws IOException { BytesReference metadata = JsonXContent.contentBuilder() .startObject() .startObject("index_name") .field("random", "value") .endObject() .endObject().bytes(); XContentParser parser = createParser(JsonXContent.jsonXContent, metadata); try { IndexMetaData.Builder.fromXContent(parser); fail(); } catch (IllegalArgumentException e) { assertEquals("Unexpected field [random]", e.getMessage()); } } public void testMetaDataGlobalStateChangesOnIndexDeletions() { IndexGraveyard.Builder builder = IndexGraveyard.builder(); builder.addTombstone(new Index("idx1", UUIDs.randomBase64UUID())); final MetaData metaData1 = MetaData.builder().indexGraveyard(builder.build()).build(); builder = IndexGraveyard.builder(metaData1.indexGraveyard()); builder.addTombstone(new Index("idx2", UUIDs.randomBase64UUID())); final MetaData metaData2 = MetaData.builder(metaData1).indexGraveyard(builder.build()).build(); assertFalse("metadata not equal after adding index deletions", MetaData.isGlobalStateEquals(metaData1, metaData2)); final MetaData metaData3 = MetaData.builder(metaData2).build(); assertTrue("metadata equal when not adding index deletions", MetaData.isGlobalStateEquals(metaData2, metaData3)); } public void testXContentWithIndexGraveyard() throws IOException { final IndexGraveyard graveyard = IndexGraveyardTests.createRandom(); final MetaData originalMeta = MetaData.builder().indexGraveyard(graveyard).build(); final XContentBuilder builder = JsonXContent.contentBuilder(); builder.startObject(); originalMeta.toXContent(builder, ToXContent.EMPTY_PARAMS); builder.endObject(); XContentParser parser = createParser(JsonXContent.jsonXContent, builder.bytes()); final MetaData fromXContentMeta = MetaData.fromXContent(parser); assertThat(fromXContentMeta.indexGraveyard(), equalTo(originalMeta.indexGraveyard())); } public void testSerializationWithIndexGraveyard() throws IOException { final IndexGraveyard graveyard = IndexGraveyardTests.createRandom(); final MetaData originalMeta = MetaData.builder().indexGraveyard(graveyard).build(); final BytesStreamOutput out = new BytesStreamOutput(); originalMeta.writeTo(out); NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry(ClusterModule.getNamedWriteables()); final MetaData fromStreamMeta = MetaData.readFrom( new NamedWriteableAwareStreamInput(out.bytes().streamInput(), namedWriteableRegistry) ); assertThat(fromStreamMeta.indexGraveyard(), equalTo(fromStreamMeta.indexGraveyard())); } }