From d1cc484e504677337f98240f2a81ef072e503563 Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 03:08:00 +0530 Subject: [PATCH 01/12] cl --- changelog/unreleased/SOLR-16398-replication-phase2.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 changelog/unreleased/SOLR-16398-replication-phase2.yml diff --git a/changelog/unreleased/SOLR-16398-replication-phase2.yml b/changelog/unreleased/SOLR-16398-replication-phase2.yml new file mode 100644 index 000000000000..62591c33f5d2 --- /dev/null +++ b/changelog/unreleased/SOLR-16398-replication-phase2.yml @@ -0,0 +1,9 @@ +title: > + Replication phase2 - TBA +type: +authors: + - name: Jalaz Kumar + nick: jaykay12 +links: + - name: SOLR-16398 + url: https://issues.apache.org/jira/browse/SOLR-16398 From 341035b312aef178cfed40f774eb300d9ffd5855 Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 13:39:51 +0530 Subject: [PATCH 02/12] initial changes --- ...98-replication-restore-status-commits.yml} | 4 +- .../client/api/endpoint/ReplicationApis.java | 18 +++++ .../client/api/model/CommitsResponse.java | 38 ++++++++++ .../api/model/ReplicationDetailsResponse.java | 13 +--- .../api/model/RestoreStatusResponse.java | 51 +++++++++++++ .../solr/handler/ReplicationHandler.java | 72 +++++++++---------- .../handler/admin/api/CoreReplication.java | 14 ++++ .../handler/admin/api/ReplicationAPIBase.java | 14 ++++ .../apache/solr/handler/api/V2ApiUtils.java | 4 ++ .../admin/api/CoreReplicationAPITest.java | 35 +++++++++ 10 files changed, 212 insertions(+), 51 deletions(-) rename changelog/unreleased/{SOLR-16398-replication-phase2.yml => SOLR-16398-replication-restore-status-commits.yml} (64%) create mode 100644 solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java create mode 100644 solr/api/src/java/org/apache/solr/client/api/model/RestoreStatusResponse.java diff --git a/changelog/unreleased/SOLR-16398-replication-phase2.yml b/changelog/unreleased/SOLR-16398-replication-restore-status-commits.yml similarity index 64% rename from changelog/unreleased/SOLR-16398-replication-phase2.yml rename to changelog/unreleased/SOLR-16398-replication-restore-status-commits.yml index 62591c33f5d2..b1ab5e704f71 100644 --- a/changelog/unreleased/SOLR-16398-replication-phase2.yml +++ b/changelog/unreleased/SOLR-16398-replication-restore-status-commits.yml @@ -1,6 +1,6 @@ title: > - Replication phase2 - TBA -type: + Add V2 JAX-RS APIs for GET replication restore status and commits. +type: added authors: - name: Jalaz Kumar nick: jaykay12 diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java index f95335dc407a..6e44b79ac988 100644 --- a/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java @@ -29,9 +29,11 @@ import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.StreamingOutput; import java.io.IOException; +import org.apache.solr.client.api.model.CommitsResponse; import org.apache.solr.client.api.model.FileListResponse; import org.apache.solr.client.api.model.IndexVersionResponse; import org.apache.solr.client.api.model.ReplicationDetailsResponse; +import org.apache.solr.client.api.model.RestoreStatusResponse; import org.apache.solr.client.api.util.CoreApiParameters; @Path("/cores/{coreName}/replication") @@ -50,6 +52,22 @@ ReplicationDetailsResponse fetchReplicationDetails( @DefaultValue("true") Boolean follower); + @GET + @CoreApiParameters + @Path("/restore") + @Operation( + summary = "Return the status of the most recent restore operation.", + tags = {"replication"}) + RestoreStatusResponse fetchRestoreStatus() throws IOException; + + @GET + @CoreApiParameters + @Path("/commits") + @Operation( + summary = "Return the index commit points retained by the specified core.", + tags = {"replication"}) + CommitsResponse fetchCommits() throws IOException; + @GET @CoreApiParameters @Path("/indexversion") diff --git a/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java new file mode 100644 index 000000000000..6cf77405bae9 --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java @@ -0,0 +1,38 @@ +package org.apache.solr.client.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import org.apache.solr.client.api.util.ReflectWritable; + +/** Response body for the `GET /api/cores/coreName/replication/commits` API */ +public class CommitsResponse extends SolrJerseyResponse { + + @JsonProperty("commits") + @Schema(description = "Index commit points currently retained by the deletion policy") + public List commits; + + @JsonProperty("status") + @Schema(description = "Request status, typically OK") + public String status; + + /** Details of a single index commit point. */ + public static class CommitDetails implements ReflectWritable { + @JsonProperty("indexVersion") + public Long indexVersion; + + @JsonProperty("generation") + public Long generation; + + @JsonProperty("filelist") + public List filelist; + + public CommitDetails() {} + + public CommitDetails(long l, long l1, List segments7) { + this.indexVersion = l; + this.generation = l1; + this.filelist = segments7; + } + } +} diff --git a/solr/api/src/java/org/apache/solr/client/api/model/ReplicationDetailsResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/ReplicationDetailsResponse.java index 9a1054c52402..ac846cb269ce 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/ReplicationDetailsResponse.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/ReplicationDetailsResponse.java @@ -47,7 +47,7 @@ public static class ReplicationDetails implements ReflectWritable { public String indexPath; @JsonProperty("commits") - public List commits; + public List commits; @JsonProperty("isLeader") public Boolean isLeader; @@ -72,17 +72,6 @@ public static class ReplicationDetails implements ReflectWritable { public Object backup; } - public static class CommitDetails implements ReflectWritable { - @JsonProperty("indexVersion") - public Long indexVersion; - - @JsonProperty("generation") - public Long generation; - - @JsonProperty("filelist") - public List filelist; - } - public static class LeaderDetails implements ReflectWritable { @JsonProperty("confFiles") public String confFiles; diff --git a/solr/api/src/java/org/apache/solr/client/api/model/RestoreStatusResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/RestoreStatusResponse.java new file mode 100644 index 000000000000..10d92f0d6948 --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/model/RestoreStatusResponse.java @@ -0,0 +1,51 @@ +package org.apache.solr.client.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; +import org.apache.solr.client.api.util.ReflectWritable; + +/** Response body for the `GET /api/cores/coreName/replication/restore` API */ +public class RestoreStatusResponse extends SolrJerseyResponse { + + @JsonProperty("restorestatus") + @Schema(description = "State of the most recent restore operation") + public RestoreStatus restoreStatus; + + @JsonProperty("status") + @Schema(description = "Request status, typically OK") + public String status; + + /** State of a restore operation. */ + public static class RestoreStatus implements ReflectWritable { + @JsonProperty("snapshotName") + public String snapshotName; + + @JsonProperty("status") + @Schema(description = "State of the restore operation") + public RestoreState status; + + @JsonProperty("exception") + @Schema(description = "Failure message, present only when the restore failed with an exception") + public String exception; + } + + /** State of a restore operation. */ + public enum RestoreState { + NOT_STARTED("No restore actions in progress"), + IN_PROGRESS("In Progress"), + SUCCESS("success"), + FAILED("failed"); + + private final String key; + + RestoreState(String key) { + this.key = key; + } + + @JsonValue + public String getKey() { + return key; + } + } +} diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java index 8287459f28f3..f1bdbb433f33 100644 --- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java @@ -75,13 +75,14 @@ import org.apache.lucene.store.IndexInput; import org.apache.solr.api.Api; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.CommitsResponse; import org.apache.solr.client.api.model.FileMetaData; import org.apache.solr.client.api.model.IndexVersionResponse; import org.apache.solr.client.api.model.ReplicationDetailsResponse; -import org.apache.solr.client.api.model.ReplicationDetailsResponse.CommitDetails; import org.apache.solr.client.api.model.ReplicationDetailsResponse.FollowerDetails; import org.apache.solr.client.api.model.ReplicationDetailsResponse.LeaderDetails; import org.apache.solr.client.api.model.ReplicationDetailsResponse.ReplicationDetails; +import org.apache.solr.client.api.model.RestoreStatusResponse; import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; @@ -311,7 +312,14 @@ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throw } else if (command.equalsIgnoreCase(CMD_RESTORE)) { restore(new ModifiableSolrParams(solrParams), rsp, req); } else if (command.equalsIgnoreCase(CMD_RESTORE_STATUS)) { - populateRestoreStatus(rsp); + final CoreReplication coreReplicationAPI = new CoreReplication(core, req, rsp); + final RestoreStatusResponse restoreStatus = coreReplicationAPI.fetchRestoreStatus(); + V2ApiUtils.squashIntoSolrResponseWithoutHeader(rsp, restoreStatus); + if (restoreStatus.restoreStatus.exception != null) { + // V1 reports a failed restore as an error response + rsp.getValues().remove(STATUS); + reportErrorOnResponse(rsp, "Unabled to read restorestatus", new Exception(restoreStatus.restoreStatus.exception)); + } } else if (command.equalsIgnoreCase(CMD_DELETE_BACKUP)) { deleteSnapshot(new ModifiableSolrParams(solrParams), rsp); } else if (command.equalsIgnoreCase(CMD_FETCH_INDEX)) { @@ -327,7 +335,8 @@ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throw reportErrorOnResponse(rsp, "No follower configured", null); } } else if (command.equals(CMD_SHOW_COMMITS)) { - populateCommitInfo(rsp); + final CoreReplication coreReplicationAPI = new CoreReplication(core, req, rsp); + V2ApiUtils.squashIntoSolrResponseWithoutHeader(rsp, coreReplicationAPI.fetchCommits()); } else if (command.equals(CMD_DETAILS)) { final CoreReplication coreReplicationAPI = new CoreReplication(core, req, rsp); // stringifyBooleans=true: V1's command=details has always rendered isLeader/isFollower/etc. @@ -642,42 +651,35 @@ private void restore(SolrParams params, SolrQueryResponse rsp, SolrQueryRequest } } - private void populateRestoreStatus(SolrQueryResponse rsp) { - NamedList restoreStatus = new SimpleOrderedMap<>(); - if (restoreFuture == null) { - restoreStatus.add(STATUS, "No restore actions in progress"); - rsp.add(CMD_RESTORE_STATUS, restoreStatus); - rsp.add(STATUS, OK_STATUS); - return; + public RestoreStatusResponse getRestoreStatusResponse() { + RestoreStatusResponse response = new RestoreStatusResponse(); + response.restoreStatus = new RestoreStatusResponse.RestoreStatus(); + response.status = OK_STATUS; + Future future = restoreFuture; + if (future == null) { + response.restoreStatus.status = RestoreStatusResponse.RestoreState.NOT_STARTED; + return response; } - restoreStatus.add("snapshotName", currentRestoreName); - if (restoreFuture.isDone()) { + response.restoreStatus.snapshotName = currentRestoreName; + if (future.isDone()) { try { - boolean success = restoreFuture.get(); - if (success) { - restoreStatus.add(STATUS, SUCCESS); - } else { - restoreStatus.add(STATUS, FAILED); - } + response.restoreStatus.status = future.get() ? RestoreStatusResponse.RestoreState.SUCCESS : RestoreStatusResponse.RestoreState.FAILED; } catch (Exception e) { - restoreStatus.add(STATUS, FAILED); - restoreStatus.add(EXCEPTION, e.getMessage()); - rsp.add(CMD_RESTORE_STATUS, restoreStatus); - reportErrorOnResponse(rsp, "Unable to read restorestatus", e); - return; + response.restoreStatus.status = RestoreStatusResponse.RestoreState.FAILED; + response.restoreStatus.exception = e.getMessage(); } } else { - restoreStatus.add(STATUS, "In Progress"); + response.restoreStatus.status = RestoreStatusResponse.RestoreState.IN_PROGRESS; } - - rsp.add(CMD_RESTORE_STATUS, restoreStatus); - rsp.add(STATUS, OK_STATUS); + return response; } - private void populateCommitInfo(SolrQueryResponse rsp) { - rsp.add(CMD_SHOW_COMMITS, getCommits()); - rsp.add(STATUS, OK_STATUS); + public CommitsResponse getCommitsResponse() { + CommitsResponse response = new CommitsResponse(); + response.commits = getCommitDetails(); + response.status = OK_STATUS; + return response; } private void doSnapShoot(SolrParams params, SolrQueryResponse rsp, SolrQueryRequest req) { @@ -1237,10 +1239,10 @@ private void addReplicationProperties(FollowerDetails followerDetails, Propertie } @SuppressWarnings("unchecked") - private List getCommitDetails() { - List commits = new ArrayList<>(); + private List getCommitDetails() { + List commits = new ArrayList<>(); for (NamedList namedList : getCommits()) { - CommitDetails commitDetail = new CommitDetails(); + CommitsResponse.CommitDetails commitDetail = new CommitsResponse.CommitDetails(); commitDetail.indexVersion = (Long) namedList.get("indexVersion"); commitDetail.generation = (Long) namedList.get(GENERATION); commitDetail.filelist = (List) namedList.get(CMD_GET_FILE_LIST); @@ -1685,10 +1687,6 @@ public static Long readIntervalNs(String interval) { } } - private static final String SUCCESS = "success"; - - private static final String FAILED = "failed"; - public static final String EXCEPTION = "exception"; public static final String LEADER_URL = "leaderUrl"; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplication.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplication.java index 9985eb05a676..478322d74776 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplication.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplication.java @@ -22,9 +22,11 @@ import jakarta.ws.rs.core.StreamingOutput; import java.io.IOException; import org.apache.solr.client.api.endpoint.ReplicationApis; +import org.apache.solr.client.api.model.CommitsResponse; import org.apache.solr.client.api.model.FileListResponse; import org.apache.solr.client.api.model.IndexVersionResponse; import org.apache.solr.client.api.model.ReplicationDetailsResponse; +import org.apache.solr.client.api.model.RestoreStatusResponse; import org.apache.solr.common.SolrException; import org.apache.solr.core.SolrCore; import org.apache.solr.jersey.PermissionName; @@ -51,6 +53,18 @@ public ReplicationDetailsResponse fetchReplicationDetails(Boolean follower) { return doFetchReplicationDetails(follower == null || follower); } + @Override + @PermissionName(CORE_READ_PERM) + public RestoreStatusResponse fetchRestoreStatus() throws IOException { + return doFetchRestoreStatus(); + } + + @Override + @PermissionName(CORE_READ_PERM) + public CommitsResponse fetchCommits() throws IOException { + return doFetchCommits(); + } + @Override @PermissionName(CORE_READ_PERM) public IndexVersionResponse fetchIndexVersion() throws IOException { diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java index 378c5699d31c..a0fed4539b78 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java @@ -45,10 +45,12 @@ import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.RateLimiter; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.CommitsResponse; import org.apache.solr.client.api.model.FileListResponse; import org.apache.solr.client.api.model.FileMetaData; import org.apache.solr.client.api.model.IndexVersionResponse; import org.apache.solr.client.api.model.ReplicationDetailsResponse; +import org.apache.solr.client.api.model.RestoreStatusResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.util.FastOutputStream; import org.apache.solr.common.util.IOUtils; @@ -100,6 +102,18 @@ protected ReplicationDetailsResponse doFetchReplicationDetails(boolean showFollo return replicationHandler.getReplicationDetails(showFollowerDetails); } + protected RestoreStatusResponse doFetchRestoreStatus() throws IOException { + ReplicationHandler replicationHandler = + (ReplicationHandler) solrCore.getRequestHandler(ReplicationHandler.PATH); + return null; + } + + protected CommitsResponse doFetchCommits() throws IOException { + ReplicationHandler replicationHandler = + (ReplicationHandler) solrCore.getRequestHandler(ReplicationHandler.PATH); + return null; + } + protected IndexVersionResponse doFetchIndexVersion() throws IOException { ReplicationHandler replicationHandler = (ReplicationHandler) solrCore.getRequestHandler(ReplicationHandler.PATH); diff --git a/solr/core/src/java/org/apache/solr/handler/api/V2ApiUtils.java b/solr/core/src/java/org/apache/solr/handler/api/V2ApiUtils.java index 478c7c09be6e..0a902ae68356 100644 --- a/solr/core/src/java/org/apache/solr/handler/api/V2ApiUtils.java +++ b/solr/core/src/java/org/apache/solr/handler/api/V2ApiUtils.java @@ -34,6 +34,7 @@ import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.StrUtils; import org.apache.solr.common.util.Utils; +import org.apache.solr.jersey.SolrJacksonMapper; import org.apache.solr.response.PrometheusResponseWriter; import org.apache.solr.response.RawResponseWriter; import org.apache.solr.response.SolrQueryResponse; @@ -157,6 +158,9 @@ private static Object convertReflectWriteableValue(Object value, boolean stringi if (stringifyBooleans && value instanceof Boolean bool) { return bool.toString(); } + if (value instanceof Enum e) { + return SolrJacksonMapper.getObjectMapper().convertValue(e, Object.class); + } if (value instanceof ReflectWritable) { NamedList result = new SimpleOrderedMap<>(); squashObjectIntoNamedList(result, value, true, stringifyBooleans); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java index 8406f8db35bf..ff1116cd9ad9 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java @@ -30,11 +30,13 @@ import java.util.List; import org.apache.lucene.util.Constants; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.client.api.model.CommitsResponse; import org.apache.solr.client.api.model.FileListResponse; import org.apache.solr.client.api.model.FileMetaData; import org.apache.solr.client.api.model.IndexVersionResponse; import org.apache.solr.client.api.model.ReplicationDetailsResponse; import org.apache.solr.client.api.model.ReplicationDetailsResponse.ReplicationDetails; +import org.apache.solr.client.api.model.RestoreStatusResponse; import org.apache.solr.common.SolrException; import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrResourceLoader; @@ -100,6 +102,39 @@ public void testFetchReplicationDetails() { assertSame(expectedResponse, withFollowerFalse); } + @Test + public void testGetRestoreStatus() throws Exception { + RestoreStatusResponse expected = new RestoreStatusResponse(); + expected.status = "OK"; + expected.restoreStatus = new RestoreStatusResponse.RestoreStatus(); + expected.restoreStatus.snapshotName = "snapshot.test"; + expected.restoreStatus.status = RestoreStatusResponse.RestoreState.FAILED; + expected.restoreStatus.exception = "restore failed"; + when(mockReplicationHandler.getRestoreStatusResponse()).thenReturn(expected); + + RestoreStatusResponse actual = coreReplicationAPI.doFetchRestoreStatus(); + assertEquals(expected.status, actual.status); + assertEquals(expected.restoreStatus.snapshotName, actual.restoreStatus.snapshotName); + assertEquals(expected.restoreStatus.status, actual.restoreStatus.status); + assertEquals(expected.restoreStatus.exception, actual.restoreStatus.exception); + } + + @Test + public void testGetCommits() throws Exception { + CommitsResponse.CommitDetails commit = new CommitsResponse.CommitDetails(42L, 7L, List.of("segments_7", "_0.cfs")); + CommitsResponse expected = new CommitsResponse(); + expected.status = "OK"; + expected.commits = List.of(commit); + when(mockReplicationHandler.getCommitsResponse()).thenReturn(expected); + + CommitsResponse actual = coreReplicationAPI.doFetchCommits(); + assertEquals(expected.status, actual.status); + assertEquals(1, actual.commits.size()); + assertEquals(expected.commits.getFirst().indexVersion, actual.commits.getFirst().indexVersion); + assertEquals(expected.commits.getFirst().generation, actual.commits.getFirst().generation); + assertEquals(expected.commits.getFirst().filelist, actual.commits.getFirst().filelist); + } + @Test public void testGetIndexVersion() throws Exception { IndexVersionResponse expected = new IndexVersionResponse(123L, 123L, "testGeneration"); From f7c4153c23aa5255cbcf7c80d0b27007ac39e9fc Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 13:43:49 +0530 Subject: [PATCH 03/12] first changes --- .../SOLR-16398-replication-restore-status-commits.yml | 3 +-- .../org/apache/solr/handler/admin/api/ReplicationAPIBase.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/changelog/unreleased/SOLR-16398-replication-restore-status-commits.yml b/changelog/unreleased/SOLR-16398-replication-restore-status-commits.yml index b1ab5e704f71..6b2cc979d50e 100644 --- a/changelog/unreleased/SOLR-16398-replication-restore-status-commits.yml +++ b/changelog/unreleased/SOLR-16398-replication-restore-status-commits.yml @@ -1,5 +1,4 @@ -title: > - Add V2 JAX-RS APIs for GET replication restore status and commits. +title: Add V2 JAX-RS APIs for GET replication restore status and commits. type: added authors: - name: Jalaz Kumar diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java index a0fed4539b78..d7b02c1500c7 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java @@ -105,13 +105,13 @@ protected ReplicationDetailsResponse doFetchReplicationDetails(boolean showFollo protected RestoreStatusResponse doFetchRestoreStatus() throws IOException { ReplicationHandler replicationHandler = (ReplicationHandler) solrCore.getRequestHandler(ReplicationHandler.PATH); - return null; + return replicationHandler.getRestoreStatusResponse(); } protected CommitsResponse doFetchCommits() throws IOException { ReplicationHandler replicationHandler = (ReplicationHandler) solrCore.getRequestHandler(ReplicationHandler.PATH); - return null; + return replicationHandler.getCommitsResponse(); } protected IndexVersionResponse doFetchIndexVersion() throws IOException { From 9e5715162a3332aa28603334b2566a9220b77bfa Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 13:45:01 +0530 Subject: [PATCH 04/12] tidying --- .../org/apache/solr/handler/ReplicationHandler.java | 10 ++++++++-- .../solr/handler/admin/api/CoreReplicationAPITest.java | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java index f1bdbb433f33..1f615383786e 100644 --- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java @@ -318,7 +318,10 @@ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throw if (restoreStatus.restoreStatus.exception != null) { // V1 reports a failed restore as an error response rsp.getValues().remove(STATUS); - reportErrorOnResponse(rsp, "Unabled to read restorestatus", new Exception(restoreStatus.restoreStatus.exception)); + reportErrorOnResponse( + rsp, + "Unabled to read restorestatus", + new Exception(restoreStatus.restoreStatus.exception)); } } else if (command.equalsIgnoreCase(CMD_DELETE_BACKUP)) { deleteSnapshot(new ModifiableSolrParams(solrParams), rsp); @@ -664,7 +667,10 @@ public RestoreStatusResponse getRestoreStatusResponse() { response.restoreStatus.snapshotName = currentRestoreName; if (future.isDone()) { try { - response.restoreStatus.status = future.get() ? RestoreStatusResponse.RestoreState.SUCCESS : RestoreStatusResponse.RestoreState.FAILED; + response.restoreStatus.status = + future.get() + ? RestoreStatusResponse.RestoreState.SUCCESS + : RestoreStatusResponse.RestoreState.FAILED; } catch (Exception e) { response.restoreStatus.status = RestoreStatusResponse.RestoreState.FAILED; response.restoreStatus.exception = e.getMessage(); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java index ff1116cd9ad9..726c1b2488ef 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java @@ -121,7 +121,8 @@ public void testGetRestoreStatus() throws Exception { @Test public void testGetCommits() throws Exception { - CommitsResponse.CommitDetails commit = new CommitsResponse.CommitDetails(42L, 7L, List.of("segments_7", "_0.cfs")); + CommitsResponse.CommitDetails commit = + new CommitsResponse.CommitDetails(42L, 7L, List.of("segments_7", "_0.cfs")); CommitsResponse expected = new CommitsResponse(); expected.status = "OK"; expected.commits = List.of(commit); From dd945e7be580c41b70014b7004f1401cc9d37cc7 Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 13:46:00 +0530 Subject: [PATCH 05/12] licenses --- .../solr/client/api/model/CommitsResponse.java | 16 ++++++++++++++++ .../client/api/model/RestoreStatusResponse.java | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java index 6cf77405bae9..302aedb9ba48 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.solr.client.api.model; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/solr/api/src/java/org/apache/solr/client/api/model/RestoreStatusResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/RestoreStatusResponse.java index 10d92f0d6948..8938c1a7ecc2 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/RestoreStatusResponse.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/RestoreStatusResponse.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.solr.client.api.model; import com.fasterxml.jackson.annotation.JsonProperty; From db349f4aab9c196e01a793bef3f0736054338041 Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 13:56:04 +0530 Subject: [PATCH 06/12] ref guides changes --- .../pages/user-managed-index-replication.adoc | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc index b3e8484098e3..657f2d451b00 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc @@ -427,6 +427,30 @@ Disable the specified follower from polling for changes on the leader. [source,bash] http://{followerHost}:{port}/solr/{coreName}/replication?command=disablepoll +`commits`:: +Retrieve the index commit points currently retained by the core, with each commit's index version, generation, and the file list. ++ +[tabs#commits-request] +====== +V1 API:: ++ +==== +[source,bash] +---- +http://{leaderHost}:{port}/solr/{coreName}/replication?command=commits +---- +==== + +V2 API:: ++ +==== +[source,bash] +---- +http://{leaderHost}:{port}/api/cores/{coreName}/replication/commits +---- +==== +====== + `details`:: Retrieve configuration details and current status. + @@ -570,9 +594,28 @@ For file system repository, location defaults to core's dataDir (data directory) `restorestatus`:: Check the status of a running restore operation. + ++ +[tabs#restorestatus-request] +====== +V1 API:: + +==== [source,bash] +---- http://{leaderHost}:{port}/solr/{coreName}/replication?command=restorestatus +---- +==== + +V2 API:: ++ +==== +[source,bash] +---- +http://{followerHost}:{port}/api/cores/{coreName}/replication/restore +---- +==== +====== + This command is used to check the status of a restore operation. This command takes no parameters. From 407dc223f56996df155704277cde70b30701514d Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 14:01:45 +0530 Subject: [PATCH 07/12] local agent review --- .../apache/solr/client/api/endpoint/ReplicationApis.java | 4 ++-- .../org/apache/solr/client/api/model/CommitsResponse.java | 8 ++++---- .../java/org/apache/solr/handler/ReplicationHandler.java | 2 +- .../apache/solr/handler/admin/api/CoreReplication.java | 4 ++-- .../apache/solr/handler/admin/api/ReplicationAPIBase.java | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java index 6e44b79ac988..471692396d5b 100644 --- a/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java @@ -58,7 +58,7 @@ ReplicationDetailsResponse fetchReplicationDetails( @Operation( summary = "Return the status of the most recent restore operation.", tags = {"replication"}) - RestoreStatusResponse fetchRestoreStatus() throws IOException; + RestoreStatusResponse fetchRestoreStatus(); @GET @CoreApiParameters @@ -66,7 +66,7 @@ ReplicationDetailsResponse fetchReplicationDetails( @Operation( summary = "Return the index commit points retained by the specified core.", tags = {"replication"}) - CommitsResponse fetchCommits() throws IOException; + CommitsResponse fetchCommits(); @GET @CoreApiParameters diff --git a/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java index 302aedb9ba48..6eea2d07bd83 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/CommitsResponse.java @@ -45,10 +45,10 @@ public static class CommitDetails implements ReflectWritable { public CommitDetails() {} - public CommitDetails(long l, long l1, List segments7) { - this.indexVersion = l; - this.generation = l1; - this.filelist = segments7; + public CommitDetails(long indexVersion, long generation, List filelist) { + this.indexVersion = indexVersion; + this.generation = generation; + this.filelist = filelist; } } } diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java index 1f615383786e..62987f884028 100644 --- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java @@ -320,7 +320,7 @@ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throw rsp.getValues().remove(STATUS); reportErrorOnResponse( rsp, - "Unabled to read restorestatus", + "Unable to read restorestatus", new Exception(restoreStatus.restoreStatus.exception)); } } else if (command.equalsIgnoreCase(CMD_DELETE_BACKUP)) { diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplication.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplication.java index 478322d74776..ea0341eb59e3 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplication.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplication.java @@ -55,13 +55,13 @@ public ReplicationDetailsResponse fetchReplicationDetails(Boolean follower) { @Override @PermissionName(CORE_READ_PERM) - public RestoreStatusResponse fetchRestoreStatus() throws IOException { + public RestoreStatusResponse fetchRestoreStatus() { return doFetchRestoreStatus(); } @Override @PermissionName(CORE_READ_PERM) - public CommitsResponse fetchCommits() throws IOException { + public CommitsResponse fetchCommits() { return doFetchCommits(); } diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java index d7b02c1500c7..a00261b388d5 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplicationAPIBase.java @@ -102,13 +102,13 @@ protected ReplicationDetailsResponse doFetchReplicationDetails(boolean showFollo return replicationHandler.getReplicationDetails(showFollowerDetails); } - protected RestoreStatusResponse doFetchRestoreStatus() throws IOException { + protected RestoreStatusResponse doFetchRestoreStatus() { ReplicationHandler replicationHandler = (ReplicationHandler) solrCore.getRequestHandler(ReplicationHandler.PATH); return replicationHandler.getRestoreStatusResponse(); } - protected CommitsResponse doFetchCommits() throws IOException { + protected CommitsResponse doFetchCommits() { ReplicationHandler replicationHandler = (ReplicationHandler) solrCore.getRequestHandler(ReplicationHandler.PATH); return replicationHandler.getCommitsResponse(); From 19206168fdef01f08b2db34a215a6bbd4475222e Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 14:26:47 +0530 Subject: [PATCH 08/12] few http tests --- .../solr/handler/ReplicationHandler.java | 2 +- .../admin/api/FetchCommitsAPITest.java | 41 ++++++++++++++++++ .../admin/api/FetchRestoreStatusAPITest.java | 42 +++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 solr/core/src/test/org/apache/solr/handler/admin/api/FetchCommitsAPITest.java create mode 100644 solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java index 62987f884028..e1693296e19e 100644 --- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java @@ -673,7 +673,7 @@ public RestoreStatusResponse getRestoreStatusResponse() { : RestoreStatusResponse.RestoreState.FAILED; } catch (Exception e) { response.restoreStatus.status = RestoreStatusResponse.RestoreState.FAILED; - response.restoreStatus.exception = e.getMessage(); + response.restoreStatus.exception = e.getMessage() != null ? e.getMessage() : e.toString(); } } else { response.restoreStatus.status = RestoreStatusResponse.RestoreState.IN_PROGRESS; diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/FetchCommitsAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchCommitsAPITest.java new file mode 100644 index 000000000000..2f1b299f91c8 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchCommitsAPITest.java @@ -0,0 +1,41 @@ +package org.apache.solr.handler.admin.api; + +import static org.apache.solr.core.CoreContainer.ALLOW_PATHS_SYSPROP; + +import org.apache.solr.SolrTestCase; +import org.apache.solr.client.solrj.request.ReplicationApi; +import org.apache.solr.util.ExternalPaths; +import org.apache.solr.util.SolrJettyTestRule; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; + +/** + * HTTP tests for {@code GET /api/cores/coreName/replication/commits} via the generated SolrJ + * request. + */ +public class FetchCommitsAPITest extends SolrTestCase { + + private static final String CORE_NAME = "commitsApiTestCore"; + + @ClassRule public static final SolrJettyTestRule solrTestRule = new SolrJettyTestRule(); + + @BeforeClass + public static void setupSolr() throws Exception { + System.setProperty(ALLOW_PATHS_SYSPROP, ExternalPaths.SERVER_HOME.toAbsolutePath().toString()); + solrTestRule.startSolr(createTempDir()); + solrTestRule.newCollection(CORE_NAME).withConfigSet(ExternalPaths.DEFAULT_CONFIGSET).create(); + } + + @Test + public void testFetchCommits() throws Exception { + var request = new ReplicationApi.FetchCommits(CORE_NAME); + var response = request.process(solrTestRule.getSolrClient(CORE_NAME)); + + assertNotNull(response); + assertNull(response.error); + assertEquals("OK", response.status); + assertNotNull(response.commits); + assertFalse(response.commits.isEmpty()); + } +} diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java new file mode 100644 index 000000000000..6d3213b6930f --- /dev/null +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java @@ -0,0 +1,42 @@ +package org.apache.solr.handler.admin.api; + +import static org.apache.solr.core.CoreContainer.ALLOW_PATHS_SYSPROP; + +import org.apache.solr.SolrTestCase; +import org.apache.solr.client.api.model.RestoreStatusResponse; +import org.apache.solr.client.solrj.request.ReplicationApi; +import org.apache.solr.util.ExternalPaths; +import org.apache.solr.util.SolrJettyTestRule; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; + +/** + * HTTP tests for {@code GET /api/cores/coreName/replication/restore} via the generated SolrJ + * request. + */ +public class FetchRestoreStatusAPITest extends SolrTestCase { + + private static final String CORE_NAME = "restoreStatusApiTestCore"; + + @ClassRule public static final SolrJettyTestRule solrTestRule = new SolrJettyTestRule(); + + @BeforeClass + public static void setupSolr() throws Exception { + System.setProperty(ALLOW_PATHS_SYSPROP, ExternalPaths.SERVER_HOME.toAbsolutePath().toString()); + solrTestRule.startSolr(createTempDir()); + solrTestRule.newCollection(CORE_NAME).withConfigSet(ExternalPaths.DEFAULT_CONFIGSET).create(); + } + + @Test + public void testFetchRestoreStatus() throws Exception { + var request = new ReplicationApi.FetchRestoreStatus(CORE_NAME); + var response = request.process(solrTestRule.getSolrClient(CORE_NAME)); + + assertNotNull(response); + assertNull(response.error); + assertEquals("OK", response.status); + assertNotNull(response.restoreStatus); + assertEquals(RestoreStatusResponse.RestoreState.NOT_STARTED, response.restoreStatus.status); + } +} From b1bfc9a818d1f829b53e0824b047bdba239c3dba Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 14:29:45 +0530 Subject: [PATCH 09/12] licenses --- .../handler/admin/api/FetchCommitsAPITest.java | 16 ++++++++++++++++ .../admin/api/FetchRestoreStatusAPITest.java | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/FetchCommitsAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchCommitsAPITest.java index 2f1b299f91c8..2d9217313dfb 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/FetchCommitsAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchCommitsAPITest.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.solr.handler.admin.api; import static org.apache.solr.core.CoreContainer.ALLOW_PATHS_SYSPROP; diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java index 6d3213b6930f..c58098e90c58 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.solr.handler.admin.api; import static org.apache.solr.core.CoreContainer.ALLOW_PATHS_SYSPROP; From d1ce8141d30334f983da00ab3a06f97195f4b546 Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 14:40:10 +0530 Subject: [PATCH 10/12] more clearer apis --- .../org/apache/solr/client/api/endpoint/ReplicationApis.java | 2 +- .../deployment-guide/pages/user-managed-index-replication.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java index 471692396d5b..8b0d94618df8 100644 --- a/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/ReplicationApis.java @@ -54,7 +54,7 @@ ReplicationDetailsResponse fetchReplicationDetails( @GET @CoreApiParameters - @Path("/restore") + @Path("/restore/status") @Operation( summary = "Return the status of the most recent restore operation.", tags = {"replication"}) diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc index 657f2d451b00..36f492746cdd 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc @@ -612,7 +612,7 @@ V2 API:: ==== [source,bash] ---- -http://{followerHost}:{port}/api/cores/{coreName}/replication/restore +http://{followerHost}:{port}/api/cores/{coreName}/replication/restore/status ---- ==== ====== From 1de34c883c478dbb6d5a082fd286ae0c917d9193 Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Sat, 24 Oct 2026 14:55:32 +0530 Subject: [PATCH 11/12] minor sanity changes --- .../api/model/ReplicationDetailsResponse.java | 3 ++- .../solr/handler/ReplicationHandler.java | 22 +++++++++---------- .../admin/api/CoreReplicationAPITest.java | 8 +++---- .../admin/api/FetchRestoreStatusAPITest.java | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/solr/api/src/java/org/apache/solr/client/api/model/ReplicationDetailsResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/ReplicationDetailsResponse.java index ac846cb269ce..a4215970f71c 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/ReplicationDetailsResponse.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/ReplicationDetailsResponse.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; +import org.apache.solr.client.api.model.CommitsResponse.CommitDetails; import org.apache.solr.client.api.util.ReflectWritable; public class ReplicationDetailsResponse extends SolrJerseyResponse { @@ -47,7 +48,7 @@ public static class ReplicationDetails implements ReflectWritable { public String indexPath; @JsonProperty("commits") - public List commits; + public List commits; @JsonProperty("isLeader") public Boolean isLeader; diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java index e1693296e19e..87ac3063b6c1 100644 --- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java @@ -76,6 +76,7 @@ import org.apache.solr.api.Api; import org.apache.solr.api.JerseyResource; import org.apache.solr.client.api.model.CommitsResponse; +import org.apache.solr.client.api.model.CommitsResponse.CommitDetails; import org.apache.solr.client.api.model.FileMetaData; import org.apache.solr.client.api.model.IndexVersionResponse; import org.apache.solr.client.api.model.ReplicationDetailsResponse; @@ -83,6 +84,8 @@ import org.apache.solr.client.api.model.ReplicationDetailsResponse.LeaderDetails; import org.apache.solr.client.api.model.ReplicationDetailsResponse.ReplicationDetails; import org.apache.solr.client.api.model.RestoreStatusResponse; +import org.apache.solr.client.api.model.RestoreStatusResponse.RestoreState; +import org.apache.solr.client.api.model.RestoreStatusResponse.RestoreStatus; import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; @@ -656,27 +659,24 @@ private void restore(SolrParams params, SolrQueryResponse rsp, SolrQueryRequest public RestoreStatusResponse getRestoreStatusResponse() { RestoreStatusResponse response = new RestoreStatusResponse(); - response.restoreStatus = new RestoreStatusResponse.RestoreStatus(); + response.restoreStatus = new RestoreStatus(); response.status = OK_STATUS; Future future = restoreFuture; if (future == null) { - response.restoreStatus.status = RestoreStatusResponse.RestoreState.NOT_STARTED; + response.restoreStatus.status = RestoreState.NOT_STARTED; return response; } response.restoreStatus.snapshotName = currentRestoreName; if (future.isDone()) { try { - response.restoreStatus.status = - future.get() - ? RestoreStatusResponse.RestoreState.SUCCESS - : RestoreStatusResponse.RestoreState.FAILED; + response.restoreStatus.status = future.get() ? RestoreState.SUCCESS : RestoreState.FAILED; } catch (Exception e) { - response.restoreStatus.status = RestoreStatusResponse.RestoreState.FAILED; + response.restoreStatus.status = RestoreState.FAILED; response.restoreStatus.exception = e.getMessage() != null ? e.getMessage() : e.toString(); } } else { - response.restoreStatus.status = RestoreStatusResponse.RestoreState.IN_PROGRESS; + response.restoreStatus.status = RestoreState.IN_PROGRESS; } return response; } @@ -1245,10 +1245,10 @@ private void addReplicationProperties(FollowerDetails followerDetails, Propertie } @SuppressWarnings("unchecked") - private List getCommitDetails() { - List commits = new ArrayList<>(); + private List getCommitDetails() { + List commits = new ArrayList<>(); for (NamedList namedList : getCommits()) { - CommitsResponse.CommitDetails commitDetail = new CommitsResponse.CommitDetails(); + CommitDetails commitDetail = new CommitDetails(); commitDetail.indexVersion = (Long) namedList.get("indexVersion"); commitDetail.generation = (Long) namedList.get(GENERATION); commitDetail.filelist = (List) namedList.get(CMD_GET_FILE_LIST); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java index 726c1b2488ef..2512e458555e 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java @@ -31,6 +31,7 @@ import org.apache.lucene.util.Constants; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.api.model.CommitsResponse; +import org.apache.solr.client.api.model.CommitsResponse.CommitDetails; import org.apache.solr.client.api.model.FileListResponse; import org.apache.solr.client.api.model.FileMetaData; import org.apache.solr.client.api.model.IndexVersionResponse; @@ -103,7 +104,7 @@ public void testFetchReplicationDetails() { } @Test - public void testGetRestoreStatus() throws Exception { + public void testGetRestoreStatus() { RestoreStatusResponse expected = new RestoreStatusResponse(); expected.status = "OK"; expected.restoreStatus = new RestoreStatusResponse.RestoreStatus(); @@ -120,9 +121,8 @@ public void testGetRestoreStatus() throws Exception { } @Test - public void testGetCommits() throws Exception { - CommitsResponse.CommitDetails commit = - new CommitsResponse.CommitDetails(42L, 7L, List.of("segments_7", "_0.cfs")); + public void testGetCommits() { + CommitDetails commit = new CommitDetails(42L, 7L, List.of("segments_7", "_0.cfs")); CommitsResponse expected = new CommitsResponse(); expected.status = "OK"; expected.commits = List.of(commit); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java index c58098e90c58..993afee20278 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/FetchRestoreStatusAPITest.java @@ -28,7 +28,7 @@ import org.junit.Test; /** - * HTTP tests for {@code GET /api/cores/coreName/replication/restore} via the generated SolrJ + * HTTP tests for {@code GET /api/cores/coreName/replication/restore/status} via the generated SolrJ * request. */ public class FetchRestoreStatusAPITest extends SolrTestCase { From 9599df2d01f77a9c1dfcb12f1e10938054d15441 Mon Sep 17 00:00:00 2001 From: Eric Pugh Date: Mon, 26 Oct 2026 06:50:47 -0400 Subject: [PATCH 12/12] small ref guide fix --- .../deployment-guide/pages/user-managed-index-replication.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc index 36f492746cdd..781c2c54861e 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/user-managed-index-replication.adoc @@ -594,7 +594,6 @@ For file system repository, location defaults to core's dataDir (data directory) `restorestatus`:: Check the status of a running restore operation. - + [tabs#restorestatus-request] ====== @@ -612,7 +611,7 @@ V2 API:: ==== [source,bash] ---- -http://{followerHost}:{port}/api/cores/{coreName}/replication/restore/status +http://{leaderHost}:{port}/api/cores/{coreName}/replication/restore/status ---- ==== ======