forked from opensearch-project/OpenSearch
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Views, simplify data access and manipulation by providing a virtual layer over one or more indices Signed-off-by: Peter Nied <[email protected]> Signed-off-by: Peter Nied <[email protected]> Signed-off-by: Shivansh Arora <[email protected]>
- Loading branch information
Showing
34 changed files
with
2,913 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
154 changes: 154 additions & 0 deletions
154
server/src/internalClusterTest/java/org/opensearch/action/admin/indices/view/ViewIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/* | ||
* 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.cluster.metadata.View; | ||
import org.opensearch.index.IndexNotFoundException; | ||
import org.opensearch.test.OpenSearchIntegTestCase.ClusterScope; | ||
import org.opensearch.test.OpenSearchIntegTestCase.Scope; | ||
import org.hamcrest.MatcherAssert; | ||
|
||
import java.util.List; | ||
|
||
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 ViewTestBase { | ||
|
||
public void testCreateView() throws Exception { | ||
final String viewName = randomAlphaOfLength(8); | ||
final String indexPattern = randomAlphaOfLength(8); | ||
|
||
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().first().getIndexPattern(), is(indexPattern)); | ||
|
||
logger.info("Testing createView with existing view name"); | ||
final Exception ex = assertThrows(ViewAlreadyExistsException.class, () -> createView(viewName, randomAlphaOfLength(8))); | ||
MatcherAssert.assertThat(ex.getMessage(), is("View [" + viewName + "] already exists")); | ||
} | ||
|
||
public void testCreateViewTargetsSet() throws Exception { | ||
final String viewName = randomAlphaOfLength(8); | ||
final String indexPattern = "a" + randomAlphaOfLength(8); | ||
final String indexPattern2 = "b" + randomAlphaOfLength(8); | ||
final List<String> targetPatterns = List.of(indexPattern2, indexPattern, indexPattern); | ||
|
||
logger.info("Testing createView with targets that will be reordered and deduplicated"); | ||
final View view = createView(viewName, targetPatterns).getView(); | ||
MatcherAssert.assertThat(view.getName(), is(viewName)); | ||
MatcherAssert.assertThat(view.getTargets().size(), is(2)); | ||
MatcherAssert.assertThat(view.getTargets().first().getIndexPattern(), is(indexPattern)); | ||
MatcherAssert.assertThat(view.getTargets().last().getIndexPattern(), is(indexPattern2)); | ||
} | ||
|
||
public void testGetView() throws Exception { | ||
final String viewName = randomAlphaOfLength(8); | ||
createView(viewName, randomAlphaOfLength(8)); | ||
|
||
final View view = getView(viewName).getView(); | ||
MatcherAssert.assertThat(view.getName(), is(viewName)); | ||
|
||
logger.info("Testing getView with non-existent view"); | ||
final String nonExistentView = "non-existent-" + randomAlphaOfLength(8); | ||
final Exception whenNeverExistedEx = assertThrows(ViewNotFoundException.class, () -> getView(nonExistentView)); | ||
MatcherAssert.assertThat(whenNeverExistedEx.getMessage(), is("View [" + nonExistentView + "] does not exist")); | ||
} | ||
|
||
public void testDeleteView() throws Exception { | ||
final String viewName = randomAlphaOfLength(8); | ||
createView(viewName, randomAlphaOfLength(8)); | ||
|
||
logger.info("Testing deleteView with existing view"); | ||
deleteView(viewName); | ||
final Exception whenDeletedEx = assertThrows(ViewNotFoundException.class, () -> getView(viewName)); | ||
MatcherAssert.assertThat(whenDeletedEx.getMessage(), is("View [" + viewName + "] does not exist")); | ||
|
||
logger.info("Testing deleteView with non-existent view"); | ||
final String nonExistentView = "non-existent-" + randomAlphaOfLength(8); | ||
final Exception whenNeverExistedEx = assertThrows(ViewNotFoundException.class, () -> deleteView(nonExistentView)); | ||
MatcherAssert.assertThat(whenNeverExistedEx.getMessage(), is("View [" + nonExistentView + "] does not exist")); | ||
} | ||
|
||
public void testUpdateView() throws Exception { | ||
final String viewName = randomAlphaOfLength(8); | ||
final String originalIndexPattern = randomAlphaOfLength(8); | ||
final View originalView = createView(viewName, originalIndexPattern).getView(); | ||
|
||
logger.info("Testing updateView with existing view"); | ||
final String newDescription = randomAlphaOfLength(20); | ||
final String newIndexPattern = "newPattern-" + originalIndexPattern; | ||
final View updatedView = updateView(viewName, newDescription, newIndexPattern).getView(); | ||
|
||
MatcherAssert.assertThat(updatedView, not(is(originalView))); | ||
MatcherAssert.assertThat(updatedView.getDescription(), is(newDescription)); | ||
MatcherAssert.assertThat(updatedView.getTargets(), hasSize(1)); | ||
MatcherAssert.assertThat(updatedView.getTargets().first().getIndexPattern(), is(newIndexPattern)); | ||
|
||
logger.info("Testing updateView with non-existent view"); | ||
final String nonExistentView = "non-existent-" + randomAlphaOfLength(8); | ||
final Exception whenNeverExistedEx = assertThrows(ViewNotFoundException.class, () -> updateView(nonExistentView, null, "index-*")); | ||
MatcherAssert.assertThat(whenNeverExistedEx.getMessage(), is("View [" + nonExistentView + "] does not exist")); | ||
} | ||
|
||
public void testListViewNames() throws Exception { | ||
logger.info("Testing listViewNames when no views have been created"); | ||
MatcherAssert.assertThat(listViewNames(), is(List.of())); | ||
|
||
final String view1 = "view1"; | ||
final String view2 = "view2"; | ||
createView(view1, "index-1-*"); | ||
createView(view2, "index-2-*"); | ||
|
||
logger.info("Testing listViewNames"); | ||
final List<String> views = listViewNames(); | ||
MatcherAssert.assertThat(views, containsInAnyOrder(view1, view2)); | ||
|
||
logger.info("Testing listViewNames after deleting a view"); | ||
deleteView(view1); | ||
final List<String> viewsAfterDeletion = listViewNames(); | ||
MatcherAssert.assertThat(viewsAfterDeletion, not(contains(view1))); | ||
MatcherAssert.assertThat(viewsAfterDeletion, contains(view2)); | ||
} | ||
|
||
public void testSearchOperations() throws Exception { | ||
final String indexInView1 = "index-1"; | ||
final String indexInView2 = "index-2"; | ||
final String indexNotInView = "another-index-1"; | ||
|
||
final int indexInView1DocCount = createIndexWithDocs(indexInView1); | ||
final int indexInView2DocCount = createIndexWithDocs(indexInView2); | ||
createIndexWithDocs(indexNotInView); | ||
|
||
logger.info("Testing view with no matches"); | ||
createView("no-matches", "this-pattern-will-match-nothing"); | ||
final Exception ex = assertThrows(IndexNotFoundException.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"); | ||
createView("only-index-1", "index-1"); | ||
assertHitCount(searchView("only-index-1"), indexInView1DocCount); | ||
|
||
logger.info("Testing view with wildcard matches"); | ||
createView("both-indices", "index-*"); | ||
assertHitCount(searchView("both-indices"), indexInView1DocCount + indexInView2DocCount); | ||
|
||
logger.info("Testing searchView with non-existent view"); | ||
final String nonExistentView = "non-existent-" + randomAlphaOfLength(8); | ||
final Exception whenNeverExistedEx = assertThrows(ViewNotFoundException.class, () -> searchView(nonExistentView)); | ||
MatcherAssert.assertThat(whenNeverExistedEx.getMessage(), is("View [" + nonExistentView + "] does not exist")); | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
...r/src/internalClusterTest/java/org/opensearch/action/admin/indices/view/ViewTestBase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* 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 java.util.stream.Collectors; | ||
|
||
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 { | ||
return createView(name, List.of(indexPattern)); | ||
} | ||
|
||
protected GetViewAction.Response createView(final String name, final List<String> targets) throws Exception { | ||
final CreateViewAction.Request request = new CreateViewAction.Request( | ||
name, | ||
null, | ||
targets.stream().map(CreateViewAction.Request.Target::new).collect(Collectors.toList()) | ||
); | ||
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<String> listViewNames() { | ||
return client().listViewNames(new ListViewNamesAction.Request()).actionGet().getViewNames(); | ||
} | ||
|
||
protected SearchResponse searchView(final String viewName) throws Exception { | ||
final SearchViewAction.Request request = new SearchViewAction.Request(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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.