From 4ceb43b00c314b6acba6d036132d1947d22b5f8d Mon Sep 17 00:00:00 2001 From: Harsha Vamsi Kalluri Date: Wed, 3 May 2023 14:13:15 -0700 Subject: [PATCH] Adds point in time APIs (#461) * Adds point in time APIs Signed-off-by: Harsha Vamsi Kalluri * Add version check for Point in time tests Signed-off-by: Harsha Vamsi Kalluri * Update point in time namespace Signed-off-by: Harsha Vamsi Kalluri * Update point in time to pit everywhere Signed-off-by: Harsha Vamsi Kalluri * Update USER_GUIDE.md Co-authored-by: Andriy Redko Signed-off-by: Harsha Vamsi Kalluri * Update USER_GUIDE.md Co-authored-by: Andriy Redko Signed-off-by: Harsha Vamsi Kalluri * Using AssumeTrue for tests for PIT Signed-off-by: Harsha Vamsi Kalluri --------- Signed-off-by: Harsha Vamsi Kalluri Co-authored-by: Andriy Redko --- CHANGELOG.md | 1 + USER_GUIDE.md | 54 ++- .../opensearch/OpenSearchAsyncClient.java | 84 +++++ .../client/opensearch/OpenSearchClient.java | 83 +++++ .../cat/OpenSearchCatAsyncClient.java | 14 + .../opensearch/cat/OpenSearchCatClient.java | 41 +++ .../opensearch/cat/PitSegmentsRequest.java | 107 ++++++ .../client/opensearch/core/SearchRequest.java | 31 ++ .../opensearch/core/pit/CreatePitRequest.java | 337 ++++++++++++++++++ .../core/pit/CreatePitResponse.java | 157 ++++++++ .../opensearch/core/pit/DeletePitRecord.java | 127 +++++++ .../opensearch/core/pit/DeletePitRequest.java | 129 +++++++ .../core/pit/DeletePitResponse.java | 125 +++++++ .../core/pit/ListAllPitRequest.java | 40 +++ .../core/pit/ListAllPitResponse.java | 125 +++++++ .../client/opensearch/core/pit/PitRecord.java | 153 ++++++++ .../client/opensearch/core/search/Pit.java | 127 +++++++ .../integTest/AbstractCatClientIT.java | 59 ++- .../integTest/AbstractRequestIT.java | 61 ++++ 19 files changed, 1844 insertions(+), 11 deletions(-) create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/cat/PitSegmentsRequest.java create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/core/pit/CreatePitRequest.java create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/core/pit/CreatePitResponse.java create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitRecord.java create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitRequest.java create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitResponse.java create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/core/pit/ListAllPitRequest.java create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/core/pit/ListAllPitResponse.java create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/core/pit/PitRecord.java create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/core/search/Pit.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 37dea9b86c08b..047746b776f4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Added - Document HTTP/2 support ([#330](https://github.com/opensearch-project/opensearch-java/pull/330)) +- Added Point-In-Time APIs ([#461](https://github.com/opensearch-project/opensearch-java/pull/461)) ### Dependencies diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 92f9fe70d2b57..740acc5a8cbcf 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -19,11 +19,16 @@ - [Create a data stream](#create-a-data-stream) - [Get data stream](#get-data-stream) - [Data stream stats](#data-stream-stats) - - [Delete data stream](#delete-data-stream-and-backing-indices) + - [Delete data stream and backing indices](#delete-data-stream-and-backing-indices) + - [Point-In-Time API](#point-in-time-api) + - [Creating a point in time](#creating-a-point-in-time) + - [List all point in time](#list-all-point-in-time) + - [Delete point in time](#delete-point-in-time) - [Cat API](#cat-api) - [Cat Indices](#cat-indices) - - [Cat Aliases](#cat-aliases) - - [Cat Nodes](#cat-nodes) + - [Cat aliases](#cat-aliases) + - [Cat nodes](#cat-nodes) + - [Cat point in time segments](#cat-point-in-time-segments) - [Using different transport options](#using-different-transport-options) - [Amazon OpenSearch Service](#amazon-opensearch-service) @@ -266,6 +271,42 @@ DeleteDataStreamRequest deleteDataStreamRequest = new DeleteDataStreamRequest.Bu DeleteDataStreamResponse deleteDataStreamResponse = javaClient().indices().deleteDataStream(deleteDataStreamRequest); ``` +## Point-In-Time API + +### Creating a point in time + +Creates a PIT. The keep_alive query parameter is required; it specifies how long to keep a PIT. + +```java +CreatePitRequest createPitRequest = new CreatePitRequest.Builder() + .targetIndexes(Collections.singletonList(index)) + .keepAlive(new Time.Builder().time("100m").build()).build(); + +CreatePitResponse createPitResponse = javaClient() + .createPit(createPitRequest); +``` + +### List all point in time + +Returns all PITs in the OpenSearch cluster. + +```java +ListAllPitResponse listAllPitResponse = javaClient().listAllPit(); +``` + +### Delete point in time + +Deletes one, several, or all PITs. PITs are automatically deleted when the keep_alive time period elapses. However, to deallocate resources, you can delete a PIT using the Delete PIT API. The Delete PIT API supports deleting a list of PITs by ID or deleting all PITs at once. + +```java +DeletePitRequest deletePitRequest = new DeletePitRequest.Builder() + .pitId(Collections.singletonList("pit_id")).build(); + +DeletePitResponse deletePitResponse = javaClient() + .deletePit(deletePitRequest); +``` + + ## Cat API ### Cat Indices @@ -291,6 +332,13 @@ The following sample code cat nodes sorted by cpu NodesResponse nodesResponse = javaClient().cat().nodes(r -> r.sort("cpu")); ``` +### Cat point in time segments +Similarly to the CAT Segments API, the PIT Segments API provides low-level information about the disk utilization of a PIT by describing its Lucene segments. +```java +SegmentsResponse pitSegmentsResponse = javaClient().cat() + .pitSegments(r -> r.headers("index,shard,id,segment,size")); +``` + # Using different transport options ## Amazon OpenSearch Service diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java index 56979730b1f0b..e6d5e3a35c046 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchAsyncClient.java @@ -116,6 +116,12 @@ import org.opensearch.client.opensearch.core.UpdateByQueryRethrottleResponse; import org.opensearch.client.opensearch.core.UpdateRequest; import org.opensearch.client.opensearch.core.UpdateResponse; +import org.opensearch.client.opensearch.core.pit.CreatePitRequest; +import org.opensearch.client.opensearch.core.pit.CreatePitResponse; +import org.opensearch.client.opensearch.core.pit.DeletePitRequest; +import org.opensearch.client.opensearch.core.pit.DeletePitResponse; +import org.opensearch.client.opensearch.core.pit.ListAllPitRequest; +import org.opensearch.client.opensearch.core.pit.ListAllPitResponse; import org.opensearch.client.opensearch.dangling_indices.OpenSearchDanglingIndicesAsyncClient; import org.opensearch.client.opensearch.features.OpenSearchFeaturesAsyncClient; import org.opensearch.client.opensearch.indices.OpenSearchIndicesAsyncClient; @@ -362,6 +368,39 @@ public final CompletableFuture create( return create(fn.apply(new CreateRequest.Builder()).build()); } + // ----- Endpoint: create_point_in_time + + /** + * Provides low-level information about the disk utilization of a PIT by + * describing its Lucene segments. + * + * + */ + + public CompletableFuture createPit(CreatePitRequest request) + throws IOException, OpenSearchException { + @SuppressWarnings("unchecked") + JsonEndpoint endpoint = (JsonEndpoint) CreatePitRequest._ENDPOINT; + + return this.transport.performRequestAsync(request, endpoint, this.transportOptions); + } + + /** + * Provides low-level information about the disk utilization of a PIT by + * describing its Lucene segments. + * + * @param fn + * a function that initializes a builder to create the + * {@link CreatePitRequest} + * + */ + + public final CompletableFuture createPit( + Function> fn) + throws IOException, OpenSearchException { + return createPit(fn.apply(new CreatePitRequest.Builder()).build()); + } + // ----- Endpoint: delete /** @@ -393,6 +432,37 @@ public final CompletableFuture delete( return delete(fn.apply(new DeleteRequest.Builder()).build()); } + // ----- Endpoint: delete_point_in_time + + /** + * Delete Point In Time + * + * + */ + + public CompletableFuture deletePit(DeletePitRequest request) + throws IOException, OpenSearchException { + @SuppressWarnings("unchecked") + JsonEndpoint endpoint = (JsonEndpoint) DeletePitRequest._ENDPOINT; + + return this.transport.performRequestAsync(request, endpoint, this.transportOptions); + } + + /** + * Delete Point In Time + * + * @param fn + * a function that initializes a builder to create the + * {@link DeletePitRequest} + * + */ + + public final CompletableFuture deletePit( + Function> fn) + throws IOException, OpenSearchException { + return deletePit(fn.apply(new DeletePitRequest.Builder()).build()); + } + // ----- Endpoint: delete_by_query /** @@ -801,6 +871,20 @@ public CompletableFuture info() throws IOException, OpenSearchExce return this.transport.performRequestAsync(InfoRequest._INSTANCE, InfoRequest._ENDPOINT, this.transportOptions); } + // ----- Endpoint: list_point_in_time + + /** + * List all Point In Time + * + * + */ + + public CompletableFuture listAllPit() + throws IOException, OpenSearchException { + return this.transport.performRequestAsync(ListAllPitRequest._INSTANCE, ListAllPitRequest._ENDPOINT, + this.transportOptions); + } + // ----- Endpoint: mget /** diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClient.java b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClient.java index 56ef79d5b19fc..12d3704293690 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClient.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/OpenSearchClient.java @@ -116,6 +116,12 @@ import org.opensearch.client.opensearch.core.UpdateByQueryRethrottleResponse; import org.opensearch.client.opensearch.core.UpdateRequest; import org.opensearch.client.opensearch.core.UpdateResponse; +import org.opensearch.client.opensearch.core.pit.CreatePitRequest; +import org.opensearch.client.opensearch.core.pit.CreatePitResponse; +import org.opensearch.client.opensearch.core.pit.DeletePitRequest; +import org.opensearch.client.opensearch.core.pit.DeletePitResponse; +import org.opensearch.client.opensearch.core.pit.ListAllPitRequest; +import org.opensearch.client.opensearch.core.pit.ListAllPitResponse; import org.opensearch.client.opensearch.dangling_indices.OpenSearchDanglingIndicesClient; import org.opensearch.client.opensearch.features.OpenSearchFeaturesClient; import org.opensearch.client.opensearch.indices.OpenSearchIndicesClient; @@ -359,6 +365,39 @@ public final CreateResponse create( return create(fn.apply(new CreateRequest.Builder()).build()); } + // ----- Endpoint: create_point_in_time + + /** + * Provides low-level information about the disk utilization of a PIT by + * describing its Lucene segments. + * + * + */ + + public CreatePitResponse createPit(CreatePitRequest request) + throws IOException, OpenSearchException { + @SuppressWarnings("unchecked") + JsonEndpoint endpoint = (JsonEndpoint) CreatePitRequest._ENDPOINT; + + return this.transport.performRequest(request, endpoint, this.transportOptions); + } + + /** + * Provides low-level information about the disk utilization of a PIT by + * describing its Lucene segments. + * + * @param fn + * a function that initializes a builder to create the + * {@link CreatePitRequest} + * + */ + + public final CreatePitResponse createPit( + Function> fn) + throws IOException, OpenSearchException { + return createPit(fn.apply(new CreatePitRequest.Builder()).build()); + } + // ----- Endpoint: delete /** @@ -389,6 +428,37 @@ public final DeleteResponse delete(Function endpoint = (JsonEndpoint) DeletePitRequest._ENDPOINT; + + return this.transport.performRequest(request, endpoint, this.transportOptions); + } + + /** + * Delete Point In Time + * + * @param fn + * a function that initializes a builder to create the + * {@link DeletePitRequest} + * + */ + + public final DeletePitResponse deletePit( + Function> fn) + throws IOException, OpenSearchException { + return deletePit(fn.apply(new DeletePitRequest.Builder()).build()); + } + // ----- Endpoint: delete_by_query /** @@ -790,6 +860,19 @@ public InfoResponse info() throws IOException, OpenSearchException { return this.transport.performRequest(InfoRequest._INSTANCE, InfoRequest._ENDPOINT, this.transportOptions); } + // ----- Endpoint: list_point_in_time + + /** + * List all Point In Time + * + * + */ + + public ListAllPitResponse listAllPit() + throws IOException, OpenSearchException { + return this.transport.performRequest(ListAllPitRequest._INSTANCE, ListAllPitRequest._ENDPOINT, this.transportOptions); + } + // ----- Endpoint: mget /** diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/cat/OpenSearchCatAsyncClient.java b/java-client/src/main/java/org/opensearch/client/opensearch/cat/OpenSearchCatAsyncClient.java index 98af262630934..41c82e73e66f2 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/cat/OpenSearchCatAsyncClient.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/cat/OpenSearchCatAsyncClient.java @@ -426,6 +426,20 @@ public CompletableFuture nodes() throws IOException, OpenSearchEx this.transportOptions); } + // ----- Endpoint: cat.point_in_time_segments + + /** + * Provides low-level information about the disk utilization of a PIT by + * describing its Lucene segments. + * + * + */ + public CompletableFuture pitSegments() throws IOException, OpenSearchException { + return this.transport.performRequestAsync(new PitSegmentsRequest.Builder().build(), + PitSegmentsRequest._ENDPOINT, + this.transportOptions); + } + // ----- Endpoint: cat.pending_tasks /** diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/cat/OpenSearchCatClient.java b/java-client/src/main/java/org/opensearch/client/opensearch/cat/OpenSearchCatClient.java index d714f411b1ba9..ea0d87bbdc992 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/cat/OpenSearchCatClient.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/cat/OpenSearchCatClient.java @@ -414,6 +414,47 @@ public NodesResponse nodes() throws IOException, OpenSearchException { this.transportOptions); } + // ----- Endpoint: cat.point_in_time_segments + + /** + * Provides low-level information about the disk utilization of a PIT by + * describing its Lucene segments. + * + * + */ + public SegmentsResponse pitSegments(PitSegmentsRequest request) + throws IOException, OpenSearchException { + @SuppressWarnings("unchecked") + JsonEndpoint endpoint = (JsonEndpoint) PitSegmentsRequest._ENDPOINT; + + return this.transport.performRequest(request, endpoint, this.transportOptions); + } + + /** + * Provides low-level information about the disk utilization of a PIT by + * describing its Lucene segments. + * + * * @param fn + * a function that initializes a builder to create the + * {@link PitSegmentsRequest} + */ + + public final SegmentsResponse pitSegments(Function> fn) + throws IOException, OpenSearchException { + return pitSegments(fn.apply(new PitSegmentsRequest.Builder()).build()); + } + + /** + * Provides low-level information about the disk utilization of a PIT by + * describing its Lucene segments. + * + */ + public SegmentsResponse pitSegments() throws IOException, OpenSearchException { + return this.transport.performRequest(new PitSegmentsRequest.Builder().build(), + PitSegmentsRequest._ENDPOINT, + this.transportOptions); + } + // ----- Endpoint: cat.pending_tasks /** diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/cat/PitSegmentsRequest.java b/java-client/src/main/java/org/opensearch/client/opensearch/cat/PitSegmentsRequest.java new file mode 100644 index 0000000000000..11b9c402b41bd --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/cat/PitSegmentsRequest.java @@ -0,0 +1,107 @@ +/* + * 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.opensearch.cat; + +import java.util.List; +import java.util.function.Function; + +import javax.annotation.Nullable; + +import org.opensearch.client.opensearch._types.ErrorResponse; +import org.opensearch.client.transport.Endpoint; +import org.opensearch.client.transport.endpoints.SimpleEndpoint; +import org.opensearch.client.util.ObjectBuilder; + +/** + * Provides low-level information about the disk utilization of a PIT by + * describing its Lucene segments + * + */ +public class PitSegmentsRequest extends CatRequestBase { + + @Nullable + private List pitId; + + public PitSegmentsRequest(Builder builder) { + this.pitId = builder.pitId; + } + + public static PitSegmentsRequest of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * A list of Pit IDs to get segments + *

+ * API name - {@code pit_id} + */ + @Nullable + public final List pitId() { + return this.pitId; + } + + /** + * Builder for {@link PitSegmentsRequest} + */ + public static class Builder extends CatRequestBaseBuilder { + private List pitId; + + /** + * A list of Pit IDs to get segments + *

+ * API name - {@code pit_id} + */ + public final Builder pitId(@Nullable List pitId) { + this.pitId = pitId; + return this; + } + + /** + * Builds a {@link PitSegmentsRequest}. + * + * @throws NullPointerException if some of the required fields are null. + */ + public PitSegmentsRequest build() { + _checkSingleUse(); + return new PitSegmentsRequest(this); + } + + @Override + protected Builder self() { + return this; + } + } + + /** + * Endpoint "{@code point_in_time_segments}" + */ + public static final Endpoint _ENDPOINT = new SimpleEndpoint<>( + // Request Method + request -> { + return "GET"; + }, + + // Request Path + request -> { + final int _all = 1 << 0; + + int propsSet = 0; + + if (request.pitId() == null) { + propsSet |= _all; + } + if (propsSet == 0) { + return "/_cat/pit_segments"; + } else { + return "/_cat/pit_segments/_all"; + } + }, + SimpleEndpoint.emptyMap(), SimpleEndpoint.emptyMap(), false, SegmentsResponse._DESERIALIZER); + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/SearchRequest.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/SearchRequest.java index f7822edd3a2fe..fe3627e74e465 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/core/SearchRequest.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/SearchRequest.java @@ -51,6 +51,7 @@ import org.opensearch.client.opensearch._types.query_dsl.Query; import org.opensearch.client.opensearch.core.search.FieldCollapse; import org.opensearch.client.opensearch.core.search.Highlight; +import org.opensearch.client.opensearch.core.search.Pit; import org.opensearch.client.opensearch.core.search.Rescore; import org.opensearch.client.opensearch.core.search.SourceConfig; import org.opensearch.client.opensearch.core.search.Suggester; @@ -152,6 +153,9 @@ public class SearchRequest extends RequestBase implements JsonpSerializable { @Nullable private final Double minScore; + @Nullable + private final Pit pit; + @Nullable private final Query postFilter; @@ -252,6 +256,7 @@ private SearchRequest(Builder builder) { this.maxConcurrentShardRequests = builder.maxConcurrentShardRequests; this.minCompatibleShardNode = builder.minCompatibleShardNode; this.minScore = builder.minScore; + this.pit = builder.pit; this.postFilter = builder.postFilter; this.preFilterShardSize = builder.preFilterShardSize; this.preference = builder.preference; @@ -547,6 +552,14 @@ public final Double minScore() { return this.minScore; } + /** + * API name: {@code pit} + */ + @Nullable + public final Pit pit() { + return this.pit; + } + /** * API name: {@code post_filter} */ @@ -902,6 +915,12 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { generator.write(this.minScore); } + + if (this.pit != null) { + generator.writeKey("pit"); + this.pit.serialize(generator, mapper); + } + if (this.postFilter != null) { generator.writeKey("post_filter"); this.postFilter.serialize(generator, mapper); @@ -1119,6 +1138,9 @@ public static class Builder extends ObjectBuilderBase implements ObjectBuilder targetIndexes; + + private Time keepAlive; + + @Nullable + private String preference; + + @Nullable + private String routing; + + @Nullable + private List expandWildcards; + + @Nullable + private Boolean allowPartialPitCreation; + + private CreatePitRequest(Builder builder) { + this.targetIndexes = ApiTypeHelper.unmodifiableRequired(builder.targetIndexes, this, "targetIndexes"); + this.keepAlive = ApiTypeHelper.requireNonNull(builder.keepAlive, this, "keepAlive"); + this.preference = builder.preference; + this.routing = builder.routing; + this.expandWildcards = ApiTypeHelper.unmodifiable(builder.expandWildcards); + this.allowPartialPitCreation = builder.allowPartialPitCreation; + } + + public static CreatePitRequest of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * Required - The name(s) of the target index(es) for the PIT. + * May contain a comma-separated list or a wildcard index pattern. + *

+ * API name: {@code target_indexes} + */ + public final List targetIndexes() { + return this.targetIndexes; + } + + /** + * Required - The amount of time to keep the PIT. Every time you access a PIT by + * using the + * Search API, the PIT lifetime is extended by the amount of time equal to the + * keep_alive parameter. + *

+ * API name: {@code keep_alive} + */ + public final Time keepAlive() { + return this.keepAlive; + } + + /** + * The node or the shard used to perform the search. Optional. Default is + * random. + *

+ * API name: {@code preference} + */ + @Nullable + public final String preference() { + return this.preference; + } + + /** + * Specifies to route search requests to a specific shard. Optional. Default is + * the document’s _id. + *

+ * API name: {@code routing} + */ + @Nullable + public final String routing() { + return this.routing; + } + + /** + * The type of index that can match the wildcard pattern. Supports + * comma-separated values. Valid values are the following: + * - all: Match any index or data stream, including hidden ones. + * - open: Match open, non-hidden indexes or non-hidden data streams. + * - closed: Match closed, non-hidden indexes or non-hidden data streams. + * - hidden: Match hidden indexes or data streams. Must be combined with open, + * closed or both open and closed. + * - none: No wildcard patterns are accepted. + * Optional. Default is open. + *

+ * API name: {@code expand_wildcards} + */ + @Nullable + public final List expandWildcards() { + return this.expandWildcards; + } + + /** + * Specifies whether to create a PIT with partial failures. Optional. Default is + * true. + *

+ * API name: {@code allow_partial_pit_creation} + */ + @Nullable + public final Boolean allowPartialPitCreation() { + return this.allowPartialPitCreation; + } + + /** + * Builder for {@link CreatePitRequest} + */ + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private List targetIndexes; + + private Time keepAlive; + + @Nullable + private String preference; + + @Nullable + private String routing; + + @Nullable + private List expandWildcards; + + @Nullable + private Boolean allowPartialPitCreation; + + /** + * Required - The name(s) of the target index(es) for the PIT. + * May contain a comma-separated list or a wildcard index pattern. + *

+ * API name: {@code target_indexes} + *

+ * Adds all elements of list to targetIndexes. + */ + public final Builder targetIndexes(List list) { + this.targetIndexes = _listAddAll(this.targetIndexes, list); + return this; + } + + /** + * Required - The name(s) of the target index(es) for the PIT. + * May contain a comma-separated list or a wildcard index pattern. + *

+ * API name: {@code target_indexes} + *

+ * Adds one or more values to targetIndexes. + */ + public final Builder targetIndexes(String value, String... values) { + this.targetIndexes = _listAdd(this.targetIndexes, value, values); + return this; + } + + /** + * Required - The amount of time to keep the PIT. Every time you access a PIT by + * using the + * Search API, the PIT lifetime is extended by the amount of time equal to the + * keep_alive parameter. + *

+ * API name: {@code keep_alive} + */ + public final Builder keepAlive(Time keepAlive) { + this.keepAlive = keepAlive; + return this; + } + + /** + * Required - The amount of time to keep the PIT. Every time you access a PIT by + * using the + * Search API, the PIT lifetime is extended by the amount of time equal to the + * keep_alive parameter. + *

+ * API name: {@code keep_alive} + */ + public final Builder keepAlive(Function> fn) { + return this.keepAlive(fn.apply(new Time.Builder()).build()); + } + + /** + * The node or the shard used to perform the search. Optional. Default is + * random. + *

+ * API name: {@code preference} + */ + public final Builder preference(@Nullable String preference) { + this.preference = preference; + return this; + } + + /** + * Specifies to route search requests to a specific shard. Optional. Default is + * the document’s _id. + *

+ * API name: {@code routing} + */ + public final Builder routing(@Nullable String routing) { + this.routing = routing; + return this; + } + + /** + * The type of index that can match the wildcard pattern. Supports + * comma-separated values. Valid values are the following: + * - all: Match any index or data stream, including hidden ones. + * - open: Match open, non-hidden indexes or non-hidden data streams. + * - closed: Match closed, non-hidden indexes or non-hidden data streams. + * - hidden: Match hidden indexes or data streams. Must be combined with open, + * closed or both open and closed. + * - none: No wildcard patterns are accepted. + * Optional. Default is open. + *

+ * API name: {@code expand_wildcards} + *

+ * Adds all elements of list to expandWildcards. + */ + public final Builder expandWildcards(@Nullable List list) { + this.expandWildcards = _listAddAll(this.expandWildcards, list); + return this; + } + + /** + * The type of index that can match the wildcard pattern. Supports + * comma-separated values. Valid values are the following: + * - all: Match any index or data stream, including hidden ones. + * - open: Match open, non-hidden indexes or non-hidden data streams. + * - closed: Match closed, non-hidden indexes or non-hidden data streams. + * - hidden: Match hidden indexes or data streams. Must be combined with open, + * closed or both open and closed. + * - none: No wildcard patterns are accepted. + * Optional. Default is open. + *

+ * API name: {@code expand_wildcards} + *

+ * Adds one or more values to expandWildcards. + */ + public final Builder expandWildcards(ExpandWildcard value, ExpandWildcard... values) { + this.expandWildcards = _listAdd(this.expandWildcards, value, values); + return this; + } + + /** + * Specifies whether to create a PIT with partial failures. Optional. Default is + * true. + *

+ * API name: {@code allow_partial_pit_creation} + */ + public final Builder allowPartialPitCreation(@Nullable Boolean allowPartialPitCreation) { + this.allowPartialPitCreation = allowPartialPitCreation; + return this; + } + + /** + * Builds a {@link CreatePitRequest}. + * + * @throws NullPointerException if some of the required fields are null. + */ + public CreatePitRequest build() { + _checkSingleUse(); + return new CreatePitRequest(this); + } + } + + public static final Endpoint _ENDPOINT = new SimpleEndpoint<>( + // Request method + request -> { + return "POST"; + }, + + // Request Path + request -> { + + final int _targetIndexes = 1 << 0; + + int propsSet = 0; + + propsSet |= _targetIndexes; + + if (propsSet == (_targetIndexes)) { + StringBuilder buf = new StringBuilder(); + buf.append("/"); + SimpleEndpoint.pathEncode( + request.targetIndexes.stream().map(v -> v).collect(Collectors.joining(",")), buf); + buf.append("/_search/point_in_time"); + return buf.toString(); + } + throw SimpleEndpoint.noPathTemplateFound("path"); + }, request -> { + Map params = new HashMap<>(); + params.put("keep_alive", request.keepAlive._toJsonString()); + + if (request.preference != null) { + params.put("preference", request.preference); + } + if (request.routing != null) { + params.put("routing", request.routing); + } + if (ApiTypeHelper.isDefined(request.expandWildcards)) { + params.put("expand_wildcards", + request.expandWildcards.stream() + .map(v -> v.jsonValue()).collect(Collectors.joining(","))); + } + if (request.allowPartialPitCreation != null) { + params.put("allow_partial_pit_creation", String.valueOf(request.allowPartialPitCreation)); + } + return params; + }, SimpleEndpoint.emptyMap(), false, CreatePitResponse._DESERIALIZER); +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/CreatePitResponse.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/CreatePitResponse.java new file mode 100644 index 0000000000000..4897a96477729 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/CreatePitResponse.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. + */ + +package org.opensearch.client.opensearch.core.pit; + +import java.util.function.Function; + +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.ShardStatistics; +import org.opensearch.client.util.ApiTypeHelper; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +import jakarta.json.stream.JsonGenerator; + + +@JsonpDeserializable +public class CreatePitResponse implements JsonpSerializable { + + private final String pitId; + + private final ShardStatistics shards; + + private final Long creationTime; + + private CreatePitResponse(Builder builder) { + this.pitId = ApiTypeHelper.requireNonNull(builder.pitId, this, "pitId"); + this.shards = ApiTypeHelper.requireNonNull(builder.shards, this, "shards"); + this.creationTime = ApiTypeHelper.requireNonNull(builder.creationTime, this, "creationTime"); + } + + public static CreatePitResponse of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * Required - API name: {@code pit_d} + */ + public final String pitId() { + return this.pitId; + } + + /** + * Required - API name: {@code _shards} + */ + public final ShardStatistics shards() { + return this.shards; + } + + /** + * Required - API name: {@code creation_time} + */ + public final Long creationTime() { + return this.creationTime; + } + + /** + * 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) { + + generator.writeKey("pit_id"); + generator.write(this.pitId); + + generator.writeKey("_shards"); + this.shards.serialize(generator, mapper); + + generator.writeKey("creation_time"); + generator.write(this.creationTime); + + } + + /** + * builder for {@link CreatePitResponse} + */ + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private String pitId; + + private ShardStatistics shards; + + private Long creationTime; + + /** + * Required - API name: {@code pit_id} + */ + public final Builder pitId(String pitId) { + this.pitId = pitId; + return this; + } + + /** + * Required - API name: {@code _shards} + */ + public final Builder shards(ShardStatistics value) { + this.shards = value; + return this; + } + + /** + * Required - API name: {@code _shards} + */ + public final Builder shards(Function> fn) { + return this.shards(fn.apply(new ShardStatistics.Builder()).build()); + } + + /** + * Required - API name: {@code creation_time} + */ + public final Builder creationTime(Long creationTime) { + this.creationTime = creationTime; + return this; + } + + /** + * Builds a {@link CreatePitResponse}. + * + * @throws NullPointerException if some of the required fields are null. + */ + public CreatePitResponse build() { + _checkSingleUse(); + + return new CreatePitResponse(this); + } + } + + /** + * Json deserializer for {@link CreatePitResponse} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer + .lazy(Builder::new, CreatePitResponse::setupCreatePitResponseDeserializer); + + protected static void setupCreatePitResponseDeserializer(ObjectDeserializer op) { + + op.add(Builder::pitId, JsonpDeserializer.stringDeserializer(), "pit_id"); + op.add(Builder::shards, + ShardStatistics._DESERIALIZER, + "_shards"); + op.add(Builder::creationTime, JsonpDeserializer.longDeserializer(), "creation_time"); + + } +} \ No newline at end of file diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitRecord.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitRecord.java new file mode 100644 index 0000000000000..f107f52e10abc --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitRecord.java @@ -0,0 +1,127 @@ +/* + * 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.opensearch.core.pit; + +import java.util.function.Function; + +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; + +import jakarta.json.stream.JsonGenerator; + +@JsonpDeserializable +public class DeletePitRecord implements JsonpSerializable { + + private final String pitId; + + private final Boolean successful; + + private DeletePitRecord(Builder builder) { + this.pitId = builder.pitId; + this.successful = builder.successful; + } + + public static DeletePitRecord of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * API name: {@code pit_id} + */ + public final String pitId() { + return this.pitId; + } + + /** + * API name: {@code successful} + */ + public final Boolean successful() { + return this.successful; + } + + /** + * 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.pitId != null) { + generator.writeKey("pit_id"); + generator.write(this.pitId); + + } + if (this.successful != null) { + generator.writeKey("successful"); + generator.write(this.successful); + + } + } + + /** + * Builder for {@link DeletePitRecord}. + */ + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private String pitId; + + private Boolean successful; + + /** + * API name: {@code pit_id} + */ + public final Builder pitId(String pitId) { + this.pitId = pitId; + return this; + } + + /** + * API name: {@code successful} + */ + public final Builder successful(Boolean successful) { + this.successful = successful; + return this; + } + + /** + * Builds a {@link DeletePitRecord}. + * + * @throws NullPointerException if some of the required fields are null. + */ + public DeletePitRecord build() { + _checkSingleUse(); + + return new DeletePitRecord(this); + } + } + + /** + * Json deserializer for {@link DeletePitRecord} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + DeletePitRecord::setupDeletePitRecordDeserializer); + + protected static void setupDeletePitRecordDeserializer( + ObjectDeserializer op) { + + op.add(Builder::pitId, JsonpDeserializer.stringDeserializer(), "pit_id"); + op.add(Builder::successful, JsonpDeserializer.booleanDeserializer(), "successful"); + + } +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitRequest.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitRequest.java new file mode 100644 index 0000000000000..5ad4a394478ea --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitRequest.java @@ -0,0 +1,129 @@ +/* + * 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.opensearch.core.pit; + +import java.util.List; +import java.util.function.Function; + +import javax.annotation.Nullable; + +import org.opensearch.client.json.JsonpMapper; +import org.opensearch.client.json.JsonpSerializable; +import org.opensearch.client.opensearch._types.ErrorResponse; +import org.opensearch.client.opensearch._types.RequestBase; +import org.opensearch.client.transport.Endpoint; +import org.opensearch.client.transport.endpoints.SimpleEndpoint; +import org.opensearch.client.util.ApiTypeHelper; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +import jakarta.json.stream.JsonGenerator; + + +/** + * Deletes PITs on the OpenSearch cluster + * + */ +public class DeletePitRequest extends RequestBase implements JsonpSerializable { + + @Nullable + private List pitId; + + public DeletePitRequest(Builder builder) { + this.pitId = builder.pitId; + } + + public static DeletePitRequest of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * A list of Pit IDs to be deleted + *

+ * API name - {@code pit_id} + */ + @Nullable + public final List pitId() { + return this.pitId; + } + + /** + * 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 (ApiTypeHelper.isDefined(this.pitId)) { + generator.writeKey("pit_id"); + generator.writeStartArray(); + for (String item0 : this.pitId) { + generator.write(item0); + } + generator.writeEnd(); + + } + + } + + /** + * Builder for {@link DeletePitRequest} + */ + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private List pitId; + + /** + * A list of Pit IDs to be deleted + *

+ * API name - {@code pit_id} + */ + public final Builder pitId(@Nullable List pitId) { + this.pitId = pitId; + return this; + } + + /** + * Builds a {@link DeletePitRequest}. + * + * @throws NullPointerException if some of the required fields are null. + */ + public DeletePitRequest build() { + _checkSingleUse(); + return new DeletePitRequest(this); + } + } + + public static final Endpoint _ENDPOINT = new SimpleEndpoint<>( + // Request Method + request -> { + return "DELETE"; + }, + + // Request Path + request -> { + final int _all = 1 << 0; + + int propsSet = 0; + + if (request.pitId() == null) { + propsSet |= _all; + } + if (propsSet == 0) { + return "/_search/point_in_time"; + } else { + return "/_search/point_in_time/_all"; + } + }, + SimpleEndpoint.emptyMap(), SimpleEndpoint.emptyMap(), true, DeletePitResponse._DESERIALIZER); + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitResponse.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitResponse.java new file mode 100644 index 0000000000000..bac4f55bd574e --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/DeletePitResponse.java @@ -0,0 +1,125 @@ +/* + * 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.opensearch.core.pit; + +import java.util.List; +import java.util.function.Function; + +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.ApiTypeHelper; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +import jakarta.json.stream.JsonGenerator; + +@JsonpDeserializable +public class DeletePitResponse implements JsonpSerializable { + private final List pits; + + private DeletePitResponse(Builder builder) { + this.pits = ApiTypeHelper.unmodifiableRequired(builder.pits, this, "pits"); + } + + public static DeletePitResponse of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * Required - Response value. + *

+ * API name: {@code pits} + */ + public final List pits() { + return this.pits; + } + + /** + * Serialize this value to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartArray(); + for (DeletePitRecord item0 : this.pits) { + item0.serialize(generator, mapper); + + } + generator.writeEnd(); + + } + + /** + * Builder for {@link DeletePitResponse}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private List pits; + + /** + * Required - Response value. + *

+ * API name: {@code pits} + *

+ * Adds all elements of list to pits. + */ + public final Builder pits(List list) { + this.pits = _listAddAll(this.pits, list); + return this; + } + + /** + * Required - Response value. + *

+ * API name: {@code pits} + *

+ * Adds one or more values to pits. + */ + public final Builder pits(DeletePitRecord value, DeletePitRecord... values) { + this.pits = _listAdd(this.pits, value, values); + return this; + } + + /** + * Required - Response value. + *

+ * API name: {@code pits} + *

+ * Adds a value to pits using a builder lambda. + */ + public final Builder pits(Function> fn) { + return pits(fn.apply(new DeletePitRecord.Builder()).build()); + } + + /** + * Builds a {@link DeletePitResponse}. + * + * @throws NullPointerException if some of the required fields are null. + */ + public DeletePitResponse build() { + _checkSingleUse(); + + return new DeletePitResponse(this); + } + } + + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer + .lazy(Builder::new, DeletePitResponse::createDeletePitResponseDeserializer); + + protected static void createDeletePitResponseDeserializer( + ObjectDeserializer op) { + + JsonpDeserializer> valueDeserializer = JsonpDeserializer + .arrayDeserializer(DeletePitRecord._DESERIALIZER); + + op.add(Builder::pits, valueDeserializer, "pits"); + } +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/ListAllPitRequest.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/ListAllPitRequest.java new file mode 100644 index 0000000000000..1391046f69801 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/ListAllPitRequest.java @@ -0,0 +1,40 @@ +/* + * 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.opensearch.core.pit; + +import org.opensearch.client.opensearch._types.ErrorResponse; +import org.opensearch.client.transport.Endpoint; +import org.opensearch.client.transport.endpoints.SimpleEndpoint; + + +/** + * Lists all PITs on the OpenSearch cluster + * + */ +public class ListAllPitRequest { + public ListAllPitRequest() { + + } + + /** + * Singleton instance for {@link ListAllPitRequest}. + */ + public static final ListAllPitRequest _INSTANCE = new ListAllPitRequest(); + + public static final Endpoint _ENDPOINT = new SimpleEndpoint<>( + // Request method + request -> { + return "GET"; + }, + + // Request Path + request -> { + return "/_search/point_in_time/_all"; + }, SimpleEndpoint.emptyMap(), SimpleEndpoint.emptyMap(), false, ListAllPitResponse._DESERIALIZER); +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/ListAllPitResponse.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/ListAllPitResponse.java new file mode 100644 index 0000000000000..8e3ce672b327b --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/ListAllPitResponse.java @@ -0,0 +1,125 @@ +/* + * 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.opensearch.core.pit; + +import java.util.List; +import java.util.function.Function; + +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.ApiTypeHelper; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +import jakarta.json.stream.JsonGenerator; + +@JsonpDeserializable +public class ListAllPitResponse implements JsonpSerializable { + private final List pits; + + private ListAllPitResponse(Builder builder) { + this.pits = ApiTypeHelper.unmodifiableRequired(builder.pits, this, "pits"); + } + + public static ListAllPitResponse of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * Required - Response value. + *

+ * API name: {@code _value_body} + */ + public final List pits() { + return this.pits; + } + + /** + * Serialize this value to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartArray(); + for (PitRecord item0 : this.pits) { + item0.serialize(generator, mapper); + + } + generator.writeEnd(); + + } + + /** + * Builder for {@link ListAllPitResponse}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private List pits; + + /** + * Required - Response value. + *

+ * API name: {@code _value_body} + *

+ * Adds all elements of list to pits. + */ + public final Builder pits(List list) { + this.pits = _listAddAll(this.pits, list); + return this; + } + + /** + * Required - Response value. + *

+ * API name: {@code _value_body} + *

+ * Adds one or more values to pits. + */ + public final Builder pits(PitRecord value, PitRecord... values) { + this.pits = _listAdd(this.pits, value, values); + return this; + } + + /** + * Required - Response value. + *

+ * API name: {@code _value_body} + *

+ * Adds a value to pits using a builder lambda. + */ + public final Builder pits(Function> fn) { + return pits(fn.apply(new PitRecord.Builder()).build()); + } + + /** + * Builds a {@link ListAllPitResponse}. + * + * @throws NullPointerException if some of the required fields are null. + */ + public ListAllPitResponse build() { + _checkSingleUse(); + + return new ListAllPitResponse(this); + } + } + + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer + .lazy(Builder::new, ListAllPitResponse::createListAllPitResponseDeserializer); + + protected static void createListAllPitResponseDeserializer( + ObjectDeserializer op) { + + JsonpDeserializer> valueDeserializer = JsonpDeserializer + .arrayDeserializer(PitRecord._DESERIALIZER); + + op.add(Builder::pits, valueDeserializer, "pits"); + } +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/PitRecord.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/PitRecord.java new file mode 100644 index 0000000000000..52ad829fbd476 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/pit/PitRecord.java @@ -0,0 +1,153 @@ +/* + * 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.opensearch.core.pit; + +import java.util.function.Function; + +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; + +import jakarta.json.stream.JsonGenerator; + +@JsonpDeserializable +public class PitRecord implements JsonpSerializable { + + private final String pitId; + + private final Long creationTime; + + private final Long keepAlive; + + private PitRecord(Builder builder) { + this.pitId = builder.pitId; + this.creationTime = builder.creationTime; + this.keepAlive = builder.keepAlive; + } + + public static PitRecord of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * API name: {@code pit_id} + */ + public final String pitId() { + return this.pitId; + } + + /** + * API name: {@code creation_time} + */ + public final Long creationTime() { + return this.creationTime; + } + + /** + * API name: {@code keep_alive} + */ + public final Long keepAlive() { + return this.keepAlive; + } + + /** + * 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.pitId != null) { + generator.writeKey("pit_id"); + generator.write(this.pitId); + + } + if (this.creationTime != null) { + generator.writeKey("creation_time"); + generator.write(this.creationTime); + + } + if (this.keepAlive != null) { + generator.writeKey("keep_alive"); + generator.write(this.keepAlive); + + } + } + + /** + * Builder for {@link PitRecord}. + */ + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private String pitId; + + private Long creationTime; + + private Long keepAlive; + + /** + * API name: {@code pit_id} + */ + public final Builder pitId(String pitId) { + this.pitId = pitId; + return this; + } + + /** + * API name: {@code creation_time} + */ + public final Builder creationTime(Long creationTime) { + this.creationTime = creationTime; + return this; + } + + /** + * API name: {@code keep_alive} + */ + public final Builder keepAlive(Long keepAlive) { + this.keepAlive = keepAlive; + return this; + } + + /** + * Builds a {@link PitRecord}. + * + * @throws NullPointerException if some of the required fields are null. + */ + public PitRecord build() { + _checkSingleUse(); + + return new PitRecord(this); + } + } + + /** + * Json deserializer for {@link PitRecord} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + PitRecord::setupPitRecordDeserializer); + + protected static void setupPitRecordDeserializer( + ObjectDeserializer op) { + + op.add(Builder::pitId, JsonpDeserializer.stringDeserializer(), "pit_id"); + op.add(Builder::creationTime, JsonpDeserializer.longDeserializer(), "creation_time"); + op.add(Builder::keepAlive, JsonpDeserializer.longDeserializer(), "keep_alive"); + + } +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/search/Pit.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/search/Pit.java new file mode 100644 index 0000000000000..acc4d47376629 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/search/Pit.java @@ -0,0 +1,127 @@ +/* + * 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.opensearch.core.search; + +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.ApiTypeHelper; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +import jakarta.json.stream.JsonGenerator; + +@JsonpDeserializable +public class Pit implements JsonpSerializable { + private final String id; + + @Nullable + private final String keepAlive; + + private Pit(Builder builder) { + this.id = ApiTypeHelper.requireNonNull(builder.id, this, "id"); + this.keepAlive = builder.keepAlive; + } + + public static Pit of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * Required - API name: {@code id} + */ + public final String id() { + return this.id; + } + + /** + * API name: {@code keep_alive} + */ + @Nullable + public final String keepAlive() { + return this.keepAlive; + } + + /** + * 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) { + generator.writeKey("id"); + generator.write(this.id); + + if (this.keepAlive != null) { + generator.writeKey("keep_alive"); + generator.write(this.keepAlive); + } + } + + /** + * Builder for {@link Pit}. + */ + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + + private String id; + + @Nullable + private String keepAlive; + + /** + * Required - API name: {@code id} + */ + public final Builder id(String id) { + this.id = id; + return this; + } + + /** + * API name: {@code keep_alive} + */ + public final Builder keepAlive(@Nullable String keepAlive) { + this.keepAlive = keepAlive; + return this; + } + + /** + * Builds a {@link Pit}. + * + * @throws NullPointerException if some of the required fields are null. + */ + public Pit build() { + _checkSingleUse(); + + return new Pit(this); + } + } + + /** + * Json deserializer for {@link Pit} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy(Builder::new, + Pit::setupPitDeserializer); + + protected static void setupPitDeserializer(ObjectDeserializer op) { + + op.add(Builder::id, JsonpDeserializer.stringDeserializer(), "id"); + op.add(Builder::keepAlive, JsonpDeserializer.stringDeserializer(), "keep_alive"); + } + +} diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractCatClientIT.java b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractCatClientIT.java index af9f9caeb0838..7c6b1cdee58f4 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractCatClientIT.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractCatClientIT.java @@ -8,9 +8,17 @@ package org.opensearch.client.opensearch.integTest; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.junit.Test; +import org.opensearch.Version; import org.opensearch.client.opensearch._types.Bytes; import org.opensearch.client.opensearch._types.Refresh; import org.opensearch.client.opensearch._types.Result; +import org.opensearch.client.opensearch._types.Time; import org.opensearch.client.opensearch.cat.AliasesResponse; import org.opensearch.client.opensearch.cat.AllocationResponse; import org.opensearch.client.opensearch.cat.IndicesResponse; @@ -27,12 +35,10 @@ import org.opensearch.client.opensearch.cat.segments.SegmentsRecord; import org.opensearch.client.opensearch.cat.shards.ShardsRecord; import org.opensearch.client.opensearch.core.IndexResponse; +import org.opensearch.client.opensearch.core.InfoResponse; +import org.opensearch.client.opensearch.core.pit.CreatePitResponse; import org.opensearch.client.opensearch.indices.CreateIndexResponse; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - public abstract class AbstractCatClientIT extends OpenSearchJavaClientTestCase { public void testCatNodes() throws Exception { @@ -188,10 +194,10 @@ public void testCatSegments() throws Exception { createIndex("cat-segments-test-index"); final IndexResponse index = javaClient().index(b -> b - .index("test-cat-segments-index") - .id("id") - .refresh(Refresh.True) - .document(Map.of("test-cat-segments-key", "test-cat-segments-value"))); + .index("test-cat-segments-index") + .id("id") + .refresh(Refresh.True) + .document(Map.of("test-cat-segments-key", "test-cat-segments-value"))); assertTrue(index.result() == Result.Created); @@ -209,6 +215,35 @@ public void testCatSegments() throws Exception { assertNull(segmentsRecord.ip()); assertNull(segmentsRecord.prirep()); } + + @Test + public void testCatPitSegments() throws Exception { + InfoResponse info = javaClient().info(); + String version = info.version().number(); + if (version.contains("SNAPSHOT")) { + version = version.split("-")[0]; + } + assumeTrue("The PIT is supported in OpenSearch 2.4.0 and later", + Version.fromString(version).onOrAfter(Version.fromString("2.4.0"))); + createIndex("cat-pit-segments-test-index"); + + final IndexResponse index = javaClient().index(b -> b + .index("test-cat-pit-segments-index") + .id("id") + .refresh(Refresh.True) + .document(Map.of("test-cat-pit-segments-key", "test-cat-pit-segments-value"))); + + assertTrue(index.result() == Result.Created); + + createPit("cat-pit-segments-test-index"); + + SegmentsResponse PitSegmentsResponse = javaClient().cat() + .pitSegments(r -> r.headers("index,shard,id,segment,size")); + + assertNotNull("PitSegmentsResponse.segments() is null", PitSegmentsResponse.valueBody()); + assertTrue("PitSegmentsResponse.segments().size() == 0", + PitSegmentsResponse.valueBody().size() > 0); + } private void createIndex(String indexName) throws Exception { CreateIndexResponse createResponse = javaClient().indices().create(b -> b.index(indexName)); @@ -216,4 +251,12 @@ private void createIndex(String indexName) throws Exception { assertTrue(createResponse.shardsAcknowledged()); } + private void createPit(String indexName) throws Exception { + CreatePitResponse createPitResponse = javaClient() + .createPit(r -> r.targetIndexes(Collections.singletonList(indexName)) + .keepAlive(new Time.Builder().time("100m").build())); + assertNotNull(createPitResponse); + assertNotNull(createPitResponse.pitId()); + } + } 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 586abd49d953f..0435cb9f720c5 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 @@ -38,6 +38,7 @@ import org.opensearch.client.opensearch._types.FieldValue; import org.opensearch.client.opensearch._types.OpenSearchException; import org.opensearch.client.opensearch._types.Refresh; +import org.opensearch.client.opensearch._types.Time; import org.opensearch.client.opensearch._types.aggregations.Aggregate; import org.opensearch.client.opensearch._types.aggregations.HistogramAggregate; import org.opensearch.client.opensearch._types.aggregations.TermsAggregation; @@ -55,6 +56,11 @@ import org.opensearch.client.opensearch.core.SearchResponse; import org.opensearch.client.opensearch.core.bulk.OperationType; import org.opensearch.client.opensearch.core.msearch.RequestItem; +import org.opensearch.client.opensearch.core.pit.CreatePitRequest; +import org.opensearch.client.opensearch.core.pit.CreatePitResponse; +import org.opensearch.client.opensearch.core.pit.DeletePitRequest; +import org.opensearch.client.opensearch.core.pit.DeletePitResponse; +import org.opensearch.client.opensearch.core.pit.ListAllPitResponse; import org.opensearch.client.opensearch.core.search.CompletionSuggester; import org.opensearch.client.opensearch.core.search.FieldSuggester; import org.opensearch.client.opensearch.core.search.FieldSuggesterBuilders; @@ -591,6 +597,61 @@ public void testCompletionSuggester() throws IOException { assertTrue(response.suggest().size() > 0); } + @Test + public void testPit() throws IOException { + InfoResponse info = javaClient().info(); + String version = info.version().number(); + if (version.contains("SNAPSHOT")) { + version = version.split("-")[0]; + } + assumeTrue("The PIT is supported in OpenSearch 2.4.0 and later", + Version.fromString(version).onOrAfter(Version.fromString("2.4.0"))); + String index = "test-point-in-time"; + + javaClient().indices().create(c -> c + .index(index)); + + AppData appData = new AppData(); + appData.setIntValue(1337); + appData.setMsg("foo"); + + javaClient().index(b -> b + .index(index) + .id("1") + .document(appData) + .refresh(Refresh.True)); + + CreatePitRequest createPitRequest = new CreatePitRequest.Builder() + .targetIndexes(Collections.singletonList(index)) + .keepAlive(new Time.Builder().time("100m").build()).build(); + + CreatePitResponse createPitResponse = javaClient() + .createPit(createPitRequest); + + assertNotNull(createPitResponse); + assertNotNull(createPitResponse.pitId()); + assertEquals(createPitResponse.shards().total(), + createPitResponse.shards().successful()); + + ListAllPitResponse listAllPitResponse = javaClient().listAllPit(); + + assertNotNull(listAllPitResponse); + assertNotNull(listAllPitResponse.pits()); + assertEquals(listAllPitResponse.pits().get(0).pitId(), createPitResponse.pitId()); + assertEquals(listAllPitResponse.pits().get(0).keepAlive(), Long.valueOf(6000000L)); + + DeletePitRequest deletePitRequest = new DeletePitRequest.Builder() + .pitId(Collections.singletonList(createPitResponse.pitId())).build(); + + DeletePitResponse deletePitResponse = javaClient() + .deletePit(deletePitRequest); + + assertNotNull(deletePitResponse); + assertNotNull(deletePitResponse.pits()); + assertEquals(deletePitResponse.pits().get(0).pitId(), createPitResponse.pitId()); + assertTrue(deletePitResponse.pits().get(0).successful()); + } + // @Test // public void testValueBodyResponse() throws Exception { // DiskUsageResponse resp = highLevelClient().indices().diskUsage(b -> b