diff --git a/CHANGELOG.md b/CHANGELOG.md index d097a218a6..7bdc00a611 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased 2.x] ### Added +- Added support for indexing and search index settings ([#667](https://github.com/opensearch-project/opensearch-java/pull/667)) ### Dependencies diff --git a/guides/index_templates.md b/guides/index_templates.md new file mode 100644 index 0000000000..43cf79fd2d --- /dev/null +++ b/guides/index_templates.md @@ -0,0 +1,79 @@ +- [Index templates](#index-templates) + - [Setup](#setup) + + +# Index templates + +Index templates let you initialize new indexes with predefined mappings and settings. +For example, if you continuously index log data, you can define an index template so that all of these indexes have +the same number of shards and replicas. + +## Setup + +To get started, first create a client, create an index template. In this example, an index template is created, +composed of two component templates: + +- `index-settings` which specifies index settings such as shard configuration and slowlog settings +- `index-mappings` which specifies the field mappings + +```java +import org.apache.hc.core5.http.HttpHost; + +final HttpHost[] hosts = new HttpHost[] { + new HttpHost("http", "localhost", 9200) + }; + +final OpenSearchTransport transport = ApacheHttpClient5TransportBuilder + .builder(hosts) + .setMapper(new JacksonJsonpMapper()) + .build(); +OpenSearchClient client = new OpenSearchClient(transport); + +final var indexSettingsComponentTemplate = "index-settings"; +PutComponentTemplateRequest putComponentTemplateRequest = PutComponentTemplateRequest.of( + c -> c.name(indexSettingsComponentTemplate) + .settings( + s -> s.numberOfShards("2") + .numberOfReplicas("1") + .indexing( + i -> i.slowlog( + sl -> sl.level("info") + .reformat(true) + .threshold(th -> th.index(ith -> ith.warn(Time.of(t -> t.time("2s"))))) + ) + ) + .search( + se -> se.slowlog(sl -> sl.level("info").threshold(th -> th.query(q -> q.warn(Time.of(t -> t.time("2s")))))) + ) + ) +); +client.cluster().putComponentTemplate(putComponentTemplateRequest); + +final var indexMappingsComponentTemplate = "index-mappings"; +putComponentTemplateRequest = PutComponentTemplateRequest.of( + c -> c.name(indexMappingsComponentTemplate).mappings(m -> m.properties("age", p -> p.integer(i -> i))) +); +client.cluster().putComponentTemplate(putComponentTemplateRequest); + +final var indexTemplateName = "my-index-template"; +PutIndexTemplateRequest putIndexTemplateRequest = PutIndexTemplateRequest.of( + it -> it.name(indexTemplateName) + .indexPatterns("my-index-*") + .composedOf(List.of(indexSettingsComponentTemplate, indexMappingsComponentTemplate)) +); + +client.indices().putIndexTemplate(putIndexTemplateRequest); +``` + +## Usage + +Create an index with a name that matches the index template's `indexPatterns` + +```java +String indexName = "my-index-1"; +client.indices().create(CreateIndexRequest.of(c -> c.index(indexName))); +``` + +The index will be created with the index settings and mappings defined by the `my-index-template` index template. + +You can find a working sample of the above code in [IndexTemplates.java](../samples/src/main/java/org/opensearch/client/samples/IndexTemplates.java). \ No newline at end of file diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettings.java b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettings.java index 509c0fcb4e..783a07c884 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettings.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettings.java @@ -215,6 +215,12 @@ public class IndexSettings implements JsonpSerializable { @Nullable private final IndexSettingsMapping mapping; + @Nullable + private final IndexSettingsIndexing indexing; + + @Nullable + private final IndexSettingsSearch search; + @Nullable private final Boolean knn; @@ -280,6 +286,8 @@ private IndexSettings(Builder builder) { this.analysis = builder.analysis; this.settings = builder.settings; this.mapping = builder.mapping; + this.indexing = builder.indexing; + this.search = builder.search; this.knn = builder.knn; this.knnAlgoParamEfSearch = builder.knnAlgoParamEfSearch; @@ -748,6 +756,22 @@ public final IndexSettingsMapping mapping() { return this.mapping; } + /** + * API name: {@code indexing} + */ + @Nullable + public final IndexSettingsIndexing indexing() { + return this.indexing; + } + + /** + * API name: {@code search} + */ + @Nullable + public final IndexSettingsSearch search() { + return this.search; + } + /** * API name: {@code knn} */ @@ -1054,6 +1078,16 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { generator.writeKey("mapping"); this.mapping.serialize(generator, mapper); + } + if (this.indexing != null) { + generator.writeKey("indexing"); + this.indexing.serialize(generator, mapper); + + } + if (this.search != null) { + generator.writeKey("search"); + this.search.serialize(generator, mapper); + } if (this.knn != null) { generator.writeKey("knn"); @@ -1240,6 +1274,12 @@ public static class Builder extends ObjectBuilderBase implements ObjectBuilder> fn) { + return this.indexing(fn.apply(new IndexSettingsIndexing.Builder()).build()); + } + + /** + * API name: {@code search} + */ + public final Builder search(@Nullable IndexSettingsSearch value) { + this.search = value; + return this; + } + + /** + * API name: {@code search} + */ + public final Builder search(Function> fn) { + return this.search(fn.apply(new IndexSettingsSearch.Builder()).build()); + } + /** * Builds a {@link IndexSettings}. * @@ -1995,6 +2065,8 @@ protected static void setupIndexSettingsDeserializer(ObjectDeserializer> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * API name: {@code slowlog} + */ + @Nullable + public final IndexingSlowlog slowlog() { + return this.slowlog; + } + + /** + * Serialize this object to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartObject(); + serializeInternal(generator, mapper); + generator.writeEnd(); + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + if (this.slowlog != null) { + generator.writeKey("slowlog"); + this.slowlog.serialize(generator, mapper); + + } + + } + + // --------------------------------------------------------------------------------------------- + + /** + * Builder for {@link IndexSettingsIndexing}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + @Nullable + private IndexingSlowlog slowlog; + + /** + * API name: {@code slowlog} + */ + public final Builder slowlog(@Nullable IndexingSlowlog value) { + this.slowlog = value; + return this; + } + + /** + * API name: {@code slowlog} + */ + public final Builder slowlog(Function> fn) { + return this.slowlog(fn.apply(new IndexingSlowlog.Builder()).build()); + } + + /** + * Builds a {@link IndexSettingsIndexing}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public IndexSettingsIndexing build() { + _checkSingleUse(); + + return new IndexSettingsIndexing(this); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Json deserializer for {@link IndexSettingsIndexing} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + IndexSettingsIndexing::setupSettingsSearchDeserializer + ); + + protected static void setupSettingsSearchDeserializer(ObjectDeserializer op) { + + op.add(Builder::slowlog, IndexingSlowlog._DESERIALIZER, "slowlog"); + + } + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettingsSearch.java b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettingsSearch.java new file mode 100644 index 0000000000..c32d7ce6a8 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettingsSearch.java @@ -0,0 +1,176 @@ +/* + * 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 B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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.client.opensearch.indices; + +import jakarta.json.stream.JsonGenerator; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.opensearch.client.json.*; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +@JsonpDeserializable +public class IndexSettingsSearch implements JsonpSerializable { + @Nullable + private final SearchIdle idle; + + @Nullable + private final SearchSlowlog slowlog; + + // --------------------------------------------------------------------------------------------- + + private IndexSettingsSearch(Builder builder) { + + this.idle = builder.idle; + this.slowlog = builder.slowlog; + + } + + public static IndexSettingsSearch of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * API name: {@code idle} + */ + @Nullable + public final SearchIdle idle() { + return this.idle; + } + + /** + * API name: {@code slowlog} + */ + @Nullable + public final SearchSlowlog slowlog() { + return this.slowlog; + } + + /** + * Serialize this object to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartObject(); + serializeInternal(generator, mapper); + generator.writeEnd(); + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + if (this.idle != null) { + generator.writeKey("idle"); + this.idle.serialize(generator, mapper); + + } + if (this.slowlog != null) { + generator.writeKey("slowlog"); + this.slowlog.serialize(generator, mapper); + + } + + } + + // --------------------------------------------------------------------------------------------- + + /** + * Builder for {@link IndexSettingsSearch}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + @Nullable + private SearchIdle idle; + + @Nullable + private SearchSlowlog slowlog; + + /** + * API name: {@code idle} + */ + public final Builder idle(@Nullable SearchIdle value) { + this.idle = value; + return this; + } + + /** + * API name: {@code idle} + */ + public final Builder idle(Function> fn) { + return this.idle(fn.apply(new SearchIdle.Builder()).build()); + } + + /** + * API name: {@code slowlog} + */ + public final Builder slowlog(@Nullable SearchSlowlog value) { + this.slowlog = value; + return this; + } + + /** + * API name: {@code slowlog} + */ + public final Builder slowlog(Function> fn) { + return this.slowlog(fn.apply(new SearchSlowlog.Builder()).build()); + } + + /** + * Builds a {@link IndexSettingsSearch}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public IndexSettingsSearch build() { + _checkSingleUse(); + + return new IndexSettingsSearch(this); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Json deserializer for {@link IndexSettingsSearch} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + IndexSettingsSearch::setupSettingsSearchDeserializer + ); + + protected static void setupSettingsSearchDeserializer(ObjectDeserializer op) { + + op.add(Builder::idle, SearchIdle._DESERIALIZER, "idle"); + op.add(Builder::slowlog, SearchSlowlog._DESERIALIZER, "slowlog"); + + } + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexingSlowlog.java b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexingSlowlog.java new file mode 100644 index 0000000000..8e00dd626b --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexingSlowlog.java @@ -0,0 +1,232 @@ +/* + * 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 B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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.client.opensearch.indices; + +import jakarta.json.stream.JsonGenerator; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.opensearch.client.json.JsonpDeserializable; +import org.opensearch.client.json.JsonpDeserializer; +import org.opensearch.client.json.JsonpMapper; +import org.opensearch.client.json.JsonpSerializable; +import org.opensearch.client.json.ObjectBuilderDeserializer; +import org.opensearch.client.json.ObjectDeserializer; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +@JsonpDeserializable +public class IndexingSlowlog implements JsonpSerializable { + @Nullable + private final String level; + + @Nullable + private final Integer source; + + @Nullable + private final Boolean reformat; + + @Nullable + private final IndexingSlowlogThresholds threshold; + + // --------------------------------------------------------------------------------------------- + + private IndexingSlowlog(Builder builder) { + + this.level = builder.level; + this.source = builder.source; + this.reformat = builder.reformat; + this.threshold = builder.threshold; + + } + + public static IndexingSlowlog of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * API name: {@code level} + */ + @Nullable + public final String level() { + return this.level; + } + + /** + * API name: {@code source} + */ + @Nullable + public final Integer source() { + return this.source; + } + + /** + * API name: {@code reformat} + */ + @Nullable + public final Boolean reformat() { + return this.reformat; + } + + /** + * API name: {@code threshold} + */ + @Nullable + public final IndexingSlowlogThresholds threshold() { + return this.threshold; + } + + /** + * Serialize this object to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartObject(); + serializeInternal(generator, mapper); + generator.writeEnd(); + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + if (this.level != null) { + generator.writeKey("level"); + generator.write(this.level); + + } + if (this.source != null) { + generator.writeKey("source"); + generator.write(this.source); + + } + if (this.reformat != null) { + generator.writeKey("reformat"); + generator.write(this.reformat); + + } + if (this.threshold != null) { + generator.writeKey("threshold"); + this.threshold.serialize(generator, mapper); + + } + + } + + // --------------------------------------------------------------------------------------------- + + /** + * Builder for {@link IndexingSlowlog}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + @Nullable + private String level; + + @Nullable + private Integer source; + + @Nullable + private Boolean reformat; + + @Nullable + private IndexingSlowlogThresholds threshold; + + /** + * API name: {@code level} + */ + public final Builder level(@Nullable String value) { + this.level = value; + return this; + } + + /** + * API name: {@code source} + */ + public final Builder source(@Nullable Integer value) { + this.source = value; + return this; + } + + /** + * API name: {@code reformat} + */ + public final Builder reformat(@Nullable Boolean value) { + this.reformat = value; + return this; + } + + /** + * API name: {@code threshold} + */ + public final Builder threshold(@Nullable IndexingSlowlogThresholds value) { + this.threshold = value; + return this; + } + + /** + * API name: {@code threshold} + */ + public final Builder threshold(Function> fn) { + return this.threshold(fn.apply(new IndexingSlowlogThresholds.Builder()).build()); + } + + /** + * Builds a {@link IndexingSlowlog}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public IndexingSlowlog build() { + _checkSingleUse(); + + return new IndexingSlowlog(this); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Json deserializer for {@link IndexingSlowlog} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + IndexingSlowlog::setupIndexingSlowlogSettingsDeserializer + ); + + protected static void setupIndexingSlowlogSettingsDeserializer(ObjectDeserializer op) { + + op.add(Builder::level, JsonpDeserializer.stringDeserializer(), "level"); + op.add(Builder::source, JsonpDeserializer.integerDeserializer(), "source"); + op.add(Builder::reformat, JsonpDeserializer.booleanDeserializer(), "reformat"); + op.add(Builder::threshold, IndexingSlowlogThresholds._DESERIALIZER, "threshold"); + + } + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexingSlowlogThresholds.java b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexingSlowlogThresholds.java new file mode 100644 index 0000000000..964625102f --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexingSlowlogThresholds.java @@ -0,0 +1,157 @@ +/* + * 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 B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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.client.opensearch.indices; + +import jakarta.json.stream.JsonGenerator; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.opensearch.client.json.JsonpDeserializable; +import org.opensearch.client.json.JsonpDeserializer; +import org.opensearch.client.json.JsonpMapper; +import org.opensearch.client.json.JsonpSerializable; +import org.opensearch.client.json.ObjectBuilderDeserializer; +import org.opensearch.client.json.ObjectDeserializer; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +@JsonpDeserializable +public class IndexingSlowlogThresholds implements JsonpSerializable { + @Nullable + private final SlowlogThresholdLevels index; + + // --------------------------------------------------------------------------------------------- + + private IndexingSlowlogThresholds(Builder builder) { + + this.index = builder.index; + + } + + public static IndexingSlowlogThresholds of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * The indexing slow log, similar in functionality to the search slow log. The + * log file name ends with _index_indexing_slowlog.json. Log and + * the thresholds are configured in the same way as the search slowlog. + *

+ * API name: {@code index} + */ + @Nullable + public final SlowlogThresholdLevels index() { + return this.index; + } + + /** + * Serialize this object to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartObject(); + serializeInternal(generator, mapper); + generator.writeEnd(); + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + if (this.index != null) { + generator.writeKey("index"); + this.index.serialize(generator, mapper); + + } + + } + + // --------------------------------------------------------------------------------------------- + + /** + * Builder for {@link IndexingSlowlogThresholds}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + @Nullable + private SlowlogThresholdLevels index; + + /** + * The indexing slow log, similar in functionality to the search slow log. The + * log file name ends with _index_indexing_slowlog.json. Log and + * the thresholds are configured in the same way as the search slowlog. + *

+ * API name: {@code index} + */ + public final Builder index(@Nullable SlowlogThresholdLevels value) { + this.index = value; + return this; + } + + /** + * The indexing slow log, similar in functionality to the search slow log. The + * log file name ends with _index_indexing_slowlog.json. Log and + * the thresholds are configured in the same way as the search slowlog. + *

+ * API name: {@code index} + */ + public final Builder index(Function> fn) { + return this.index(fn.apply(new SlowlogThresholdLevels.Builder()).build()); + } + + /** + * Builds a {@link IndexingSlowlogThresholds}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public IndexingSlowlogThresholds build() { + _checkSingleUse(); + + return new IndexingSlowlogThresholds(this); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Json deserializer for {@link IndexingSlowlogThresholds} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + IndexingSlowlogThresholds::setupIndexingSlowlogTresholdsDeserializer + ); + + protected static void setupIndexingSlowlogTresholdsDeserializer(ObjectDeserializer op) { + + op.add(Builder::index, SlowlogThresholdLevels._DESERIALIZER, "index"); + + } + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/indices/SearchIdle.java b/java-client/src/main/java/org/opensearch/client/opensearch/indices/SearchIdle.java new file mode 100644 index 0000000000..47a6ed7f5c --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/indices/SearchIdle.java @@ -0,0 +1,141 @@ +/* + * 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 B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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.client.opensearch.indices; + +import jakarta.json.stream.JsonGenerator; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.opensearch.client.json.*; +import org.opensearch.client.opensearch._types.Time; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +@JsonpDeserializable +public class SearchIdle implements JsonpSerializable { + @Nullable + private final Time after; + + // --------------------------------------------------------------------------------------------- + + private SearchIdle(Builder builder) { + + this.after = builder.after; + + } + + public static SearchIdle of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * API name: {@code after} + */ + @Nullable + public final Time after() { + return this.after; + } + + /** + * Serialize this object to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartObject(); + serializeInternal(generator, mapper); + generator.writeEnd(); + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + if (this.after != null) { + generator.writeKey("after"); + this.after.serialize(generator, mapper); + + } + + } + + // --------------------------------------------------------------------------------------------- + + /** + * Builder for {@link SearchIdle}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + @Nullable + private Time after; + + /** + * API name: {@code after} + */ + public final Builder after(@Nullable Time value) { + this.after = value; + return this; + } + + /** + * API name: {@code after} + */ + public final Builder after(Function> fn) { + return this.after(fn.apply(new Time.Builder()).build()); + } + + /** + * Builds a {@link SearchIdle}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public SearchIdle build() { + _checkSingleUse(); + + return new SearchIdle(this); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Json deserializer for {@link SearchIdle} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + SearchIdle::setupSearchIdleDeserializer + ); + + protected static void setupSearchIdleDeserializer(ObjectDeserializer op) { + + op.add(Builder::after, Time._DESERIALIZER, "after"); + + } + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/indices/SearchSlowlog.java b/java-client/src/main/java/org/opensearch/client/opensearch/indices/SearchSlowlog.java new file mode 100644 index 0000000000..33980acf33 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/indices/SearchSlowlog.java @@ -0,0 +1,170 @@ +/* + * 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 B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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.client.opensearch.indices; + +import jakarta.json.stream.JsonGenerator; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.opensearch.client.json.*; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +@JsonpDeserializable +public class SearchSlowlog implements JsonpSerializable { + @Nullable + private final String level; + + @Nullable + private final SearchSlowlogThresholds threshold; + + // --------------------------------------------------------------------------------------------- + + private SearchSlowlog(Builder builder) { + + this.level = builder.level; + this.threshold = builder.threshold; + + } + + public static SearchSlowlog of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * API name: {@code level} + */ + @Nullable + public final String level() { + return this.level; + } + + /** + * API name: {@code threshold} + */ + @Nullable + public final SearchSlowlogThresholds threshold() { + return this.threshold; + } + + /** + * Serialize this object to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartObject(); + serializeInternal(generator, mapper); + generator.writeEnd(); + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + if (this.level != null) { + generator.writeKey("level"); + generator.write(this.level); + + } + + if (this.threshold != null) { + generator.writeKey("threshold"); + this.threshold.serialize(generator, mapper); + + } + + } + + // --------------------------------------------------------------------------------------------- + + /** + * Builder for {@link SearchSlowlog}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + @Nullable + private String level; + + @Nullable + private SearchSlowlogThresholds threshold; + + /** + * API name: {@code level} + */ + public final Builder level(@Nullable String value) { + this.level = value; + return this; + } + + /** + * API name: {@code threshold} + */ + public final Builder threshold(@Nullable SearchSlowlogThresholds value) { + this.threshold = value; + return this; + } + + /** + * API name: {@code threshold} + */ + public final Builder threshold(Function> fn) { + return this.threshold(fn.apply(new SearchSlowlogThresholds.Builder()).build()); + } + + /** + * Builds a {@link SearchSlowlog}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public SearchSlowlog build() { + _checkSingleUse(); + + return new SearchSlowlog(this); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Json deserializer for {@link SearchSlowlog} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + SearchSlowlog::setupIndexingSlowlogSettingsDeserializer + ); + + protected static void setupIndexingSlowlogSettingsDeserializer(ObjectDeserializer op) { + + op.add(Builder::level, JsonpDeserializer.stringDeserializer(), "level"); + op.add(Builder::threshold, SearchSlowlogThresholds._DESERIALIZER, "threshold"); + + } + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/indices/SearchSlowlogThresholds.java b/java-client/src/main/java/org/opensearch/client/opensearch/indices/SearchSlowlogThresholds.java new file mode 100644 index 0000000000..6f7dfe9456 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/indices/SearchSlowlogThresholds.java @@ -0,0 +1,181 @@ +/* + * 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 B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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.client.opensearch.indices; + +import jakarta.json.stream.JsonGenerator; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.opensearch.client.json.JsonpDeserializable; +import org.opensearch.client.json.JsonpDeserializer; +import org.opensearch.client.json.JsonpMapper; +import org.opensearch.client.json.JsonpSerializable; +import org.opensearch.client.json.ObjectBuilderDeserializer; +import org.opensearch.client.json.ObjectDeserializer; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +@JsonpDeserializable +public class SearchSlowlogThresholds implements JsonpSerializable { + @Nullable + private final SlowlogThresholdLevels query; + + @Nullable + private final SlowlogThresholdLevels fetch; + + // --------------------------------------------------------------------------------------------- + + private SearchSlowlogThresholds(Builder builder) { + + this.query = builder.query; + this.fetch = builder.fetch; + + } + + public static SearchSlowlogThresholds of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * API name: {@code query} + */ + @Nullable + public final SlowlogThresholdLevels query() { + return this.query; + } + + /** + * API name: {@code fetch} + */ + @Nullable + public final SlowlogThresholdLevels fetch() { + return this.fetch; + } + + /** + * Serialize this object to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartObject(); + serializeInternal(generator, mapper); + generator.writeEnd(); + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + if (this.query != null) { + generator.writeKey("query"); + this.query.serialize(generator, mapper); + + } + if (this.fetch != null) { + generator.writeKey("fetch"); + this.fetch.serialize(generator, mapper); + + } + + } + + // --------------------------------------------------------------------------------------------- + + /** + * Builder for {@link SearchSlowlogThresholds}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + @Nullable + private SlowlogThresholdLevels query; + + @Nullable + private SlowlogThresholdLevels fetch; + + /** + * API name: {@code query} + */ + public final Builder query(@Nullable SlowlogThresholdLevels value) { + this.query = value; + return this; + } + + /** + * API name: {@code query} + */ + public final Builder query(Function> fn) { + return this.query(fn.apply(new SlowlogThresholdLevels.Builder()).build()); + } + + /** + * API name: {@code fetch} + */ + public final Builder fetch(@Nullable SlowlogThresholdLevels value) { + this.fetch = value; + return this; + } + + /** + * API name: {@code fetch} + */ + public final Builder fetch(Function> fn) { + return this.fetch(fn.apply(new SlowlogThresholdLevels.Builder()).build()); + } + + /** + * Builds a {@link SearchSlowlogThresholds}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public SearchSlowlogThresholds build() { + _checkSingleUse(); + + return new SearchSlowlogThresholds(this); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Json deserializer for {@link SearchSlowlogThresholds} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + SearchSlowlogThresholds::setupIndexingSlowlogTresholdsDeserializer + ); + + protected static void setupIndexingSlowlogTresholdsDeserializer(ObjectDeserializer op) { + + op.add(Builder::query, SlowlogThresholdLevels._DESERIALIZER, "query"); + op.add(Builder::fetch, SlowlogThresholdLevels._DESERIALIZER, "fetch"); + + } + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/indices/SlowlogThresholdLevels.java b/java-client/src/main/java/org/opensearch/client/opensearch/indices/SlowlogThresholdLevels.java new file mode 100644 index 0000000000..2534f75366 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/indices/SlowlogThresholdLevels.java @@ -0,0 +1,255 @@ +/* + * 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 B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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.client.opensearch.indices; + +import jakarta.json.stream.JsonGenerator; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.opensearch.client.json.JsonpDeserializable; +import org.opensearch.client.json.JsonpDeserializer; +import org.opensearch.client.json.JsonpMapper; +import org.opensearch.client.json.JsonpSerializable; +import org.opensearch.client.json.ObjectBuilderDeserializer; +import org.opensearch.client.json.ObjectDeserializer; +import org.opensearch.client.opensearch._types.Time; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +// typedef: indices._types.SlowlogTresholdLevels + +@JsonpDeserializable +public class SlowlogThresholdLevels implements JsonpSerializable { + @Nullable + private final Time warn; + + @Nullable + private final Time info; + + @Nullable + private final Time debug; + + @Nullable + private final Time trace; + + // --------------------------------------------------------------------------------------------- + + private SlowlogThresholdLevels(Builder builder) { + + this.warn = builder.warn; + this.info = builder.info; + this.debug = builder.debug; + this.trace = builder.trace; + + } + + public static SlowlogThresholdLevels of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * API name: {@code warn} + */ + @Nullable + public final Time warn() { + return this.warn; + } + + /** + * API name: {@code info} + */ + @Nullable + public final Time info() { + return this.info; + } + + /** + * API name: {@code debug} + */ + @Nullable + public final Time debug() { + return this.debug; + } + + /** + * API name: {@code trace} + */ + @Nullable + public final Time trace() { + return this.trace; + } + + /** + * Serialize this object to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartObject(); + serializeInternal(generator, mapper); + generator.writeEnd(); + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + if (this.warn != null) { + generator.writeKey("warn"); + this.warn.serialize(generator, mapper); + + } + if (this.info != null) { + generator.writeKey("info"); + this.info.serialize(generator, mapper); + + } + if (this.debug != null) { + generator.writeKey("debug"); + this.debug.serialize(generator, mapper); + + } + if (this.trace != null) { + generator.writeKey("trace"); + this.trace.serialize(generator, mapper); + + } + + } + + // --------------------------------------------------------------------------------------------- + + /** + * Builder for {@link SlowlogThresholdLevels}. + */ + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + @Nullable + private Time warn; + + @Nullable + private Time info; + + @Nullable + private Time debug; + + @Nullable + private Time trace; + + /** + * API name: {@code warn} + */ + public final Builder warn(@Nullable Time value) { + this.warn = value; + return this; + } + + /** + * API name: {@code warn} + */ + public final Builder warn(Function> fn) { + return this.warn(fn.apply(new Time.Builder()).build()); + } + + /** + * API name: {@code info} + */ + public final Builder info(@Nullable Time value) { + this.info = value; + return this; + } + + /** + * API name: {@code info} + */ + public final Builder info(Function> fn) { + return this.info(fn.apply(new Time.Builder()).build()); + } + + /** + * API name: {@code debug} + */ + public final Builder debug(@Nullable Time value) { + this.debug = value; + return this; + } + + /** + * API name: {@code debug} + */ + public final Builder debug(Function> fn) { + return this.debug(fn.apply(new Time.Builder()).build()); + } + + /** + * API name: {@code trace} + */ + public final Builder trace(@Nullable Time value) { + this.trace = value; + return this; + } + + /** + * API name: {@code trace} + */ + public final Builder trace(Function> fn) { + return this.trace(fn.apply(new Time.Builder()).build()); + } + + /** + * Builds a {@link SlowlogThresholdLevels}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public SlowlogThresholdLevels build() { + _checkSingleUse(); + + return new SlowlogThresholdLevels(this); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Json deserializer for {@link SlowlogThresholdLevels} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + SlowlogThresholdLevels::setupSlowlogTresholdLevelsDeserializer + ); + + protected static void setupSlowlogTresholdLevelsDeserializer(ObjectDeserializer op) { + + op.add(Builder::warn, Time._DESERIALIZER, "warn"); + op.add(Builder::info, Time._DESERIALIZER, "info"); + op.add(Builder::debug, Time._DESERIALIZER, "debug"); + op.add(Builder::trace, Time._DESERIALIZER, "trace"); + + } + +} diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/experiments/ParsingTests.java b/java-client/src/test/java/org/opensearch/client/opensearch/experiments/ParsingTests.java index 70a598a805..ab46a8418d 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/experiments/ParsingTests.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/experiments/ParsingTests.java @@ -48,7 +48,9 @@ import org.opensearch.client.opensearch.experiments.api.FooRequest; import org.opensearch.client.opensearch.indices.GetFieldMappingResponse; import org.opensearch.client.opensearch.indices.IndexSettings; +import org.opensearch.client.opensearch.indices.IndexSettingsIndexing; import org.opensearch.client.opensearch.indices.IndexSettingsMapping; +import org.opensearch.client.opensearch.indices.IndexSettingsSearch; import org.opensearch.client.opensearch.indices.Translog; import org.opensearch.client.opensearch.indices.get_field_mapping.TypeFieldMappings; import org.opensearch.client.opensearch.model.ModelTestCase; @@ -275,4 +277,84 @@ public void testTermvectorsResponseOptionals() { assertEquals(response.index(), response2.index()); } + @Test + public void testIndexSettingsIndexing() { + + var indexing = IndexSettingsIndexing.of( + is -> is.slowlog( + s -> s.level("info") + .source(0) + .threshold( + t -> t.index( + it -> it.debug(Time.of(ti -> ti.time("500ms"))) + .info(Time.of(ti -> ti.time("1000ms"))) + .trace(Time.of(ti -> ti.time("200ms"))) + .warn(Time.of(ti -> ti.time("5000ms"))) + ) + ) + ) + ); + + var str = toJson(indexing); + assertEquals( + "{\"slowlog\":{\"level\":\"info\",\"source\":0,\"threshold\":{\"index\":{" + + "\"warn\":\"5000ms\",\"info\":\"1000ms\",\"debug\":\"500ms\",\"trace\":\"200ms\"}}}}", + str + ); + + var deserialized = fromJson(str, IndexSettingsIndexing._DESERIALIZER); + assertEquals(indexing.slowlog().level(), deserialized.slowlog().level()); + assertEquals(indexing.slowlog().source(), deserialized.slowlog().source()); + assertEquals(indexing.slowlog().threshold().index().debug().time(), deserialized.slowlog().threshold().index().debug().time()); + assertEquals(indexing.slowlog().threshold().index().info().time(), deserialized.slowlog().threshold().index().info().time()); + assertEquals(indexing.slowlog().threshold().index().trace().time(), deserialized.slowlog().threshold().index().trace().time()); + assertEquals(indexing.slowlog().threshold().index().warn().time(), deserialized.slowlog().threshold().index().warn().time()); + + } + + @Test + public void testIndexSettingsSearch() { + + var search = IndexSettingsSearch.of( + is -> is.slowlog( + s -> s.level("info") + .threshold( + t -> t.query( + it -> it.debug(Time.of(ti -> ti.time("500ms"))) + .info(Time.of(ti -> ti.time("1000ms"))) + .trace(Time.of(ti -> ti.time("200ms"))) + .warn(Time.of(ti -> ti.time("5000ms"))) + ) + .fetch( + it -> it.debug(Time.of(ti -> ti.time("5ms"))) + .info(Time.of(ti -> ti.time("10ms"))) + .trace(Time.of(ti -> ti.time("2ms"))) + .warn(Time.of(ti -> ti.time("50ms"))) + ) + ) + ).idle(id -> id.after(a -> a.time("5s"))) + ); + + var str = toJson(search); + assertEquals( + "{\"idle\":{\"after\":\"5s\"},\"slowlog\":{\"level\":\"info\"," + + "\"threshold\":{\"query\":{\"warn\":\"5000ms\",\"info\":\"1000ms\",\"debug\":\"500ms\"," + + "\"trace\":\"200ms\"},\"fetch\":{\"warn\":\"50ms\",\"info\":\"10ms\",\"debug\":\"5ms\"," + + "\"trace\":\"2ms\"}}}}", + str + ); + + var deserialized = fromJson(str, IndexSettingsSearch._DESERIALIZER); + assertEquals(search.slowlog().level(), deserialized.slowlog().level()); + assertEquals(search.slowlog().threshold().query().debug().time(), deserialized.slowlog().threshold().query().debug().time()); + assertEquals(search.slowlog().threshold().query().info().time(), deserialized.slowlog().threshold().query().info().time()); + assertEquals(search.slowlog().threshold().query().trace().time(), deserialized.slowlog().threshold().query().trace().time()); + assertEquals(search.slowlog().threshold().query().warn().time(), deserialized.slowlog().threshold().query().warn().time()); + assertEquals(search.slowlog().threshold().fetch().debug().time(), deserialized.slowlog().threshold().fetch().debug().time()); + assertEquals(search.slowlog().threshold().fetch().info().time(), deserialized.slowlog().threshold().fetch().info().time()); + assertEquals(search.slowlog().threshold().fetch().trace().time(), deserialized.slowlog().threshold().fetch().trace().time()); + assertEquals(search.slowlog().threshold().fetch().warn().time(), deserialized.slowlog().threshold().fetch().warn().time()); + assertEquals(search.idle().after().time(), deserialized.idle().after().time()); + + } } diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractRequestIT.java b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractRequestIT.java index 8280cae0d1..ecfd9ff3aa 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractRequestIT.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractRequestIT.java @@ -139,6 +139,40 @@ public void testIndexSettings() throws Exception { .depth(f -> f.limit(3L)) .nestedObjects(f -> f.limit(9L)) ) + .indexing( + i -> i.slowlog( + sl -> sl.level("info") + .source(1000) + .reformat(false) + .threshold( + th -> th.index( + in -> in.trace(Time.of(t -> t.time("5s"))) + .debug(Time.of(t -> t.time("10s"))) + .info(Time.of(t -> t.time("20s"))) + .warn(Time.of(t -> t.time("30s"))) + ) + ) + ) + ) + .search( + i -> i.slowlog( + sl -> sl.level("info") + .threshold( + th -> th.query( + in -> in.trace(Time.of(t -> t.time("5s"))) + .debug(Time.of(t -> t.time("10s"))) + .info(Time.of(t -> t.time("20s"))) + .warn(Time.of(t -> t.time("30s"))) + ) + .fetch( + in -> in.trace(Time.of(t -> t.time("5s"))) + .debug(Time.of(t -> t.time("10s"))) + .info(Time.of(t -> t.time("20s"))) + .warn(Time.of(t -> t.time("30s"))) + ) + ) + ).idle(id -> id.after(a -> a.time("120s"))) + ) ) ); assertTrue(createResponse.acknowledged()); @@ -166,6 +200,35 @@ public void testIndexSettings() throws Exception { assertNotNull(createdMappingSettings.nestedObjects()); assertEquals(9L, (Object) createdMappingSettings.nestedObjects().limit()); + var createdIndexingSettings = createdIndexSettings.settings().index().indexing(); + assertNotNull(createdIndexingSettings); + assertNotNull(createdIndexingSettings.slowlog()); + assertEquals("info", createdIndexingSettings.slowlog().level()); + assertEquals(1000, (Object) createdIndexingSettings.slowlog().source()); + assertEquals(false, createdIndexingSettings.slowlog().reformat()); + assertNotNull(createdIndexingSettings.slowlog().threshold()); + assertNotNull(createdIndexingSettings.slowlog().threshold().index()); + assertEquals("5s", createdIndexingSettings.slowlog().threshold().index().trace().time()); + assertEquals("10s", createdIndexingSettings.slowlog().threshold().index().debug().time()); + assertEquals("20s", createdIndexingSettings.slowlog().threshold().index().info().time()); + assertEquals("30s", createdIndexingSettings.slowlog().threshold().index().warn().time()); + + var createdSearchSettings = createdIndexSettings.settings().index().search(); + assertNotNull(createdSearchSettings); + assertNotNull(createdSearchSettings.slowlog()); + assertEquals("info", createdSearchSettings.slowlog().level()); + assertNotNull(createdSearchSettings.slowlog().threshold()); + assertNotNull(createdSearchSettings.slowlog().threshold().query()); + assertEquals("5s", createdSearchSettings.slowlog().threshold().query().trace().time()); + assertEquals("10s", createdSearchSettings.slowlog().threshold().query().debug().time()); + assertEquals("20s", createdSearchSettings.slowlog().threshold().query().info().time()); + assertEquals("30s", createdSearchSettings.slowlog().threshold().query().warn().time()); + assertNotNull(createdSearchSettings.slowlog().threshold().fetch()); + assertEquals("5s", createdSearchSettings.slowlog().threshold().fetch().trace().time()); + assertEquals("10s", createdSearchSettings.slowlog().threshold().fetch().debug().time()); + assertEquals("20s", createdSearchSettings.slowlog().threshold().fetch().info().time()); + assertEquals("30s", createdSearchSettings.slowlog().threshold().fetch().warn().time()); + var putSettingsResponse = javaClient().indices() .putSettings( r -> r.index("test-settings") diff --git a/samples/src/main/java/org/opensearch/client/samples/IndexTemplates.java b/samples/src/main/java/org/opensearch/client/samples/IndexTemplates.java new file mode 100644 index 0000000000..e086652f7a --- /dev/null +++ b/samples/src/main/java/org/opensearch/client/samples/IndexTemplates.java @@ -0,0 +1,100 @@ +/* + * 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. + */ + +package org.opensearch.client.samples; + +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.client.opensearch._types.Time; +import org.opensearch.client.opensearch.cluster.PutComponentTemplateRequest; +import org.opensearch.client.opensearch.indices.*; + +/** + * Run with: ./gradlew :samples:run -Dsamples.mainClass=IndexTemplates + */ +public class IndexTemplates { + private static final Logger LOGGER = LogManager.getLogger(IndexTemplates.class); + + public static void main(String[] args) { + try { + var client = SampleClient.create(); + var version = client.info().version(); + LOGGER.info("Server: {}@{}", version.distribution(), version.number()); + + final var indexTemplateName = "my-index-template"; + + if (client.indices().existsIndexTemplate(t -> t.name(indexTemplateName)).value()) { + DeleteIndexTemplateRequest deleteIndexTemplateRequest = DeleteIndexTemplateRequest.of(i -> i.name(indexTemplateName)); + LOGGER.info("Deleting index template {}", indexTemplateName); + client.indices().deleteIndexTemplate(deleteIndexTemplateRequest); + } + + // Create an index template composed of two component templates, one for index settings, and one for mappings + final var indexSettingsComponentTemplate = "index-settings"; + PutComponentTemplateRequest putComponentTemplateRequest = PutComponentTemplateRequest.of( + c -> c.name(indexSettingsComponentTemplate) + .settings( + s -> s.numberOfShards("2") + .numberOfReplicas("1") + .indexing( + i -> i.slowlog( + sl -> sl.level("info") + .reformat(true) + .threshold(th -> th.index(ith -> ith.warn(Time.of(t -> t.time("2s"))))) + ) + ) + .search( + se -> se.slowlog(sl -> sl.level("info").threshold(th -> th.query(q -> q.warn(Time.of(t -> t.time("2s")))))) + ) + ) + ); + LOGGER.info("Creating component template {}", indexSettingsComponentTemplate); + client.cluster().putComponentTemplate(putComponentTemplateRequest); + + final var indexMappingsComponentTemplate = "index-mappings"; + putComponentTemplateRequest = PutComponentTemplateRequest.of( + c -> c.name(indexMappingsComponentTemplate).mappings(m -> m.properties("age", p -> p.integer(i -> i))) + ); + LOGGER.info("Creating component template {}", indexMappingsComponentTemplate); + client.cluster().putComponentTemplate(putComponentTemplateRequest); + + PutIndexTemplateRequest putIndexTemplateRequest = PutIndexTemplateRequest.of( + it -> it.name(indexTemplateName) + .indexPatterns("my-index-*") + .composedOf(List.of(indexSettingsComponentTemplate, indexMappingsComponentTemplate)) + ); + + LOGGER.info("Creating index template {}", indexTemplateName); + client.indices().putIndexTemplate(putIndexTemplateRequest); + + final var indexName = "my-index-1"; + if (client.indices().exists(r -> r.index(indexName)).value()) { + LOGGER.info("Deleting index {}", indexName); + client.indices().delete(DeleteIndexRequest.of(d -> d.index(indexName))); + } + + LOGGER.info("Creating index {}", indexName); + client.indices().create(CreateIndexRequest.of(c -> c.index(indexName))); + + GetMappingResponse getMappingResponse = client.indices().getMapping(GetMappingRequest.of(m -> m.index(indexName))); + // mappings for the index should contain those defined in component template + LOGGER.info("Mappings {} found for index {}", getMappingResponse.result().get(indexName).mappings(), indexName); + + GetIndicesSettingsResponse getSettingsResponse = client.indices() + .getSettings(GetIndicesSettingsRequest.of(m -> m.index(indexName))); + // settings for the index should contain those defined in component template + LOGGER.info("Settings {} found for index {}", getSettingsResponse.result().get(indexName).settings(), indexName); + + LOGGER.info("Deleting index {}", indexName); + client.indices().delete(DeleteIndexRequest.of(d -> d.index(indexName))); + } catch (Exception e) { + LOGGER.error("Unexpected exception", e); + } + } +}