Skip to content

Commit bdd4332

Browse files
authored
feat(action): implement View, Ingestion, Scale and RemoteStore APIs (#16)
* feat(action): implement View, Ingestion, Scale and RemoteStore APIs for OpenSearch 3 Add HTTP action implementations for OpenSearch 3 APIs that were previously throwing UnsupportedOperationException: - View API: create, get, delete, update, search, and list view names - Streaming Ingestion API: pause, resume, and get ingestion state - Scale Index API: search-only scaling support - Remote Store Metadata API: cluster remote store metadata retrieval - CreateIndex: add support for context parameter in OpenSearch 3 Includes comprehensive unit tests for all new actions and ByteArrayStreamOutput. * fix: address Codex review findings for response parsing and test quality - HttpGetIngestionStateAction: fully parse ingestion_state per-shard data and next_page_token instead of returning empty arrays - HttpRemoteStoreMetadataAction: fully parse indices/shards metadata instead of skipping the indices section - HttpListViewNamesAction: remove trailing slash from /views/ endpoint - HttpScaleIndexAction: add setAccessible for package-private class access and document why reflection is required - HttpCreateViewAction/HttpUpdateViewAction: extract buildRequestBody() for testability - HttpListViewNamesAction: extract parseViewNames() for testability - Update all tests to exercise production code instead of duplicated helpers, add payload parsing and URL encoding coverage
1 parent ce57ab9 commit bdd4332

29 files changed

Lines changed: 2537 additions & 51 deletions

src/main/java/org/codelibs/fesen/client/HttpAbstractClient.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
import org.opensearch.action.admin.cluster.node.usage.NodesUsageRequest;
103103
import org.opensearch.action.admin.cluster.node.usage.NodesUsageRequestBuilder;
104104
import org.opensearch.action.admin.cluster.node.usage.NodesUsageResponse;
105+
import org.opensearch.action.admin.cluster.remotestore.metadata.RemoteStoreMetadataAction;
105106
import org.opensearch.action.admin.cluster.remotestore.metadata.RemoteStoreMetadataRequestBuilder;
106107
import org.opensearch.action.admin.cluster.remotestore.restore.RestoreRemoteStoreAction;
107108
import org.opensearch.action.admin.cluster.remotestore.restore.RestoreRemoteStoreRequest;
@@ -286,6 +287,9 @@
286287
import org.opensearch.action.admin.indices.rollover.RolloverRequestBuilder;
287288
import org.opensearch.action.admin.indices.rollover.RolloverResponse;
288289
import org.opensearch.action.admin.indices.scale.searchonly.ScaleIndexRequestBuilder;
290+
import org.opensearch.action.admin.indices.streamingingestion.pause.PauseIngestionAction;
291+
import org.opensearch.action.admin.indices.streamingingestion.resume.ResumeIngestionAction;
292+
import org.opensearch.action.admin.indices.streamingingestion.state.GetIngestionStateAction;
289293
import org.opensearch.action.admin.indices.segments.IndicesSegmentResponse;
290294
import org.opensearch.action.admin.indices.segments.IndicesSegmentsAction;
291295
import org.opensearch.action.admin.indices.segments.IndicesSegmentsRequest;
@@ -339,6 +343,10 @@
339343
import org.opensearch.action.admin.indices.validate.query.ValidateQueryRequest;
340344
import org.opensearch.action.admin.indices.validate.query.ValidateQueryRequestBuilder;
341345
import org.opensearch.action.admin.indices.validate.query.ValidateQueryResponse;
346+
import org.opensearch.action.admin.indices.view.CreateViewAction;
347+
import org.opensearch.action.admin.indices.view.DeleteViewAction;
348+
import org.opensearch.action.admin.indices.view.GetViewAction;
349+
import org.opensearch.action.admin.indices.view.UpdateViewAction;
342350
import org.opensearch.action.bulk.BulkAction;
343351
import org.opensearch.action.bulk.BulkRequest;
344352
import org.opensearch.action.bulk.BulkRequestBuilder;
@@ -1521,13 +1529,13 @@ public void wlmStats(WlmStatsRequest request, ActionListener<WlmStatsResponse> l
15211529

15221530
@Override
15231531
public RemoteStoreMetadataRequestBuilder prepareRemoteStoreMetadata(final String clusterUUID, final String clusterName) {
1524-
throw new UnsupportedOperationException("prepareRemoteStoreMetadata is not supported");
1532+
return new RemoteStoreMetadataRequestBuilder(this, RemoteStoreMetadataAction.INSTANCE);
15251533
}
15261534

15271535
@Override
15281536
public void remoteStoreMetadata(org.opensearch.action.admin.cluster.remotestore.metadata.RemoteStoreMetadataRequest request,
15291537
org.opensearch.core.action.ActionListener<org.opensearch.action.admin.cluster.remotestore.metadata.RemoteStoreMetadataResponse> listener) {
1530-
throw new UnsupportedOperationException("remoteStoreMetadata is not supported");
1538+
execute(RemoteStoreMetadataAction.INSTANCE, request, listener);
15311539
}
15321540

15331541
}
@@ -2087,83 +2095,83 @@ public SegmentReplicationStatsRequestBuilder prepareSegmentReplicationStats(fina
20872095
@Override
20882096
public void createView(org.opensearch.action.admin.indices.view.CreateViewAction.Request request,
20892097
ActionListener<org.opensearch.action.admin.indices.view.GetViewAction.Response> listener) {
2090-
throw new UnsupportedOperationException("Not implemented yet");
2098+
execute(CreateViewAction.INSTANCE, request, listener);
20912099
}
20922100

20932101
@Override
20942102
public ActionFuture<org.opensearch.action.admin.indices.view.GetViewAction.Response> createView(
20952103
org.opensearch.action.admin.indices.view.CreateViewAction.Request request) {
2096-
throw new UnsupportedOperationException("Not implemented yet");
2104+
return execute(CreateViewAction.INSTANCE, request);
20972105
}
20982106

20992107
@Override
21002108
public void getView(org.opensearch.action.admin.indices.view.GetViewAction.Request request,
21012109
ActionListener<org.opensearch.action.admin.indices.view.GetViewAction.Response> listener) {
2102-
throw new UnsupportedOperationException("Not implemented yet");
2110+
execute(GetViewAction.INSTANCE, request, listener);
21032111
}
21042112

21052113
@Override
21062114
public ActionFuture<org.opensearch.action.admin.indices.view.GetViewAction.Response> getView(
21072115
org.opensearch.action.admin.indices.view.GetViewAction.Request request) {
2108-
throw new UnsupportedOperationException("Not implemented yet");
2116+
return execute(GetViewAction.INSTANCE, request);
21092117
}
21102118

21112119
@Override
21122120
public void deleteView(org.opensearch.action.admin.indices.view.DeleteViewAction.Request request,
21132121
ActionListener<AcknowledgedResponse> listener) {
2114-
throw new UnsupportedOperationException("Not implemented yet");
2122+
execute(DeleteViewAction.INSTANCE, request, listener);
21152123
}
21162124

21172125
@Override
21182126
public ActionFuture<AcknowledgedResponse> deleteView(org.opensearch.action.admin.indices.view.DeleteViewAction.Request request) {
2119-
throw new UnsupportedOperationException("Not implemented yet");
2127+
return execute(DeleteViewAction.INSTANCE, request);
21202128
}
21212129

21222130
@Override
21232131
public void updateView(org.opensearch.action.admin.indices.view.CreateViewAction.Request request,
21242132
ActionListener<org.opensearch.action.admin.indices.view.GetViewAction.Response> listener) {
2125-
throw new UnsupportedOperationException("Not implemented yet");
2133+
execute(UpdateViewAction.INSTANCE, request, listener);
21262134
}
21272135

21282136
@Override
21292137
public ActionFuture<org.opensearch.action.admin.indices.view.GetViewAction.Response> updateView(
21302138
org.opensearch.action.admin.indices.view.CreateViewAction.Request request) {
2131-
throw new UnsupportedOperationException("Not implemented yet");
2139+
return execute(UpdateViewAction.INSTANCE, request);
21322140
}
21332141

21342142
@Override
21352143
public ActionFuture<PauseIngestionResponse> pauseIngestion(PauseIngestionRequest request) {
2136-
throw new UnsupportedOperationException("Not implemented yet");
2144+
return execute(PauseIngestionAction.INSTANCE, request);
21372145
}
21382146

21392147
@Override
21402148
public void pauseIngestion(PauseIngestionRequest request, ActionListener<PauseIngestionResponse> listener) {
2141-
throw new UnsupportedOperationException("Not implemented yet");
2149+
execute(PauseIngestionAction.INSTANCE, request, listener);
21422150
}
21432151

21442152
@Override
21452153
public ActionFuture<ResumeIngestionResponse> resumeIngestion(ResumeIngestionRequest request) {
2146-
throw new UnsupportedOperationException("Not implemented yet");
2154+
return execute(ResumeIngestionAction.INSTANCE, request);
21472155
}
21482156

21492157
@Override
21502158
public void resumeIngestion(ResumeIngestionRequest request, ActionListener<ResumeIngestionResponse> listener) {
2151-
throw new UnsupportedOperationException("Not implemented yet");
2159+
execute(ResumeIngestionAction.INSTANCE, request, listener);
21522160
}
21532161

21542162
@Override
21552163
public ActionFuture<GetIngestionStateResponse> getIngestionState(GetIngestionStateRequest request) {
2156-
throw new UnsupportedOperationException("Not implemented yet");
2164+
return execute(GetIngestionStateAction.INSTANCE, request);
21572165
}
21582166

21592167
@Override
21602168
public void getIngestionState(GetIngestionStateRequest request, ActionListener<GetIngestionStateResponse> listener) {
2161-
throw new UnsupportedOperationException("Not implemented yet");
2169+
execute(GetIngestionStateAction.INSTANCE, request, listener);
21622170
}
21632171

21642172
@Override
21652173
public ScaleIndexRequestBuilder prepareScaleSearchOnly(String index, boolean searchOnly) {
2166-
throw new UnsupportedOperationException("Not implemented yet");
2174+
return new ScaleIndexRequestBuilder(this, searchOnly, index);
21672175
}
21682176

21692177
}

src/main/java/org/codelibs/fesen/client/HttpClient.java

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@
105105
import org.codelibs.fesen.client.action.HttpMultiTermVectorsAction;
106106
import org.codelibs.fesen.client.action.HttpNodesInfoAction;
107107
import org.codelibs.fesen.client.action.HttpNodesUsageAction;
108+
import org.codelibs.fesen.client.action.HttpCreateViewAction;
109+
import org.codelibs.fesen.client.action.HttpGetViewAction;
110+
import org.codelibs.fesen.client.action.HttpDeleteViewAction;
111+
import org.codelibs.fesen.client.action.HttpUpdateViewAction;
112+
import org.codelibs.fesen.client.action.HttpSearchViewAction;
113+
import org.codelibs.fesen.client.action.HttpListViewNamesAction;
114+
import org.codelibs.fesen.client.action.HttpPauseIngestionAction;
115+
import org.codelibs.fesen.client.action.HttpResumeIngestionAction;
116+
import org.codelibs.fesen.client.action.HttpGetIngestionStateAction;
117+
import org.codelibs.fesen.client.action.HttpScaleIndexAction;
118+
import org.codelibs.fesen.client.action.HttpRemoteStoreMetadataAction;
108119
import org.codelibs.fesen.client.action.HttpRecoveryAction;
109120
import org.codelibs.fesen.client.action.HttpRemoteInfoAction;
110121
import org.codelibs.fesen.client.action.HttpTermVectorsAction;
@@ -217,6 +228,25 @@
217228
import org.opensearch.action.admin.cluster.wlm.WlmStatsAction;
218229
import org.opensearch.action.admin.cluster.wlm.WlmStatsRequest;
219230
import org.opensearch.action.admin.cluster.wlm.WlmStatsResponse;
231+
import org.opensearch.action.admin.indices.view.CreateViewAction;
232+
import org.opensearch.action.admin.indices.view.GetViewAction;
233+
import org.opensearch.action.admin.indices.view.DeleteViewAction;
234+
import org.opensearch.action.admin.indices.view.UpdateViewAction;
235+
import org.opensearch.action.admin.indices.view.SearchViewAction;
236+
import org.opensearch.action.admin.indices.view.ListViewNamesAction;
237+
import org.opensearch.action.admin.indices.streamingingestion.pause.PauseIngestionAction;
238+
import org.opensearch.action.admin.indices.streamingingestion.pause.PauseIngestionRequest;
239+
import org.opensearch.action.admin.indices.streamingingestion.pause.PauseIngestionResponse;
240+
import org.opensearch.action.admin.indices.streamingingestion.resume.ResumeIngestionAction;
241+
import org.opensearch.action.admin.indices.streamingingestion.resume.ResumeIngestionRequest;
242+
import org.opensearch.action.admin.indices.streamingingestion.resume.ResumeIngestionResponse;
243+
import org.opensearch.action.admin.indices.streamingingestion.state.GetIngestionStateAction;
244+
import org.opensearch.action.admin.indices.streamingingestion.state.GetIngestionStateRequest;
245+
import org.opensearch.action.admin.indices.streamingingestion.state.GetIngestionStateResponse;
246+
import org.opensearch.action.admin.indices.scale.searchonly.ScaleIndexAction;
247+
import org.opensearch.action.admin.cluster.remotestore.metadata.RemoteStoreMetadataAction;
248+
import org.opensearch.action.admin.cluster.remotestore.metadata.RemoteStoreMetadataRequest;
249+
import org.opensearch.action.admin.cluster.remotestore.metadata.RemoteStoreMetadataResponse;
220250
import org.opensearch.action.admin.indices.alias.IndicesAliasesAction;
221251
import org.opensearch.action.admin.indices.alias.IndicesAliasesRequest;
222252
import org.opensearch.action.admin.indices.alias.get.GetAliasesAction;
@@ -1018,6 +1048,57 @@ public HttpClient(final Settings settings, final ThreadPool threadPool, final Li
10181048
new HttpMultiTermVectorsAction(this, MultiTermVectorsAction.INSTANCE).execute((MultiTermVectorsRequest) request,
10191049
actionListener);
10201050
});
1051+
1052+
// View API
1053+
actions.put(CreateViewAction.INSTANCE, (request, listener) -> {
1054+
new HttpCreateViewAction(this, CreateViewAction.INSTANCE).execute((CreateViewAction.Request) request,
1055+
(ActionListener<GetViewAction.Response>) listener);
1056+
});
1057+
actions.put(GetViewAction.INSTANCE, (request, listener) -> {
1058+
new HttpGetViewAction(this, GetViewAction.INSTANCE).execute((GetViewAction.Request) request,
1059+
(ActionListener<GetViewAction.Response>) listener);
1060+
});
1061+
actions.put(DeleteViewAction.INSTANCE, (request, listener) -> {
1062+
new HttpDeleteViewAction(this, DeleteViewAction.INSTANCE).execute((DeleteViewAction.Request) request,
1063+
(ActionListener<AcknowledgedResponse>) listener);
1064+
});
1065+
actions.put(UpdateViewAction.INSTANCE, (request, listener) -> {
1066+
new HttpUpdateViewAction(this, UpdateViewAction.INSTANCE).execute((CreateViewAction.Request) request,
1067+
(ActionListener<GetViewAction.Response>) listener);
1068+
});
1069+
actions.put(SearchViewAction.INSTANCE, (request, listener) -> {
1070+
new HttpSearchViewAction(this, SearchViewAction.INSTANCE).execute((SearchViewAction.Request) request,
1071+
(ActionListener<SearchResponse>) listener);
1072+
});
1073+
actions.put(ListViewNamesAction.INSTANCE, (request, listener) -> {
1074+
new HttpListViewNamesAction(this, ListViewNamesAction.INSTANCE).execute((ListViewNamesAction.Request) request,
1075+
(ActionListener<ListViewNamesAction.Response>) listener);
1076+
});
1077+
1078+
// Streaming Ingestion API
1079+
actions.put(PauseIngestionAction.INSTANCE, (request, listener) -> {
1080+
new HttpPauseIngestionAction(this, PauseIngestionAction.INSTANCE).execute((PauseIngestionRequest) request,
1081+
(ActionListener<PauseIngestionResponse>) listener);
1082+
});
1083+
actions.put(ResumeIngestionAction.INSTANCE, (request, listener) -> {
1084+
new HttpResumeIngestionAction(this, ResumeIngestionAction.INSTANCE).execute((ResumeIngestionRequest) request,
1085+
(ActionListener<ResumeIngestionResponse>) listener);
1086+
});
1087+
actions.put(GetIngestionStateAction.INSTANCE, (request, listener) -> {
1088+
new HttpGetIngestionStateAction(this, GetIngestionStateAction.INSTANCE).execute((GetIngestionStateRequest) request,
1089+
(ActionListener<GetIngestionStateResponse>) listener);
1090+
});
1091+
1092+
// Scale (Search-Only) API
1093+
actions.put(ScaleIndexAction.INSTANCE, (request, listener) -> {
1094+
new HttpScaleIndexAction(this, ScaleIndexAction.INSTANCE).execute(request, (ActionListener<AcknowledgedResponse>) listener);
1095+
});
1096+
1097+
// Remote Store Metadata API
1098+
actions.put(RemoteStoreMetadataAction.INSTANCE, (request, listener) -> {
1099+
new HttpRemoteStoreMetadataAction(this, RemoteStoreMetadataAction.INSTANCE).execute((RemoteStoreMetadataRequest) request,
1100+
(ActionListener<RemoteStoreMetadataResponse>) listener);
1101+
});
10211102
}
10221103

10231104
@Override
@@ -1288,29 +1369,29 @@ protected WorkerThread(final ForkJoinPool pool) {
12881369
@Override
12891370
public void searchView(org.opensearch.action.admin.indices.view.SearchViewAction.Request request,
12901371
ActionListener<SearchResponse> listener) {
1291-
throw new UnsupportedOperationException("Not implemented yet");
1372+
execute(SearchViewAction.INSTANCE, request, listener);
12921373
}
12931374

12941375
@Override
12951376
public ActionFuture<SearchResponse> searchView(org.opensearch.action.admin.indices.view.SearchViewAction.Request request) {
1296-
throw new UnsupportedOperationException("Not implemented yet");
1377+
return execute(SearchViewAction.INSTANCE, request);
12971378
}
12981379

12991380
@Override
13001381
public void listViewNames(org.opensearch.action.admin.indices.view.ListViewNamesAction.Request request,
13011382
ActionListener<org.opensearch.action.admin.indices.view.ListViewNamesAction.Response> listener) {
1302-
throw new UnsupportedOperationException("Not implemented yet");
1383+
execute(ListViewNamesAction.INSTANCE, request, listener);
13031384
}
13041385

13051386
@Override
13061387
public ActionFuture<org.opensearch.action.admin.indices.view.ListViewNamesAction.Response> listViewNames(
13071388
org.opensearch.action.admin.indices.view.ListViewNamesAction.Request request) {
1308-
throw new UnsupportedOperationException("Not implemented yet");
1389+
return execute(ListViewNamesAction.INSTANCE, request);
13091390
}
13101391

13111392
@Override
13121393
public SearchRequestBuilder prepareStreamSearch(final String... indices) {
1313-
throw new UnsupportedOperationException("prepareStreamSearch is not supported");
1394+
return new SearchRequestBuilder(this, SearchAction.INSTANCE).setIndices(indices);
13141395
}
13151396

13161397
}

0 commit comments

Comments
 (0)