summaryrefslogtreecommitdiffstats
path: root/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi
diff options
context:
space:
mode:
Diffstat (limited to 'vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi')
-rw-r--r--vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/OperationHandlerImplTest.java100
-rw-r--r--vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/MockedOperationHandler.java4
-rw-r--r--vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java72
3 files changed, 164 insertions, 12 deletions
diff --git a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/OperationHandlerImplTest.java b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/OperationHandlerImplTest.java
index 5021899e30b..4c04070cec4 100644
--- a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/OperationHandlerImplTest.java
+++ b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/OperationHandlerImplTest.java
@@ -145,6 +145,10 @@ public class OperationHandlerImplTest {
return new RestUri(new URI("http://localhost/document/v1/namespace/document-type/docid/"));
}
+ private static RestUri apiRootVisitUri() throws Exception {
+ return new RestUri(new URI("http://localhost/document/v1/"));
+ }
+
private static RestUri dummyGetUri() throws Exception {
return new RestUri(new URI("http://localhost/document/v1/namespace/document-type/docid/foo"));
}
@@ -166,6 +170,7 @@ public class OperationHandlerImplTest {
try {
OperationHandlerImpl handler = fixture.createHandler();
handler.visit(dummyVisitUri(), "", emptyVisitOptions());
+ fail("Exception expected");
} catch (RestApiException e) {
assertThat(e.getResponse().getStatus(), is(500));
assertThat(renderRestApiExceptionAsString(e), containsString("Timed out"));
@@ -192,14 +197,19 @@ public class OperationHandlerImplTest {
assertThat(fixture.assignedParameters.get().getSessionTimeoutMs(), is((long)OperationHandlerImpl.VISIT_TIMEOUT_MS));
}
- private static VisitorParameters generatedParametersFromVisitOptions(OperationHandler.VisitOptions options) throws Exception {
+ private static VisitorParameters generatedVisitParametersFrom(RestUri restUri, String documentSelection,
+ OperationHandler.VisitOptions options) throws Exception {
OperationHandlerImplFixture fixture = new OperationHandlerImplFixture();
OperationHandlerImpl handler = fixture.createHandler();
- handler.visit(dummyVisitUri(), "", options);
+ handler.visit(restUri, documentSelection, options);
return fixture.assignedParameters.get();
}
+ private static VisitorParameters generatedParametersFromVisitOptions(OperationHandler.VisitOptions options) throws Exception {
+ return generatedVisitParametersFrom(dummyVisitUri(), "", options);
+ }
+
@Test
public void document_type_is_mapped_to_correct_bucket_space() throws Exception {
OperationHandlerImplFixture fixture = new OperationHandlerImplFixture();
@@ -218,6 +228,7 @@ public class OperationHandlerImplTest {
try {
OperationHandlerImpl handler = fixture.createHandler();
handler.visit(dummyVisitUri(), "", emptyVisitOptions());
+ fail("Exception expected");
} catch (RestApiException e) {
assertThat(e.getResponse().getStatus(), is(400));
String errorMsg = renderRestApiExceptionAsString(e);
@@ -304,4 +315,89 @@ public class OperationHandlerImplTest {
verify(fixture.mockSyncSession).get(any(), eq("donald,duck"), any());
}
+ @Test
+ public void api_root_visit_uri_requires_cluster_set() throws Exception {
+ OperationHandlerImplFixture fixture = new OperationHandlerImplFixture();
+ OperationHandlerImpl handler = fixture.createHandler();
+ try {
+ handler.visit(apiRootVisitUri(), "", emptyVisitOptions());
+ fail("Exception expected");
+ } catch (RestApiException e) {
+ assertThat(e.getResponse().getStatus(), is(400));
+ assertThat(renderRestApiExceptionAsString(e), containsString(
+ "MISSING_CLUSTER Must set 'cluster' parameter to a valid content cluster id " +
+ "when visiting at a root /document/v1/ level"));
+ }
+ }
+
+ @Test
+ public void api_root_visiting_propagates_request_route() throws Exception {
+ VisitorParameters parameters = generatedVisitParametersFrom(apiRootVisitUri(), "", optionsBuilder().cluster("foo").build());
+ assertEquals("[Storage:cluster=foo;clusterconfigid=configId]", parameters.getRoute().toString());
+ }
+
+ @Test
+ public void api_root_visiting_targets_default_bucket_space_by_default() throws Exception {
+ VisitorParameters parameters = generatedVisitParametersFrom(apiRootVisitUri(), "", optionsBuilder().cluster("foo").build());
+ assertEquals("default", parameters.getBucketSpace());
+ }
+
+ @Test
+ public void api_root_visiting_can_explicitly_specify_bucket_space() throws Exception {
+ VisitorParameters parameters = generatedVisitParametersFrom(apiRootVisitUri(), "",
+ optionsBuilder().cluster("foo").bucketSpace("global").build());
+ assertEquals("global", parameters.getBucketSpace());
+ }
+
+ @Test
+ public void api_root_visiting_throws_exception_on_unknown_bucket_space_name() throws Exception {
+ try {
+ VisitorParameters parameters = generatedVisitParametersFrom(apiRootVisitUri(), "",
+ optionsBuilder().cluster("foo").bucketSpace("langbein").build());
+ } catch (RestApiException e) {
+ assertThat(e.getResponse().getStatus(), is(400));
+ assertThat(renderRestApiExceptionAsString(e), containsString(
+ "UNKNOWN_BUCKET_SPACE Bucket space 'langbein' is not a known bucket space " +
+ "(expected 'default' or 'global')"));
+ }
+ }
+
+ @Test
+ public void api_root_visiting_has_empty_document_selection_by_default() throws Exception {
+ VisitorParameters parameters = generatedVisitParametersFrom(apiRootVisitUri(), "", optionsBuilder().cluster("foo").build());
+ assertEquals("", parameters.getDocumentSelection());
+ }
+
+ @Test
+ public void api_root_visiting_propagates_provided_document_selection() throws Exception {
+ VisitorParameters parameters = generatedVisitParametersFrom(apiRootVisitUri(), "baz.blarg", optionsBuilder().cluster("foo").build());
+ // Note: syntax correctness of selection is checked and enforced by RestApi
+ assertEquals("baz.blarg", parameters.getDocumentSelection());
+ }
+
+ @Test
+ public void api_root_visiting_uses_all_fieldset_by_default() throws Exception {
+ VisitorParameters parameters = generatedVisitParametersFrom(apiRootVisitUri(), "", optionsBuilder().cluster("foo").build());
+ assertEquals("[all]", parameters.getFieldSet());
+ }
+
+ @Test
+ public void api_root_visiting_propagates_provided_fieldset() throws Exception {
+ VisitorParameters parameters = generatedVisitParametersFrom(apiRootVisitUri(), "",
+ optionsBuilder().cluster("foo").fieldSet("zoidberg:[document]").build());
+ assertEquals("zoidberg:[document]", parameters.getFieldSet());
+ }
+
+ @Test
+ public void namespace_and_doctype_augmented_selection_has_parenthesized_selection_sub_expression() throws Exception {
+ VisitorParameters parameters = generatedVisitParametersFrom(dummyVisitUri(), "1 != 2", optionsBuilder().cluster("foo").build());
+ assertEquals("((1 != 2) and document-type and (id.namespace=='namespace'))", parameters.getDocumentSelection());
+ }
+
+ @Test
+ public void namespace_and_doctype_visit_without_selection_does_not_contain_selection_sub_expression() throws Exception {
+ VisitorParameters parameters = generatedVisitParametersFrom(dummyVisitUri(), "", optionsBuilder().cluster("foo").build());
+ assertEquals("document-type and (id.namespace=='namespace')", parameters.getDocumentSelection());
+ }
+
}
diff --git a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/MockedOperationHandler.java b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/MockedOperationHandler.java
index 297576f1bef..5f44b06ab77 100644
--- a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/MockedOperationHandler.java
+++ b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/MockedOperationHandler.java
@@ -24,7 +24,9 @@ public class MockedOperationHandler implements OperationHandler {
+ documentSelection + "'"
+ options.wantedDocumentCount.map(n -> String.format(", min docs returned: %d", n)).orElse("")
+ options.fieldSet.map(s -> String.format(", field set: '%s'", s)).orElse("")
- + options.concurrency.map(n -> String.format(", concurrency: %d", n)).orElse(""));
+ + options.concurrency.map(n -> String.format(", concurrency: %d", n)).orElse("")
+ + options.bucketSpace.map(s -> String.format(", bucket space: '%s'", s)).orElse("")
+ + options.cluster.map(s -> String.format(", cluster: '%s'", s)).orElse(""));
}
@Override
diff --git a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
index 6b7f708e090..5e3aa05130d 100644
--- a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
+++ b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
@@ -28,6 +28,8 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
+import java.util.function.Function;
+import java.util.function.Supplier;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
@@ -288,19 +290,47 @@ public class RestApiTest {
}
}
- private String performV1RestCall(String pathSuffix) {
+ private static String defaultPathPrefix() {
+ return "namespace/document-type/";
+ }
+
+ private String performV1RestCall(String pathPrefix, String pathSuffix, Function<Request, HttpRequestBase> methodOp) {
try {
- Request request = new Request(String.format("http://localhost:%s/document/v1/namespace/document-type/%s",
- getFirstListenPort(), pathSuffix));
- HttpGet get = new HttpGet(request.getUri());
- return doRest(get);
+ Request request = new Request(String.format("http://localhost:%s/document/v1/%s%s",
+ getFirstListenPort(), pathPrefix, pathSuffix));
+ HttpRequestBase restOp = methodOp.apply(request);
+ return doRest(restOp);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
+ private String performV1GetRestCall(String pathSuffix) {
+ return performV1RestCall(defaultPathPrefix(), pathSuffix, (request) -> new HttpGet(request.getUri()));
+ }
+
+ private void doTestRootPathNotAccepted(Function<Request, HttpRequestBase> methodOpFactory) {
+ String output = performV1RestCall("", "", methodOpFactory);
+ assertThat(output, containsString("Root /document/v1/ requests only supported for HTTP GET"));
+ }
+
+ @Test
+ public void root_api_path_not_accepted_for_http_put() {
+ doTestRootPathNotAccepted((request) -> new HttpPut(request.getUri()));
+ }
+
+ @Test
+ public void root_api_path_not_accepted_for_http_post() {
+ doTestRootPathNotAccepted((request) -> new HttpPost(request.getUri()));
+ }
+
+ @Test
+ public void root_api_path_not_accepted_for_http_delete() {
+ doTestRootPathNotAccepted((request) -> new HttpDelete(request.getUri()));
+ }
+
private void assertResultingDocumentSelection(String suffix, String expected) {
- String output = performV1RestCall(suffix);
+ String output = performV1GetRestCall(suffix);
assertThat(output, containsString(String.format("doc selection: '%s'", expected)));
}
@@ -321,7 +351,7 @@ public class RestApiTest {
}
private void assertNumericIdFailsParsing(String id) {
- String output = performV1RestCall(String.format("number/%s", encoded(id)));
+ String output = performV1GetRestCall(String.format("number/%s", encoded(id)));
assertThat(output, containsString("Failed to parse numeric part of selection URI"));
}
@@ -335,7 +365,7 @@ public class RestApiTest {
@Test
public void non_text_group_string_character_returns_error() {
- String output = performV1RestCall(String.format("group/%s", encoded("\u001f")));
+ String output = performV1GetRestCall(String.format("group/%s", encoded("\u001f")));
assertThat(output, containsString("Failed to parse group part of selection URI; contains invalid text code point U001F"));
}
@@ -362,7 +392,7 @@ public class RestApiTest {
}
private void assertDocumentSelectionFailsParsing(String expression) {
- String output = performV1RestCall(String.format("number/1234?selection=%s", encoded(expression)));
+ String output = performV1GetRestCall(String.format("number/1234?selection=%s", encoded(expression)));
assertThat(output, containsString("Failed to parse expression given in 'selection' parameter. Must be a complete and valid sub-expression."));
}
@@ -416,6 +446,30 @@ public class RestApiTest {
}
@Test
+ public void root_api_visit_cluster_parameter_is_propagated() throws IOException {
+ Request request = new Request(String.format("http://localhost:%s/document/v1/?cluster=vaffel", getFirstListenPort()));
+ HttpGet get = new HttpGet(request.getUri());
+ String rest = doRest(get);
+ assertThat(rest, containsString("cluster: 'vaffel'"));
+ }
+
+ @Test
+ public void root_api_visit_selection_parameter_is_propagated() throws IOException {
+ Request request = new Request(String.format("http://localhost:%s/document/v1/?cluster=foo&selection=yoshi", getFirstListenPort()));
+ HttpGet get = new HttpGet(request.getUri());
+ String rest = doRest(get);
+ assertThat(rest, containsString("doc selection: 'yoshi'"));
+ }
+
+ @Test
+ public void root_api_visit_bucket_space_parameter_is_propagated() throws IOException {
+ Request request = new Request(String.format("http://localhost:%s/document/v1/?cluster=foo&bucketSpace=global", getFirstListenPort()));
+ HttpGet get = new HttpGet(request.getUri());
+ String rest = doRest(get);
+ assertThat(rest, containsString("bucket space: 'global'"));
+ }
+
+ @Test
public void invalid_visit_concurrency_parameter_returns_error_response() throws IOException {
Request request = new Request(String.format("http://localhost:%s/document/v1/namespace/document-type/docid/?concurrency=badgers", getFirstListenPort()));
HttpGet get = new HttpGet(request.getUri());