diff --git a/server/src/internalClusterTest/java/org/opensearch/action/admin/indices/view/ViewIT.java b/server/src/internalClusterTest/java/org/opensearch/action/admin/indices/view/ViewIT.java index 9c7b550a32ec5..9630c484d27db 100644 --- a/server/src/internalClusterTest/java/org/opensearch/action/admin/indices/view/ViewIT.java +++ b/server/src/internalClusterTest/java/org/opensearch/action/admin/indices/view/ViewIT.java @@ -8,11 +8,8 @@ package org.opensearch.action.admin.indices.view; -import org.opensearch.action.search.SearchRequest; -import org.opensearch.action.search.SearchResponse; -import org.opensearch.index.IndexNotFoundException; -import org.opensearch.test.BackgroundIndexer; -import org.opensearch.test.OpenSearchIntegTestCase; +import org.opensearch.ResourceNotFoundException; +import org.opensearch.cluster.metadata.View; import org.opensearch.test.OpenSearchIntegTestCase.ClusterScope; import org.opensearch.test.OpenSearchIntegTestCase.Scope; import org.hamcrest.MatcherAssert; @@ -21,52 +18,94 @@ import static org.opensearch.test.hamcrest.OpenSearchAssertions.assertHitCount; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; @ClusterScope(scope = Scope.TEST, numDataNodes = 2) -public class ViewIT extends OpenSearchIntegTestCase { +public class ViewIT extends ViewTestBase { - private int createIndexWithDocs(final String indexName) throws Exception { - createIndex(indexName); - ensureGreen(indexName); + public void testCreateView() throws Exception { + final String viewName = "test-view"; + final String indexPattern = "test-index-*"; - final int numOfDocs = scaledRandomIntBetween(0, 200); - try (final BackgroundIndexer indexer = new BackgroundIndexer(indexName, "_doc", client(), numOfDocs)) { - waitForDocs(numOfDocs, indexer); - } + logger.info("Testing createView with valid parameters"); + final View view = createView(viewName, indexPattern).getView(); + MatcherAssert.assertThat(view.getName(), is(viewName)); + MatcherAssert.assertThat(view.getTargets().size(), is(1)); + MatcherAssert.assertThat(view.getTargets().get(0).getIndexPattern(), is(indexPattern)); - refresh(indexName); - assertHitCount(client().prepareSearch(indexName).setSize(0).get(), numOfDocs); - return numOfDocs; + logger.info("Testing createView with existing view name"); + final Exception ex = assertThrows(ResourceNotFoundException.class, () -> createView(viewName, "new-pattern")); + MatcherAssert.assertThat(ex.getMessage(), is("View [test-view] already exists")); } - private GetViewAction.Response createView(final String name, final String indexPattern) throws Exception { - final CreateViewAction.Request request = new CreateViewAction.Request( - name, - null, - List.of(new CreateViewAction.Request.Target(indexPattern)) - ); - final GetViewAction.Response response = client().admin().indices().createView(request).actionGet(); - performRemoteStoreTestAction(); - return response; + public void testGetView() throws Exception { + final String viewName = "existing-view"; + + logger.info("Testing getView with existing view"); + createView(viewName, "index-*"); + final View view = getView(viewName).getView(); + MatcherAssert.assertThat(view.getName(), is(viewName)); + + logger.info("Testing getView with non-existent view"); + final Exception whenNeverExistedEx = assertThrows(ResourceNotFoundException.class, () -> getView("non-existent")); + MatcherAssert.assertThat(whenNeverExistedEx.getMessage(), is("View [non-existent] does not exist")); } - private void deleteView(final String name) { - client().admin().indices().deleteView(new DeleteViewAction.Request(name)).actionGet(); - performRemoteStoreTestAction(); + public void testDeleteView() throws Exception { + final String viewName = "deleted-view"; + createView(viewName, "index-*"); + + logger.info("Testing deleteView with existing view"); + deleteView(viewName); + final Exception whenDeletedEx = assertThrows(ResourceNotFoundException.class, () -> getView(viewName)); + MatcherAssert.assertThat(whenDeletedEx.getMessage(), is("View [deleted-view] does not exist")); + + logger.info("Testing deleteView with non-existent view"); + final Exception whenNeverExistedEx = assertThrows(ResourceNotFoundException.class, () -> deleteView("non-existent")); + MatcherAssert.assertThat(whenNeverExistedEx.getMessage(), is("View [non-existent] does not exist")); } - private List listViews() { - return client().listViewNames(new ListViewNamesAction.Request()).actionGet().getViewNames(); + public void testUpdateView() throws Exception { + final String viewName = "updatable-view"; + final View originalView = createView(viewName, "index-old-*").getView(); + + logger.info("Testing updateView with existing view"); + final View updatedView = updateView(viewName, "new description", "index-new-*").getView(); + + MatcherAssert.assertThat(updatedView, not(is(originalView))); + MatcherAssert.assertThat(updatedView.getDescription(), is("new description")); + MatcherAssert.assertThat(updatedView.getTargets(), hasSize(1)); + MatcherAssert.assertThat(updatedView.getTargets().get(0).getIndexPattern(), is("index-new-*")); + + logger.info("Testing updateView with non-existent view"); + final Exception whenNeverExistedEx = assertThrows( + ResourceNotFoundException.class, + () -> updateView("non-existent", null, "index-*") + ); + MatcherAssert.assertThat(whenNeverExistedEx.getMessage(), is("View [non-existent] does not exist")); } - private SearchResponse searchView(final String viewName) throws Exception { - final SearchViewAction.Request request = SearchViewAction.createRequestWith(viewName, new SearchRequest()); - final SearchResponse response = client().searchView(request).actionGet(); - return response; + public void testListViewNames() throws Exception { + final String view1 = "view1"; + final String view2 = "view2"; + createView(view1, "index-1-*"); + createView(view2, "index-2-*"); + + logger.info("Testing listViewNames"); + final List views = listViewNames(); + MatcherAssert.assertThat(views, containsInAnyOrder(view1, view2)); + + logger.info("Testing listViewNames after deleting a view"); + deleteView(view1); + final List viewsAfterDeletion = listViewNames(); + MatcherAssert.assertThat(viewsAfterDeletion, not(contains(view1))); + MatcherAssert.assertThat(viewsAfterDeletion, contains(view2)); } - public void testBasicOperations() throws Exception { + public void testSearchOperations() throws Exception { final String indexInView1 = "index-1"; final String indexInView2 = "index-2"; final String indexNotInView = "another-index-1"; @@ -77,7 +116,7 @@ public void testBasicOperations() throws Exception { logger.info("Testing view with no matches"); createView("no-matches", "this-pattern-will-match-nothing"); - final IndexNotFoundException ex = assertThrows(IndexNotFoundException.class, () -> searchView("no-matches")); + final Exception ex = assertThrows(ResourceNotFoundException.class, () -> searchView("no-matches")); MatcherAssert.assertThat(ex.getMessage(), is("no such index [this-pattern-will-match-nothing]")); logger.info("Testing view with exact index match"); @@ -87,31 +126,10 @@ public void testBasicOperations() throws Exception { logger.info("Testing view with wildcard matches"); createView("both-indices", "index-*"); assertHitCount(searchView("both-indices"), indexInView1DocCount + indexInView2DocCount); - } - - public void testListViewNames() throws Exception { - logger.info("Create a single view"); - createView("view1", "*"); - final List viewNames1 = listViews(); - - MatcherAssert.assertThat(viewNames1, contains("view1")); - - logger.info("Create a second view"); - createView("view2", "*"); - final List viewNames2 = listViews(); - - MatcherAssert.assertThat(viewNames2, contains("view1", "view2")); - - logger.info("Delete a view"); - deleteView("view1"); - final List viewNamesAfterDelete = listViews(); - - MatcherAssert.assertThat(viewNamesAfterDelete, contains("view2")); - logger.info("Update a view"); - client().admin().indices().updateView(new CreateViewAction.Request("view2", "newDescription", List.of())); - final List viewNamesAfterUpdate = listViews(); + logger.info("Testing searchView with non-existent view"); + final Exception whenNeverExistedEx = assertThrows(ResourceNotFoundException.class, () -> searchView("non-existent")); + MatcherAssert.assertThat(whenNeverExistedEx.getMessage(), is("View [non-existent] does not exist")); - MatcherAssert.assertThat(viewNamesAfterUpdate, contains("view2")); } } diff --git a/server/src/internalClusterTest/java/org/opensearch/action/admin/indices/view/ViewTestBase.java b/server/src/internalClusterTest/java/org/opensearch/action/admin/indices/view/ViewTestBase.java new file mode 100644 index 0000000000000..2d039f63f3dc2 --- /dev/null +++ b/server/src/internalClusterTest/java/org/opensearch/action/admin/indices/view/ViewTestBase.java @@ -0,0 +1,74 @@ +/* + * 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.admin.indices.view; + +import org.opensearch.action.search.SearchRequest; +import org.opensearch.action.search.SearchResponse; +import org.opensearch.test.BackgroundIndexer; +import org.opensearch.test.OpenSearchIntegTestCase; + +import java.util.List; + +import static org.opensearch.test.hamcrest.OpenSearchAssertions.assertHitCount; + +public abstract class ViewTestBase extends OpenSearchIntegTestCase { + + protected int createIndexWithDocs(final String indexName) throws Exception { + createIndex(indexName); + ensureGreen(indexName); + + final int numOfDocs = scaledRandomIntBetween(0, 200); + try (final BackgroundIndexer indexer = new BackgroundIndexer(indexName, "_doc", client(), numOfDocs)) { + waitForDocs(numOfDocs, indexer); + } + + refresh(indexName); + assertHitCount(client().prepareSearch(indexName).setSize(0).get(), numOfDocs); + return numOfDocs; + } + + protected GetViewAction.Response createView(final String name, final String indexPattern) throws Exception { + final CreateViewAction.Request request = new CreateViewAction.Request( + name, + null, + List.of(new CreateViewAction.Request.Target(indexPattern)) + ); + return client().admin().indices().createView(request).actionGet(); + } + + protected GetViewAction.Response getView(final String name) { + return client().admin().indices().getView(new GetViewAction.Request(name)).actionGet(); + + } + + protected void deleteView(final String name) { + client().admin().indices().deleteView(new DeleteViewAction.Request(name)).actionGet(); + performRemoteStoreTestAction(); + } + + protected List listViewNames() { + return client().listViewNames(new ListViewNamesAction.Request()).actionGet().getViewNames(); + } + + protected SearchResponse searchView(final String viewName) throws Exception { + final SearchViewAction.Request request = SearchViewAction.createRequestWith(viewName, new SearchRequest()); + final SearchResponse response = client().searchView(request).actionGet(); + return response; + } + + protected GetViewAction.Response updateView(final String name, final String description, final String indexPattern) { + final CreateViewAction.Request request = new CreateViewAction.Request( + name, + description, + List.of(new CreateViewAction.Request.Target(indexPattern)) + ); + final GetViewAction.Response response = client().admin().indices().updateView(request).actionGet(); + return response; + } +} diff --git a/server/src/main/java/org/opensearch/action/admin/indices/view/GetViewAction.java b/server/src/main/java/org/opensearch/action/admin/indices/view/GetViewAction.java index 73a9ff1006aba..330646837b9e2 100644 --- a/server/src/main/java/org/opensearch/action/admin/indices/view/GetViewAction.java +++ b/server/src/main/java/org/opensearch/action/admin/indices/view/GetViewAction.java @@ -127,6 +127,10 @@ public Response(final StreamInput in) throws IOException { this.view = new View(in); } + public View getView() { + return view; + } + @Override public void writeTo(final StreamOutput out) throws IOException { this.view.writeTo(out); diff --git a/server/src/main/java/org/opensearch/action/admin/indices/view/ViewService.java b/server/src/main/java/org/opensearch/action/admin/indices/view/ViewService.java index 484d7a158a7fa..3eb983b236b57 100644 --- a/server/src/main/java/org/opensearch/action/admin/indices/view/ViewService.java +++ b/server/src/main/java/org/opensearch/action/admin/indices/view/ViewService.java @@ -132,7 +132,7 @@ View getViewOrThrowException(final String viewName) { .map(ClusterState::metadata) .map(m -> m.views()) .map(views -> views.get(viewName)) - .orElseThrow(() -> new ResourceNotFoundException("no such view [" + viewName + "]")); + .orElseThrow(() -> new ResourceNotFoundException("View [" + viewName + "] does not exist")); } private enum Operation { diff --git a/server/src/main/java/org/opensearch/client/IndicesAdminClient.java b/server/src/main/java/org/opensearch/client/IndicesAdminClient.java index c1a75b02aaf95..588584cd8a280 100644 --- a/server/src/main/java/org/opensearch/client/IndicesAdminClient.java +++ b/server/src/main/java/org/opensearch/client/IndicesAdminClient.java @@ -848,21 +848,21 @@ public interface IndicesAdminClient extends OpenSearchClient { /** Create a view */ ActionFuture createView(CreateViewAction.Request request); - /** Gets a view */ + /** Get the details of a view */ void getView(GetViewAction.Request request, ActionListener listener); - /** Gets a view */ + /** Get the details of a view */ ActionFuture getView(GetViewAction.Request request); - /** Create a view */ + /** Delete a view */ void deleteView(DeleteViewAction.Request request, ActionListener listener); - /** Create a view */ + /** Delete a view */ ActionFuture deleteView(DeleteViewAction.Request request); - /** Create a view */ + /** Update a view */ void updateView(CreateViewAction.Request request, ActionListener listener); - /** Create a view */ + /** Update a view */ ActionFuture updateView(CreateViewAction.Request request); } diff --git a/server/src/test/java/org/opensearch/action/admin/indices/view/ViewServiceTest.java b/server/src/test/java/org/opensearch/action/admin/indices/view/ViewServiceTest.java index 3f76d59f45d90..93fa70b2981ac 100644 --- a/server/src/test/java/org/opensearch/action/admin/indices/view/ViewServiceTest.java +++ b/server/src/test/java/org/opensearch/action/admin/indices/view/ViewServiceTest.java @@ -20,7 +20,6 @@ import org.hamcrest.MatcherAssert; import org.junit.After; import org.junit.Before; -import org.junit.Test; import java.util.List; import java.util.Map;