-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Projected Views #11957
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Projected Views #11957
Changes from all commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
6bf2cf6
Basic view stubs
peternied 3522cc7
Cluster metadat
peternied 4e12632
Basic request handling
peternied 3a15863
Accepting requests
peternied 23632b6
Search rewriting and design dco
peternied 6031347
Functional views
peternied c66425a
Minor changes
peternied c191cc8
Resource Requset
peternied 4abefd0
Add FAQ sectino
peternied dace87a
Tidying up
peternied c88febe
Read prepare for merge into OpenSearch
peternied 61e8c98
Fix build issue
peternied ac25c96
Fix build issues
peternied 8e41fbe
Unit tests for view
peternied cf22a8d
Basic pattern for decoupled views in metadata vs transport requests
peternied 2f615cf
Merge branch 'views-core' into views
peternied d45fcb9
Integration tests and some unit tests
peternied 2832b24
Spotless and compile issue
peternied db00415
Clean up license headers
peternied 6a947e4
Fix logger usage miss
peternied 6156eb9
Before adding all action types
peternied a7dbd93
Expand action types
peternied f12efaa
wire up all actions
peternied 135acba
Functional integration test
peternied ac456da
refactor how view names are listed in tests
peternied 327d158
More tests
peternied b95056a
Following up on PR feedback
peternied ea78012
Add changelog entry
peternied 242ab85
Merge branch 'main' into views-core
peternied 7810ddf
Merge remote-tracking branch 'origin/main' into views-core
peternied 01655d0
Fix build warning about test annotations
peternied 292a322
Round out integration tests
peternied 07bcfe0
Add test cases
peternied e7f36b0
Fix compile issue
peternied 65fa8e7
Rename test class
peternied 4327237
PR feedback pass
peternied 5beefbb
Spotless
peternied 16b2b52
Merge remote-tracking branch 'origin/main' into views-core
peternied edd8902
More logging information
peternied ba385e4
Fix spotless
peternied 0663818
More detailed logging from checkStaticState
peternied 7f28330
Detact metadataFilesEligibleToDelete from its source collection
peternied 8cb9f55
Fix spotless issue
peternied 9d0e1b0
Breakout exceptions into their own clases
peternied 25e3ca9
Merge remote-tracking branch 'peternied/views-core' into views-core
peternied e58acdb
Clean up logger output message
peternied 6e9dffb
Revert changes to NamedRoute
peternied cba189e
Revert changes to SearchRequest and follow pipeline model
peternied eae9511
Remove unused codepath
peternied fcacb01
Update exception serialization tests
peternied db8f049
PR feedback
peternied 4936736
Fix error in RemoteSegmentStoreDirectory when debug logging is enabled
peternied 8c39071
Add changelog entry
peternied 7259789
Use sorted set to store targets for views
peternied fa913f7
Test compile checks
peternied a9777be
Fix compile issues related to switch to set
peternied 8796381
Add test to validate debug log statement doesn't have errors
peternied 0dd44f7
Add test to validate debug log statement doesn't have errors
peternied d77f812
Dial back the level of detail validated for the segments that are del…
peternied 946a691
Merge branch 'RemoteSegmentStoreDirectory' into views-core
peternied fc600ac
Dial back the level of detail validated for the segments that are del…
peternied bbf4945
Merge branch 'RemoteSegmentStoreDirectory' into views-core
peternied 2ac6e68
Merge remote-tracking branch 'origin/main' into views-core
peternied File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.