/* * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * 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. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ package org.opensearch.cluster.metadata; import org.opensearch.cluster.Diff; import org.opensearch.common.compress.CompressedXContent; import org.opensearch.core.common.io.stream.Writeable; import org.opensearch.common.settings.Settings; import org.opensearch.core.xcontent.XContentParser; import org.opensearch.test.AbstractDiffableSerializationTestCase; import org.opensearch.test.OpenSearchTestCase; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; public class ComposableIndexTemplateTests extends AbstractDiffableSerializationTestCase { @Override protected ComposableIndexTemplate makeTestChanges(ComposableIndexTemplate testInstance) { try { return mutateInstance(testInstance); } catch (IOException e) { logger.error(e); fail("mutating should not throw an exception, but got: " + e); return null; } } @Override protected Writeable.Reader> diffReader() { return ComposableIndexTemplate::readITV2DiffFrom; } @Override protected ComposableIndexTemplate doParseInstance(XContentParser parser) throws IOException { return ComposableIndexTemplate.parse(parser); } @Override protected Writeable.Reader instanceReader() { return ComposableIndexTemplate::new; } @Override protected ComposableIndexTemplate createTestInstance() { return randomInstance(); } public static ComposableIndexTemplate randomInstance() { Settings settings = null; CompressedXContent mappings = null; Map aliases = null; Template template = null; ComposableIndexTemplate.DataStreamTemplate dataStreamTemplate = randomDataStreamTemplate(); if (dataStreamTemplate != null || randomBoolean()) { if (randomBoolean()) { settings = randomSettings(); } if (dataStreamTemplate != null || randomBoolean()) { mappings = randomMappings(dataStreamTemplate); } if (randomBoolean()) { aliases = randomAliases(); } template = new Template(settings, mappings, aliases); } Map meta = null; if (randomBoolean()) { meta = randomMeta(); } List indexPatterns = randomList(1, 4, () -> randomAlphaOfLength(4)); List componentTemplates = randomList(0, 10, () -> randomAlphaOfLength(5)); return new ComposableIndexTemplate( indexPatterns, template, componentTemplates, randomBoolean() ? null : randomNonNegativeLong(), randomBoolean() ? null : randomNonNegativeLong(), meta, dataStreamTemplate ); } private static Map randomAliases() { String aliasName = randomAlphaOfLength(5); AliasMetadata aliasMeta = AliasMetadata.builder(aliasName) .filter("{\"term\":{\"year\":" + randomIntBetween(1, 3000) + "}}") .routing(randomBoolean() ? null : randomAlphaOfLength(3)) .isHidden(randomBoolean() ? null : randomBoolean()) .writeIndex(randomBoolean() ? null : randomBoolean()) .build(); return Collections.singletonMap(aliasName, aliasMeta); } private static CompressedXContent randomMappings(ComposableIndexTemplate.DataStreamTemplate dataStreamTemplate) { try { if (dataStreamTemplate != null) { return new CompressedXContent("{\"properties\":{\"" + dataStreamTemplate.getTimestampField() + "\":{\"type\":\"date\"}}}"); } else { return new CompressedXContent("{\"properties\":{\"" + randomAlphaOfLength(5) + "\":{\"type\":\"keyword\"}}}"); } } catch (IOException e) { fail("got an IO exception creating fake mappings: " + e); return null; } } private static Settings randomSettings() { return Settings.builder() .put(IndexMetadata.SETTING_BLOCKS_READ, randomBoolean()) .put(IndexMetadata.SETTING_BLOCKS_WRITE, randomBoolean()) .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10)) .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, randomIntBetween(0, 5)) .put(IndexMetadata.SETTING_BLOCKS_WRITE, randomBoolean()) .put(IndexMetadata.SETTING_PRIORITY, randomIntBetween(0, 100000)) .build(); } private static Map randomMeta() { if (randomBoolean()) { return Collections.singletonMap(randomAlphaOfLength(4), randomAlphaOfLength(4)); } else { return Collections.singletonMap( randomAlphaOfLength(5), Collections.singletonMap(randomAlphaOfLength(4), randomAlphaOfLength(4)) ); } } private static ComposableIndexTemplate.DataStreamTemplate randomDataStreamTemplate() { if (randomBoolean()) { return null; } else { return new ComposableIndexTemplate.DataStreamTemplate(); } } @Override protected ComposableIndexTemplate mutateInstance(ComposableIndexTemplate orig) throws IOException { return mutateTemplate(orig); } public static ComposableIndexTemplate mutateTemplate(ComposableIndexTemplate orig) { switch (randomIntBetween(0, 6)) { case 0: List newIndexPatterns = randomValueOtherThan( orig.indexPatterns(), () -> randomList(1, 4, () -> randomAlphaOfLength(4)) ); return new ComposableIndexTemplate( newIndexPatterns, orig.template(), orig.composedOf(), orig.priority(), orig.version(), orig.metadata(), orig.getDataStreamTemplate() ); case 1: return new ComposableIndexTemplate( orig.indexPatterns(), randomValueOtherThan( orig.template(), () -> new Template(randomSettings(), randomMappings(orig.getDataStreamTemplate()), randomAliases()) ), orig.composedOf(), orig.priority(), orig.version(), orig.metadata(), orig.getDataStreamTemplate() ); case 2: List newComposedOf = randomValueOtherThan(orig.composedOf(), () -> randomList(0, 10, () -> randomAlphaOfLength(5))); return new ComposableIndexTemplate( orig.indexPatterns(), orig.template(), newComposedOf, orig.priority(), orig.version(), orig.metadata(), orig.getDataStreamTemplate() ); case 3: return new ComposableIndexTemplate( orig.indexPatterns(), orig.template(), orig.composedOf(), randomValueOtherThan(orig.priority(), OpenSearchTestCase::randomNonNegativeLong), orig.version(), orig.metadata(), orig.getDataStreamTemplate() ); case 4: return new ComposableIndexTemplate( orig.indexPatterns(), orig.template(), orig.composedOf(), orig.priority(), randomValueOtherThan(orig.version(), OpenSearchTestCase::randomNonNegativeLong), orig.metadata(), orig.getDataStreamTemplate() ); case 5: return new ComposableIndexTemplate( orig.indexPatterns(), orig.template(), orig.composedOf(), orig.priority(), orig.version(), randomValueOtherThan(orig.metadata(), ComposableIndexTemplateTests::randomMeta), orig.getDataStreamTemplate() ); case 6: return new ComposableIndexTemplate( orig.indexPatterns(), orig.template(), orig.composedOf(), orig.priority(), orig.version(), orig.metadata(), randomValueOtherThan(orig.getDataStreamTemplate(), ComposableIndexTemplateTests::randomDataStreamTemplate) ); default: throw new IllegalStateException("illegal randomization branch"); } } }