diff --git a/.github/workflows/gradle-check.yml b/.github/workflows/gradle-check.yml
index 34742fbafe041..e72765e68fb13 100644
--- a/.github/workflows/gradle-check.yml
+++ b/.github/workflows/gradle-check.yml
@@ -94,7 +94,9 @@ jobs:
### Gradle Check (Jenkins) Run Completed with:
* **RESULT:** ${{ env.result }} :x:
* **FAILURES:**
+ ```
${{ env.test_failures }}
+ ```
* **URL:** ${{ env.workflow_url }}
* **CommitID:** ${{ env.pr_from_sha }}
Please examine the workflow log, locate, and copy-paste the failure below, then iterate to green.
diff --git a/.idea/runConfigurations/Debug_OpenSearch.xml b/.idea/runConfigurations/Debug_OpenSearch.xml
index 0d8bf59823acf..c18046f873477 100644
--- a/.idea/runConfigurations/Debug_OpenSearch.xml
+++ b/.idea/runConfigurations/Debug_OpenSearch.xml
@@ -6,6 +6,10 @@
+
+
+
+
-
+
\ No newline at end of file
diff --git a/client/rest-high-level/src/main/java/org/opensearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/opensearch/client/RequestConverters.java
index 88e3a3a904830..70a18ff85374f 100644
--- a/client/rest-high-level/src/main/java/org/opensearch/client/RequestConverters.java
+++ b/client/rest-high-level/src/main/java/org/opensearch/client/RequestConverters.java
@@ -53,12 +53,7 @@
import org.opensearch.action.get.GetRequest;
import org.opensearch.action.get.MultiGetRequest;
import org.opensearch.action.index.IndexRequest;
-import org.opensearch.action.search.ClearScrollRequest;
-import org.opensearch.action.search.CreatePitRequest;
-import org.opensearch.action.search.DeletePitRequest;
-import org.opensearch.action.search.MultiSearchRequest;
-import org.opensearch.action.search.SearchRequest;
-import org.opensearch.action.search.SearchScrollRequest;
+import org.opensearch.action.search.*;
import org.opensearch.action.support.ActiveShardCount;
import org.opensearch.action.support.IndicesOptions;
import org.opensearch.action.support.WriteRequest;
@@ -502,6 +497,11 @@ static Request getAllPits() {
return new Request(HttpGet.METHOD_NAME, "/_search/point_in_time/_all");
}
+ static Request updatePit(UpdatePitRequest updatePitRequest) throws IOException {
+ Request request = new Request(HttpDelete.METHOD_NAME, "/_search/point_in_time");
+ request.setEntity(createEntity(updatePitRequest, REQUEST_BODY_CONTENT_TYPE));
+ return request;
+ }
static Request multiSearch(MultiSearchRequest multiSearchRequest) throws IOException {
Request request = new Request(HttpPost.METHOD_NAME, "/_msearch");
diff --git a/client/rest-high-level/src/main/java/org/opensearch/client/RestHighLevelClient.java b/client/rest-high-level/src/main/java/org/opensearch/client/RestHighLevelClient.java
index 27f13fc3c00c4..4852b2138ae1a 100644
--- a/client/rest-high-level/src/main/java/org/opensearch/client/RestHighLevelClient.java
+++ b/client/rest-high-level/src/main/java/org/opensearch/client/RestHighLevelClient.java
@@ -57,18 +57,7 @@
import org.opensearch.action.get.MultiGetResponse;
import org.opensearch.action.index.IndexRequest;
import org.opensearch.action.index.IndexResponse;
-import org.opensearch.action.search.ClearScrollRequest;
-import org.opensearch.action.search.ClearScrollResponse;
-import org.opensearch.action.search.CreatePitRequest;
-import org.opensearch.action.search.CreatePitResponse;
-import org.opensearch.action.search.DeletePitRequest;
-import org.opensearch.action.search.DeletePitResponse;
-import org.opensearch.action.search.GetAllPitNodesResponse;
-import org.opensearch.action.search.MultiSearchRequest;
-import org.opensearch.action.search.MultiSearchResponse;
-import org.opensearch.action.search.SearchRequest;
-import org.opensearch.action.search.SearchResponse;
-import org.opensearch.action.search.SearchScrollRequest;
+import org.opensearch.action.search.*;
import org.opensearch.action.support.master.AcknowledgedResponse;
import org.opensearch.action.update.UpdateRequest;
import org.opensearch.action.update.UpdateResponse;
@@ -1403,6 +1392,16 @@ public final Cancellable getAllPitsAsync(RequestOptions options, ActionListener<
);
}
+ public final UpdatePitResponse updatePit(UpdatePitRequest updatePitRequest, RequestOptions options) throws IOException {
+ return performRequestAndParseEntity(
+ updatePitRequest,
+ RequestConverters::updatePit,
+ options,
+ UpdatePitResponse::fromXContent,
+ emptySet()
+ );
+ }
+
/**
* Clears one or more scroll ids using the Clear Scroll API.
*
diff --git a/client/rest-high-level/src/test/java/org/opensearch/client/PitIT.java b/client/rest-high-level/src/test/java/org/opensearch/client/PitIT.java
index 1f10deb400ecc..c2b48b692c61e 100644
--- a/client/rest-high-level/src/test/java/org/opensearch/client/PitIT.java
+++ b/client/rest-high-level/src/test/java/org/opensearch/client/PitIT.java
@@ -32,7 +32,7 @@
* Tests point in time API with rest high level client
*/
public class PitIT extends OpenSearchRestHighLevelClientTestCase {
-
+//--this is is PITIT
@Before
public void indexDocuments() throws IOException {
Request doc1 = new Request(HttpPut.METHOD_NAME, "/index/_doc/1");
diff --git a/server/src/main/java/org/opensearch/action/ActionModule.java b/server/src/main/java/org/opensearch/action/ActionModule.java
index 84bc9b395c5dc..b48c7cbdf2e8c 100644
--- a/server/src/main/java/org/opensearch/action/ActionModule.java
+++ b/server/src/main/java/org/opensearch/action/ActionModule.java
@@ -247,20 +247,7 @@
import org.opensearch.action.ingest.SimulatePipelineTransportAction;
import org.opensearch.action.main.MainAction;
import org.opensearch.action.main.TransportMainAction;
-import org.opensearch.action.search.ClearScrollAction;
-import org.opensearch.action.search.CreatePitAction;
-import org.opensearch.action.search.DeletePitAction;
-import org.opensearch.action.search.MultiSearchAction;
-import org.opensearch.action.search.GetAllPitsAction;
-import org.opensearch.action.search.SearchAction;
-import org.opensearch.action.search.SearchScrollAction;
-import org.opensearch.action.search.TransportClearScrollAction;
-import org.opensearch.action.search.TransportCreatePitAction;
-import org.opensearch.action.search.TransportDeletePitAction;
-import org.opensearch.action.search.TransportGetAllPitsAction;
-import org.opensearch.action.search.TransportMultiSearchAction;
-import org.opensearch.action.search.TransportSearchAction;
-import org.opensearch.action.search.TransportSearchScrollAction;
+import org.opensearch.action.search.*;
import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.AutoCreateIndex;
import org.opensearch.action.support.DestructiveOperations;
@@ -699,7 +686,7 @@ public void reg
actions.register(DeletePitAction.INSTANCE, TransportDeletePitAction.class);
actions.register(PitSegmentsAction.INSTANCE, TransportPitSegmentsAction.class);
actions.register(GetAllPitsAction.INSTANCE, TransportGetAllPitsAction.class);
-
+ // TODO: register the api here
// Remote Store
actions.register(RestoreRemoteStoreAction.INSTANCE, TransportRestoreRemoteStoreAction.class);
@@ -890,6 +877,7 @@ public void initRestHandlers(Supplier nodesInCluster) {
registerHandler.accept(new RestGetAllPitsAction(nodesInCluster));
registerHandler.accept(new RestPitSegmentsAction(nodesInCluster));
registerHandler.accept(new RestDeleteDecommissionStateAction());
+ // TODO: add update api here
for (ActionPlugin plugin : actionPlugins) {
for (RestHandler handler : plugin.getRestHandlers(
diff --git a/server/src/main/java/org/opensearch/action/search/CreatePitController.java b/server/src/main/java/org/opensearch/action/search/CreatePitController.java
index 745139fd1f1e8..97242d0afde0c 100644
--- a/server/src/main/java/org/opensearch/action/search/CreatePitController.java
+++ b/server/src/main/java/org/opensearch/action/search/CreatePitController.java
@@ -254,6 +254,7 @@ void executeUpdatePitId(
}, updatePitIdListener::onFailure);
}
+
private StepListener> getConnectionLookupListener(SearchContextId contextId) {
ClusterState state = clusterService.state();
final Set clusters = contextId.shards()
diff --git a/server/src/main/java/org/opensearch/action/search/SearchTransportService.java b/server/src/main/java/org/opensearch/action/search/SearchTransportService.java
index 8cf92ae5a23d8..15aaccde20993 100644
--- a/server/src/main/java/org/opensearch/action/search/SearchTransportService.java
+++ b/server/src/main/java/org/opensearch/action/search/SearchTransportService.java
@@ -160,6 +160,22 @@ public void updatePitContext(
);
}
+ public void updatePitContext(
+ Transport.Connection connection,
+ TransportUpdatePitAction.UpdateReaderContextRequest request,
+ SearchTask task,
+ ActionListener actionListener
+ ) {
+ transportService.sendChildRequest(
+ connection,
+ UPDATE_READER_CONTEXT_ACTION_NAME,
+ request,
+ task,
+ TransportRequestOptions.EMPTY,
+ new ActionListenerResponseHandler<>(actionListener, TransportUpdatePitAction.UpdateReaderContextResponse::new)
+ );
+ }
+
public void createPitContext(
Transport.Connection connection,
TransportCreatePitAction.CreateReaderContextRequest request,
diff --git a/server/src/main/java/org/opensearch/action/search/TransportUpdatePitAction.java b/server/src/main/java/org/opensearch/action/search/TransportUpdatePitAction.java
new file mode 100644
index 0000000000000..e300ed69fcaa7
--- /dev/null
+++ b/server/src/main/java/org/opensearch/action/search/TransportUpdatePitAction.java
@@ -0,0 +1,112 @@
+/*
+ * 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.action.search;
+
+import org.apache.logging.log4j.message.ParameterizedMessage;
+import org.opensearch.action.ActionListener;
+import org.opensearch.action.StepListener;
+import org.opensearch.action.support.ActionFilters;
+import org.opensearch.action.support.HandledTransportAction;
+import org.opensearch.cluster.service.ClusterService;
+import org.opensearch.common.inject.Inject;
+import org.opensearch.common.io.stream.NamedWriteableRegistry;
+import org.opensearch.common.io.stream.StreamInput;
+import org.opensearch.common.io.stream.StreamOutput;
+import org.opensearch.common.unit.TimeValue;
+import org.opensearch.index.shard.ShardId;
+import org.opensearch.search.SearchPhaseResult;
+import org.opensearch.search.internal.ShardSearchContextId;
+import org.opensearch.tasks.Task;
+import org.opensearch.transport.TransportRequest;
+import org.opensearch.transport.TransportService;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+public class TransportUpdatePitAction extends HandledTransportAction {
+
+ public static final String UPDATE_PIT_ACTION = "update_pit";
+ private final TransportService transportService;
+ private final SearchTransportService searchTransportService;
+ private final ClusterService clusterService;
+ private final TransportSearchAction transportSearchAction;
+ private final NamedWriteableRegistry namedWriteableRegistry;
+ private final UpdatePitController updatePitController;
+
+ @Inject
+ public TransportUpdatePitAction(
+ TransportService transportService,
+ ActionFilters actionFilters,
+ SearchTransportService searchTransportService,
+ ClusterService clusterService,
+ TransportSearchAction transportSearchAction,
+ NamedWriteableRegistry namedWriteableRegistry,
+ UpdatePitController updatePitController
+ ) {
+ super(UpdatePitAction.NAME, transportService, actionFilters, in -> new UpdatePitRequest(in));
+ this.transportService = transportService;
+ this.searchTransportService = searchTransportService;
+ this.clusterService = clusterService;
+ this.transportSearchAction = transportSearchAction;
+ this.namedWriteableRegistry = namedWriteableRegistry;
+ this.updatePitController = updatePitController;
+ }
+
+ @Override
+ protected void doExecute(Task task, UpdatePitRequest request, ActionListener listener) {
+ final StepListener updatePitListener = new StepListener<>();
+ updatePitController.executeUpdatePit(request, task, updatePitListener);
+ }
+
+ public static class UpdateReaderContextRequest extends TransportRequest {
+ private final ShardId shardId;
+ private final TimeValue keepAlive;
+
+ public UpdateReaderContextRequest(ShardId shardId, TimeValue keepAlive){
+ this.shardId = shardId;
+ this.keepAlive = keepAlive;
+ }
+
+ public ShardId getShardId() { return shardId;}
+
+ public TimeValue getKeepAlive() {
+ return keepAlive;
+ }
+
+ public UpdateReaderContextRequest(StreamInput in) throws IOException {
+ super(in);
+ this.shardId = new ShardId(in);
+ this.keepAlive = in.readTimeValue();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ shardId.writeTo(out);
+ out.writeTimeValue(keepAlive);
+ }
+ }
+
+ public static class UpdateReaderContextResponse extends SearchPhaseResult {
+ public UpdateReaderContextResponse(ShardSearchContextId shardSearchContextId){
+ this.contextId = shardSearchContextId;
+ }
+
+ public UpdateReaderContextResponse(StreamInput in) throws IOException {
+ super(in);
+ contextId = new ShardSearchContextId(in);
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ contextId.writeTo(out);
+ }
+ }
+}
diff --git a/server/src/main/java/org/opensearch/action/search/UpdatePitAction.java b/server/src/main/java/org/opensearch/action/search/UpdatePitAction.java
new file mode 100644
index 0000000000000..01dff89def026
--- /dev/null
+++ b/server/src/main/java/org/opensearch/action/search/UpdatePitAction.java
@@ -0,0 +1,20 @@
+/*
+ * 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.action.search;
+
+import org.opensearch.action.ActionType;
+
+public class UpdatePitAction extends ActionType {
+ public static final UpdatePitAction INSTANCE = new UpdatePitAction();
+ public static final String NAME = "indices:data/read/point_in_time/update";
+
+ private UpdatePitAction(){
+ super(NAME, UpdatePitResponse::new);
+ }
+}
diff --git a/server/src/main/java/org/opensearch/action/search/UpdatePitController.java b/server/src/main/java/org/opensearch/action/search/UpdatePitController.java
new file mode 100644
index 0000000000000..5c8aedcac97d5
--- /dev/null
+++ b/server/src/main/java/org/opensearch/action/search/UpdatePitController.java
@@ -0,0 +1,126 @@
+/*
+ * 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.action.search;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.message.ParameterizedMessage;
+import org.opensearch.OpenSearchException;
+import org.opensearch.action.ActionListener;
+import org.opensearch.action.StepListener;
+import org.opensearch.cluster.node.DiscoveryNode;
+import org.opensearch.cluster.service.ClusterService;
+import org.opensearch.common.inject.Inject;
+import org.opensearch.common.io.stream.NamedWriteableRegistry;
+import org.opensearch.index.shard.ShardId;
+import org.opensearch.search.SearchPhaseResult;
+import org.opensearch.search.SearchShardTarget;
+import org.opensearch.search.builder.PointInTimeBuilder;
+import org.opensearch.search.builder.SearchSourceBuilder;
+import org.opensearch.tasks.Task;
+import org.opensearch.transport.Transport;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.function.BiFunction;
+
+public class UpdatePitController {
+
+ private final SearchTransportService searchTransportService;
+ private final ClusterService clusterService;
+ private final TransportSearchAction transportSearchAction;
+ private final NamedWriteableRegistry namedWriteableRegistry;
+ private final PitService pitService;
+
+ private static final Logger logger = LogManager.getLogger(UpdatePitController.class);
+
+ @Inject
+ public UpdatePitController(
+ SearchTransportService searchTransportService,
+ ClusterService clusterService,
+ TransportSearchAction transportSearchAction,
+ NamedWriteableRegistry namedWriteableRegistry,
+ PitService pitService
+ ){
+ this.searchTransportService = searchTransportService;
+ this.clusterService = clusterService;
+ this.transportSearchAction = transportSearchAction;
+ this.namedWriteableRegistry = namedWriteableRegistry;
+ this.pitService = pitService;
+ }
+
+ public void executeUpdatePit(
+ UpdatePitRequest request,
+ Task task,
+ StepListener updatePitListener
+ ) {
+ // we need a searchsource builder since the search source builder has the PIT
+ // public SearchSourceBuilder pointInTimeBuilder(PointInTimeBuilder builder) {
+ // this.pointInTimeBuilder = builder;
+ // return this;
+ // }
+
+ // Set the Point in time ID in the search request
+ SearchRequest searchRequest = new SearchRequest().source(
+ new SearchSourceBuilder().pointInTimeBuilder(new PointInTimeBuilder(request.getPitRequestInfo().getPitId(), request.getPitRequestInfo().getKeepAlive())));
+ SearchTask searchTask = searchRequest.createTask(
+ task.getId(),
+ task.getType(),
+ task.getAction(),
+ task.getParentTaskId(),
+ Collections.emptyMap()
+ );
+ /**
+ * This is needed for cross cluster functionality to work with PITs and current ccsMinimizeRoundTrips is
+ * not supported for point in time
+ */
+ searchRequest.setCcsMinimizeRoundtrips(false);
+ /**
+ * Phase 1 of create PIT
+ */
+ executeUpdatePit(searchTask, searchRequest, updatePitListener);
+
+ }
+
+ /**
+ * Creates PIT reader context with temporary keep alive
+ */
+ void executeUpdatePit(Task task, SearchRequest searchRequest, StepListener updatePitListener) {
+ logger.debug(
+ () -> new ParameterizedMessage("Executing update of PIT [{}]", searchRequest.pointInTimeBuilder().getId())
+ );
+ transportSearchAction.executeRequest(
+ task,
+ searchRequest,
+ TransportUpdatePitAction.UPDATE_PIT_ACTION,
+ false,
+ new TransportSearchAction.SinglePhaseSearchAction() {
+ @Override
+ public void executeOnShardTarget(
+ SearchTask searchTask,
+ SearchShardTarget target,
+ Transport.Connection connection,
+ ActionListener searchPhaseResultActionListener
+ ) {
+ searchTransportService.updatePitContext(
+ connection,
+ new TransportUpdatePitAction.UpdateReaderContextRequest(
+ target.getShardId(),
+ searchRequest.pointInTimeBuilder().getKeepAlive()
+ ),
+ searchTask,
+ ActionListener.wrap(searchPhaseResultActionListener::onResponse, searchPhaseResultActionListener::onFailure)
+ );
+ }
+ },
+ updatePitListener
+ );
+ }
+}
diff --git a/server/src/main/java/org/opensearch/action/search/UpdatePitRequest.java b/server/src/main/java/org/opensearch/action/search/UpdatePitRequest.java
new file mode 100644
index 0000000000000..ebc5fb9adc6ef
--- /dev/null
+++ b/server/src/main/java/org/opensearch/action/search/UpdatePitRequest.java
@@ -0,0 +1,150 @@
+/*
+ * 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.action.search;
+
+import org.opensearch.action.ActionRequest;
+import org.opensearch.action.ActionRequestValidationException;
+import org.opensearch.common.io.stream.StreamInput;
+import org.opensearch.common.io.stream.StreamOutput;
+import org.opensearch.common.unit.TimeValue;
+import org.opensearch.common.xcontent.ToXContent;
+import org.opensearch.common.xcontent.ToXContentObject;
+import org.opensearch.common.xcontent.XContentBuilder;
+import org.opensearch.common.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.opensearch.action.ValidateActions.addValidationError;
+
+public class UpdatePitRequest extends ActionRequest implements ToXContentObject {
+// TODO: update the pit request to handle not just array
+ private final List updatePitRequests;
+
+
+ public List getUpdatePitRequests() {
+ return updatePitRequests;
+ }
+
+ public UpdatePitRequest(UpdatePitRequestInfo... updatePitRequests){
+ this.updatePitRequests = (Arrays.asList(updatePitRequests));
+ }
+
+ public UpdatePitRequest(List updatePitRequests){
+ this.updatePitRequests = updatePitRequests;
+ }
+
+ public UpdatePitRequest() {
+ this.updatePitRequests = new ArrayList<>();
+ }
+
+ public UpdatePitRequestInfo getPitRequestInfo(){
+ return updatePitRequests.get(0);
+ }
+
+ @Override
+ public ActionRequestValidationException validate() {
+ ActionRequestValidationException validationException = null;
+ if (updatePitRequests == null || updatePitRequests.isEmpty()) {
+ validationException = addValidationError("No pit ids specified", validationException);
+ }
+ return validationException;
+ }
+
+ public UpdatePitRequest(StreamInput in) throws IOException {
+ super(in);
+ int size = in.readVInt();
+ updatePitRequests = new ArrayList<>();
+ for(int i=0;i
+ // keep_alive: <>
+ // }
+ // ]
+ // }
+ public void fromXContent(XContentParser parser) throws IOException {
+ updatePitRequests.clear();
+ if(parser.nextToken() != XContentParser.Token.START_OBJECT){
+ throw new IllegalArgumentException("Malformed content, must start with an object");
+ } else {
+ XContentParser.Token token;
+ String currentFieldName = null;
+ String currentFieldName1 = null;
+ while((token = parser.nextToken()) != XContentParser.Token.END_OBJECT){
+ if (token == XContentParser.Token.FIELD_NAME){
+ currentFieldName = parser.currentName();
+ } else if("pits".equals(currentFieldName)){
+ if(token == XContentParser.Token.START_ARRAY){
+ while(parser.nextToken() != XContentParser.Token.START_OBJECT) {
+ String pit_id =null;
+ String keep_alive = null;
+ if (parser.nextToken() == XContentParser.Token.FIELD_NAME){
+ currentFieldName1 = parser.currentName();
+ }
+ if("pit_id".equals(currentFieldName1)){
+ pit_id = parser.text();
+ } else{
+ throw new IllegalArgumentException("pit_id array element should only contain pit_id " + currentFieldName1);
+ }
+
+ if (parser.nextToken() == XContentParser.Token.FIELD_NAME){
+ currentFieldName1 = parser.currentName();
+ }
+ if("keep_alive".equals(currentFieldName1)){
+ keep_alive = parser.text();
+ } else{
+ throw new IllegalArgumentException("pit_id array element should only contain pit_id " + currentFieldName1);
+ }
+ updatePitRequests.add(new UpdatePitRequestInfo(pit_id, keep_alive));
+
+
+ if(parser.nextToken() !=XContentParser.Token.END_OBJECT){
+ throw new IllegalArgumentException("pit_id array element should only contain pit_id " + currentFieldName1);
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("pit_id array element should only contain pit_id");
+
+ }
+ }
+
+ }
+ }
+ }
+}
diff --git a/server/src/main/java/org/opensearch/action/search/UpdatePitRequestInfo.java b/server/src/main/java/org/opensearch/action/search/UpdatePitRequestInfo.java
new file mode 100644
index 0000000000000..eecc87c2f92a3
--- /dev/null
+++ b/server/src/main/java/org/opensearch/action/search/UpdatePitRequestInfo.java
@@ -0,0 +1,53 @@
+/*
+ * 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.action.search;
+
+import org.opensearch.common.io.stream.StreamInput;
+import org.opensearch.common.io.stream.StreamOutput;
+import org.opensearch.common.unit.TimeValue;
+import org.opensearch.common.xcontent.ToXContent;
+import org.opensearch.common.xcontent.XContentBuilder;
+
+import java.io.IOException;
+
+public class UpdatePitRequestInfo {
+ private final String pitId;
+ private final TimeValue keepAlive;
+
+ public UpdatePitRequestInfo(String pitId, TimeValue keepAlive){
+ this.pitId = pitId;
+ this.keepAlive = keepAlive;
+ }
+
+ public UpdatePitRequestInfo(StreamInput in) throws IOException {
+ pitId = in.readString();
+ keepAlive = in.readTimeValue();
+ }
+
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeString(pitId);
+ out.writeTimeValue(keepAlive);
+ }
+
+ public String getPitId(){
+ return pitId;
+ }
+
+ public TimeValue getKeepAlive() {
+ return keepAlive;
+ }
+
+ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
+ builder.startObject();
+ builder.field("pit_id", pitId);
+ builder.field("keepAlive", keepAlive);
+ builder.endObject();
+ return builder;
+ }
+}
diff --git a/server/src/main/java/org/opensearch/action/search/UpdatePitResponse.java b/server/src/main/java/org/opensearch/action/search/UpdatePitResponse.java
new file mode 100644
index 0000000000000..2d007f5c00648
--- /dev/null
+++ b/server/src/main/java/org/opensearch/action/search/UpdatePitResponse.java
@@ -0,0 +1,88 @@
+/*
+ * 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.action.search;
+
+import org.opensearch.action.ActionResponse;
+import org.opensearch.common.ParseField;
+import org.opensearch.common.io.stream.StreamInput;
+import org.opensearch.common.io.stream.StreamOutput;
+import org.opensearch.common.xcontent.*;
+import org.opensearch.rest.RestStatus;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.opensearch.common.xcontent.ConstructingObjectParser.constructorArg;
+import static org.opensearch.rest.RestStatus.NOT_FOUND;
+import static org.opensearch.rest.RestStatus.OK;
+
+public class UpdatePitResponse extends ActionResponse implements StatusToXContentObject {
+ private final List updatePitResults;
+
+ public UpdatePitResponse(List updatePitResults){
+ this.updatePitResults = updatePitResults;
+ }
+ public UpdatePitResponse(StreamInput in) throws IOException{
+ super(in);
+ int size = in.readVInt();
+ updatePitResults = new ArrayList<>();
+ for (int i=0; i < size; i++) {
+ updatePitResults.add(new UpdatePitResponseInfo(in));
+ }
+ }
+
+ public List getUpdatePitResults() {
+ return updatePitResults;
+ }
+
+ @Override
+ public RestStatus status() {
+ if (updatePitResults.isEmpty()) return NOT_FOUND;
+ return OK;
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeVInt(updatePitResults.size());
+ for (UpdatePitResponseInfo updatePitResult : updatePitResults) {
+ updatePitResult.writeTo(out);
+ }
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
+ builder.startObject();
+ builder.startArray("pits");
+ for (UpdatePitResponseInfo response: updatePitResults) {
+ response.toXContent(builder,params);
+ }
+ builder.endArray();
+ builder.endObject();
+ return builder;
+ }
+
+ private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(
+ "update_pit_response",
+ true,
+ (Object[] parsedObjects) -> {
+ @SuppressWarnings("unchecked")
+ List updatePitResponseInfoList = (List) parsedObjects[0];
+ return new UpdatePitResponse(updatePitResponseInfoList);
+ }
+ );
+
+ static {
+ PARSER.declareObjectArray(constructorArg(), UpdatePitResponseInfo.PARSER, new ParseField("pits"));
+ }
+
+ public static UpdatePitResponse fromXContent(XContentParser parser) throws IOException {
+ return PARSER.parse(parser, null);
+ }
+}
diff --git a/server/src/main/java/org/opensearch/action/search/UpdatePitResponseInfo.java b/server/src/main/java/org/opensearch/action/search/UpdatePitResponseInfo.java
new file mode 100644
index 0000000000000..3ab6c09a571ee
--- /dev/null
+++ b/server/src/main/java/org/opensearch/action/search/UpdatePitResponseInfo.java
@@ -0,0 +1,76 @@
+/*
+ * 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.action.search;
+
+import org.opensearch.common.ParseField;
+import org.opensearch.common.io.stream.StreamInput;
+import org.opensearch.common.io.stream.StreamOutput;
+import org.opensearch.common.io.stream.Writeable;
+import org.opensearch.common.xcontent.ConstructingObjectParser;
+import org.opensearch.common.xcontent.ToXContent;
+import org.opensearch.common.xcontent.XContentBuilder;
+import org.opensearch.transport.TransportResponse;
+
+import java.io.IOException;
+
+import static org.opensearch.common.xcontent.ConstructingObjectParser.constructorArg;
+
+public class UpdatePitResponseInfo extends TransportResponse implements Writeable, ToXContent {
+ private final boolean successful;
+ private final String pitId;
+ // TODO: to add more fields as per the contract
+
+ public UpdatePitResponseInfo(boolean successful, String pitId){
+ this.successful = successful;
+ this.pitId = pitId;
+ }
+
+ public UpdatePitResponseInfo(StreamInput in) throws IOException{
+ successful = in.readBoolean();
+ pitId = in.readString();
+ }
+
+ public boolean isSuccessful(){
+ return successful;
+ }
+
+ public String getPitId(){
+ return pitId;
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeBoolean(successful);
+ out.writeString(pitId);
+ }
+
+ static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(
+ "update_pit_info",
+ true,
+ args -> new UpdatePitResponseInfo((boolean) args[0], (String) args[1])
+ );
+
+ static {
+ PARSER.declareBoolean(constructorArg(), new ParseField("successful"));
+ PARSER.declareString(constructorArg(), new ParseField("pit_id"));
+ }
+
+ private static final ParseField SUCCESSFUL = new ParseField("successful");
+ private static final ParseField PIT_ID = new ParseField("pit_id");
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.startObject();
+ builder.field(SUCCESSFUL.getPreferredName(), successful);
+ builder.field(PIT_ID.getPreferredName(), pitId);
+ builder.endObject();
+ return builder;
+ }
+}
+
diff --git a/server/src/main/java/org/opensearch/client/support/AbstractClient.java b/server/src/main/java/org/opensearch/client/support/AbstractClient.java
index 828ca5f8083ee..2927f59444b32 100644
--- a/server/src/main/java/org/opensearch/client/support/AbstractClient.java
+++ b/server/src/main/java/org/opensearch/client/support/AbstractClient.java
@@ -349,30 +349,7 @@
import org.opensearch.action.ingest.SimulatePipelineRequest;
import org.opensearch.action.ingest.SimulatePipelineRequestBuilder;
import org.opensearch.action.ingest.SimulatePipelineResponse;
-import org.opensearch.action.search.ClearScrollAction;
-import org.opensearch.action.search.ClearScrollRequest;
-import org.opensearch.action.search.ClearScrollRequestBuilder;
-import org.opensearch.action.search.ClearScrollResponse;
-import org.opensearch.action.search.CreatePitAction;
-import org.opensearch.action.search.CreatePitRequest;
-import org.opensearch.action.search.CreatePitResponse;
-import org.opensearch.action.search.DeletePitAction;
-import org.opensearch.action.search.DeletePitRequest;
-import org.opensearch.action.search.DeletePitResponse;
-import org.opensearch.action.search.GetAllPitNodesRequest;
-import org.opensearch.action.search.GetAllPitNodesResponse;
-import org.opensearch.action.search.MultiSearchAction;
-import org.opensearch.action.search.MultiSearchRequest;
-import org.opensearch.action.search.MultiSearchRequestBuilder;
-import org.opensearch.action.search.MultiSearchResponse;
-import org.opensearch.action.search.GetAllPitsAction;
-import org.opensearch.action.search.SearchAction;
-import org.opensearch.action.search.SearchRequest;
-import org.opensearch.action.search.SearchRequestBuilder;
-import org.opensearch.action.search.SearchResponse;
-import org.opensearch.action.search.SearchScrollAction;
-import org.opensearch.action.search.SearchScrollRequest;
-import org.opensearch.action.search.SearchScrollRequestBuilder;
+import org.opensearch.action.search.*;
import org.opensearch.action.support.PlainActionFuture;
import org.opensearch.action.support.master.AcknowledgedResponse;
import org.opensearch.action.termvectors.MultiTermVectorsAction;
@@ -627,6 +604,11 @@ public void getAllPits(final GetAllPitNodesRequest getAllPitNodesRequest, final
execute(GetAllPitsAction.INSTANCE, getAllPitNodesRequest, listener);
}
+ @Override
+ public void updatePit(final UpdatePitRequest updatePitRequest, final ActionListener listener){
+ execute(UpdatePitAction.INSTANCE, updatePitRequest, listener);
+ }
+
@Override
public void pitSegments(final PitSegmentsRequest request, final ActionListener listener) {
execute(PitSegmentsAction.INSTANCE, request, listener);
diff --git a/server/src/main/java/org/opensearch/rest/action/search/RestUpdatePitAction.java b/server/src/main/java/org/opensearch/rest/action/search/RestUpdatePitAction.java
new file mode 100644
index 0000000000000..707478727f51f
--- /dev/null
+++ b/server/src/main/java/org/opensearch/rest/action/search/RestUpdatePitAction.java
@@ -0,0 +1,53 @@
+/*
+ * 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.rest.action.search;
+
+import org.opensearch.action.search.UpdatePitRequest;
+import org.opensearch.action.search.UpdatePitResponse;
+import org.opensearch.client.node.NodeClient;
+import org.opensearch.common.unit.TimeValue;
+import org.opensearch.rest.BaseRestHandler;
+import org.opensearch.rest.RestRequest;
+import org.opensearch.rest.action.RestStatusToXContentListener;
+
+import java.io.IOException;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+import static org.opensearch.rest.RestRequest.Method.POST;
+
+public class RestUpdatePitAction extends BaseRestHandler {
+
+ @Override
+ public String getName(){
+ return "update_pit_action";
+ }
+
+ @Override
+ public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
+ final UpdatePitRequest updatePitRequest = new UpdatePitRequest();
+ request.withContentOrSourceParamParserOrNull((xContentParser -> {
+ if (xContentParser != null){
+ try {
+ updatePitRequest.fromXContent(xContentParser);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(" Failed to parse request body", e);
+ }
+ }
+ }));
+
+ return channel -> client.updatePit(updatePitRequest, new RestStatusToXContentListener(channel));
+ }
+
+ @Override
+ public List routes() {
+ return unmodifiableList(asList(new Route(POST, "/_search/point_in_time")));
+ }
+}
diff --git a/server/src/main/java/org/opensearch/search/builder/PointInTimeBuilder.java b/server/src/main/java/org/opensearch/search/builder/PointInTimeBuilder.java
index 520ce124a19da..ac2ae27edce35 100644
--- a/server/src/main/java/org/opensearch/search/builder/PointInTimeBuilder.java
+++ b/server/src/main/java/org/opensearch/search/builder/PointInTimeBuilder.java
@@ -80,6 +80,11 @@ public PointInTimeBuilder(String id) {
this.id = Objects.requireNonNull(id);
}
+ public PointInTimeBuilder(String id, TimeValue keepAlive){
+ this.id = Objects.requireNonNull(id);
+ this.keepAlive = Objects.requireNonNull(keepAlive);
+ }
+
public PointInTimeBuilder(StreamInput in) throws IOException {
id = in.readString();
keepAlive = in.readOptionalTimeValue();