blob: 6d728b6045944831fdc31fed192595562d072df3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.client.solrj.impl;
import org.apache.solr.SolrJettyTestBase;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.JettyConfig;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.request.RequestWriter;
import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.util.Base64;
import org.apache.solr.common.util.SuppressForbidden;
import org.eclipse.jetty.client.WWWAuthenticationProtocolHandler;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Http2SolrClientTest extends SolrJettyTestBase {
private static final String EXPECTED_USER_AGENT = "Solr[" + Http2SolrClient.class.getName() + "] 2.0";
public static class DebugServlet extends HttpServlet {
public static void clear() {
lastMethod = null;
headers = null;
parameters = null;
errorCode = null;
queryString = null;
cookies = null;
responseHeaders = null;
}
public static Integer errorCode = null;
public static String lastMethod = null;
public static HashMap<String,String> headers = null;
public static Map<String,String[]> parameters = null;
public static String queryString = null;
public static javax.servlet.http.Cookie[] cookies = null;
public static List<String[]> responseHeaders = null;
public static void setErrorCode(Integer code) {
errorCode = code;
}
public static void addResponseHeader(String headerName, String headerValue) {
if (responseHeaders == null) {
responseHeaders = new ArrayList<>();
}
responseHeaders.add(new String[]{headerName, headerValue});
}
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
lastMethod = "delete";
recordRequest(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
lastMethod = "get";
recordRequest(req, resp);
}
@Override
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
lastMethod = "head";
recordRequest(req, resp);
}
private void setHeaders(HttpServletRequest req) {
Enumeration<String> headerNames = req.getHeaderNames();
headers = new HashMap<>();
while (headerNames.hasMoreElements()) {
final String name = headerNames.nextElement();
headers.put(name.toLowerCase(Locale.getDefault()), req.getHeader(name));
}
}
@SuppressForbidden(reason = "fake servlet only")
private void setParameters(HttpServletRequest req) {
parameters = req.getParameterMap();
}
private void setQueryString(HttpServletRequest req) {
queryString = req.getQueryString();
}
private void setCookies(HttpServletRequest req) {
javax.servlet.http.Cookie[] ck = req.getCookies();
cookies = req.getCookies();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
lastMethod = "post";
recordRequest(req, resp);
}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
lastMethod = "put";
recordRequest(req, resp);
}
private void recordRequest(HttpServletRequest req, HttpServletResponse resp) {
setHeaders(req);
setParameters(req);
setQueryString(req);
setCookies(req);
if (responseHeaders != null) {
for (String[] h : responseHeaders) {
resp.addHeader(h[0], h[1]);
}
}
if (null != errorCode) {
try {
resp.sendError(errorCode);
} catch (IOException e) {
throw new RuntimeException("sendError IO fail in DebugServlet", e);
}
}
}
}
@BeforeClass
public static void beforeTest() throws Exception {
JettyConfig jettyConfig = JettyConfig.builder()
.withServlet(new ServletHolder(BasicHttpSolrClientTest.RedirectServlet.class), "/redirect/*")
.withServlet(new ServletHolder(BasicHttpSolrClientTest.SlowServlet.class), "/slow/*")
.withServlet(new ServletHolder(DebugServlet.class), "/debug/*")
.withSSLConfig(sslConfig.buildServerSSLConfig())
.build();
createAndStartJetty(legacyExampleCollection1SolrHome(), jettyConfig);
}
@Override
public void tearDown() throws Exception {
System.clearProperty("basicauth");
System.clearProperty(HttpClientUtil.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY);
DebugServlet.clear();
super.tearDown();
}
private Http2SolrClient getHttp2SolrClient(String url, int connectionTimeOut, int socketTimeout) {
return new Http2SolrClient.Builder(url)
.connectionTimeout(connectionTimeOut)
.idleTimeout(socketTimeout)
.build();
}
private Http2SolrClient getHttp2SolrClient(String url) {
return new Http2SolrClient.Builder(url)
.build();
}
@Test
public void testTimeout() throws Exception {
SolrQuery q = new SolrQuery("*:*");
try(Http2SolrClient client = getHttp2SolrClient(jetty.getBaseUrl().toString() + "/slow/foo", DEFAULT_CONNECTION_TIMEOUT, 2000)) {
client.query(q, SolrRequest.METHOD.GET);
fail("No exception thrown.");
} catch (SolrServerException e) {
assertTrue(e.getMessage().contains("timeout") || e.getMessage().contains("Timeout"));
}
}
@Test
public void test0IdleTimeout() throws Exception {
SolrQuery q = new SolrQuery("*:*");
try(Http2SolrClient client = getHttp2SolrClient(jetty.getBaseUrl().toString() + "/debug/foo", DEFAULT_CONNECTION_TIMEOUT, 0)) {
try {
client.query(q, SolrRequest.METHOD.GET);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
}
}
/**
* test that SolrExceptions thrown by HttpSolrClient can
* correctly encapsulate http status codes even when not on the list of
* ErrorCodes solr may return.
*/
@Test
public void testSolrExceptionCodeNotFromSolr() throws IOException, SolrServerException {
final int status = 527;
assertEquals(status + " didn't generate an UNKNOWN error code, someone modified the list of valid ErrorCode's w/o changing this test to work a different way",
SolrException.ErrorCode.UNKNOWN, SolrException.ErrorCode.getErrorCode(status));
try (Http2SolrClient client = getHttp2SolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
DebugServlet.setErrorCode(status);
try {
SolrQuery q = new SolrQuery("foo");
client.query(q, SolrRequest.METHOD.GET);
fail("Didn't get excepted exception from oversided request");
} catch (SolrException e) {
assertEquals("Unexpected exception status code", status, e.code());
}
} finally {
DebugServlet.clear();
}
}
@Test
public void testQuery() throws Exception {
DebugServlet.clear();
try (Http2SolrClient client = getHttp2SolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
SolrQuery q = new SolrQuery("foo");
q.setParam("a", "\u1234");
try {
client.query(q, SolrRequest.METHOD.GET);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
//default method
assertEquals("get", DebugServlet.lastMethod);
//agent
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
//default wt
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
//default version
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
//agent
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
//content-type
assertEquals(null, DebugServlet.headers.get("content-type"));
//param encoding
assertEquals(1, DebugServlet.parameters.get("a").length);
assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
//POST
DebugServlet.clear();
try {
client.query(q, SolrRequest.METHOD.POST);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
assertEquals("post", DebugServlet.lastMethod);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
assertEquals(1, DebugServlet.parameters.get("a").length);
assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals("application/x-www-form-urlencoded", DebugServlet.headers.get("content-type"));
//PUT
DebugServlet.clear();
try {
client.query(q, SolrRequest.METHOD.PUT);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
assertEquals("put", DebugServlet.lastMethod);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
assertEquals(1, DebugServlet.parameters.get("a").length);
assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals("application/x-www-form-urlencoded", DebugServlet.headers.get("content-type"));
//XML/GET
client.setParser(new XMLResponseParser());
DebugServlet.clear();
try {
client.query(q, SolrRequest.METHOD.GET);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
assertEquals("get", DebugServlet.lastMethod);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
assertEquals(1, DebugServlet.parameters.get("a").length);
assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
//XML/POST
client.setParser(new XMLResponseParser());
DebugServlet.clear();
try {
client.query(q, SolrRequest.METHOD.POST);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
assertEquals("post", DebugServlet.lastMethod);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
assertEquals(1, DebugServlet.parameters.get("a").length);
assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals("application/x-www-form-urlencoded", DebugServlet.headers.get("content-type"));
client.setParser(new XMLResponseParser());
DebugServlet.clear();
try {
client.query(q, SolrRequest.METHOD.PUT);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
assertEquals("put", DebugServlet.lastMethod);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
assertEquals(1, DebugServlet.parameters.get("a").length);
assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals("application/x-www-form-urlencoded", DebugServlet.headers.get("content-type"));
}
}
@Test
public void testDelete() throws Exception {
DebugServlet.clear();
try (Http2SolrClient client = getHttp2SolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
try {
client.deleteById("id");
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
//default method
assertEquals("post", DebugServlet.lastMethod);
//agent
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
//default wt
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
//default version
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
//agent
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
//XML
client.setParser(new XMLResponseParser());
try {
client.deleteByQuery("*:*");
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
assertEquals("post", DebugServlet.lastMethod);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
}
}
@Test
public void testGetById() throws Exception {
DebugServlet.clear();
try (Http2SolrClient client = getHttp2SolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
Collection<String> ids = Collections.singletonList("a");
try {
client.getById("a");
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
try {
client.getById(ids, null);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
try {
client.getById("foo", "a");
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
try {
client.getById("foo", ids, null);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
}
}
@Test
public void testUpdate() throws Exception {
DebugServlet.clear();
try (Http2SolrClient client = getHttp2SolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
UpdateRequest req = new UpdateRequest();
req.add(new SolrInputDocument());
req.setParam("a", "\u1234");
try {
client.request(req);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
//default method
assertEquals("post", DebugServlet.lastMethod);
//agent
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
//default wt
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
//default version
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
//content type
assertEquals("application/javabin", DebugServlet.headers.get("content-type"));
//parameter encoding
assertEquals(1, DebugServlet.parameters.get("a").length);
assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
//XML response and writer
client.setParser(new XMLResponseParser());
client.setRequestWriter(new RequestWriter());
try {
client.request(req);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
assertEquals("post", DebugServlet.lastMethod);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
assertEquals("application/xml; charset=UTF-8", DebugServlet.headers.get("content-type"));
assertEquals(1, DebugServlet.parameters.get("a").length);
assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
//javabin request
client.setParser(new BinaryResponseParser());
client.setRequestWriter(new BinaryRequestWriter());
DebugServlet.clear();
try {
client.request(req);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
assertEquals("post", DebugServlet.lastMethod);
assertEquals(EXPECTED_USER_AGENT, DebugServlet.headers.get("user-agent"));
assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
assertEquals("application/javabin", DebugServlet.headers.get("content-type"));
assertEquals(1, DebugServlet.parameters.get("a").length);
assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
}
}
@Test
public void testRedirect() throws Exception {
final String clientUrl = jetty.getBaseUrl().toString() + "/redirect/foo";
try (Http2SolrClient client = getHttp2SolrClient(clientUrl)) {
SolrQuery q = new SolrQuery("*:*");
// default = false
try {
client.query(q);
fail("Should have thrown an exception.");
} catch (SolrServerException e) {
assertTrue(e.getMessage().contains("redirect"));
}
client.setFollowRedirects(true);
client.query(q);
//And back again:
client.setFollowRedirects(false);
try {
client.query(q);
fail("Should have thrown an exception.");
} catch (SolrServerException e) {
assertTrue(e.getMessage().contains("redirect"));
}
}
}
@Test
public void testCollectionParameters() throws IOException, SolrServerException {
try (Http2SolrClient client = getHttp2SolrClient(jetty.getBaseUrl().toString())) {
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", "collection");
client.add("collection1", doc);
client.commit("collection1");
assertEquals(1, client.query("collection1", new SolrQuery("id:collection")).getResults().getNumFound());
}
final String collection1Url = jetty.getBaseUrl().toString() + "/collection1";
try (Http2SolrClient client = getHttp2SolrClient(collection1Url)) {
assertEquals(1, client.query(new SolrQuery("id:collection")).getResults().getNumFound());
}
}
private Set<String> setOf(String... keys) {
Set<String> set = new TreeSet<>();
if (keys != null) {
Collections.addAll(set, keys);
}
return set;
}
private void setReqParamsOf(UpdateRequest req, String... keys) {
if (keys != null) {
for (String k : keys) {
req.setParam(k, k+"Value");
}
}
}
private void verifyServletState(Http2SolrClient client,
@SuppressWarnings({"rawtypes"})SolrRequest request) {
// check query String
Iterator<String> paramNames = request.getParams().getParameterNamesIterator();
while (paramNames.hasNext()) {
String name = paramNames.next();
String [] values = request.getParams().getParams(name);
if (values != null) {
for (String value : values) {
boolean shouldBeInQueryString = client.getQueryParams().contains(name)
|| (request.getQueryParams() != null && request.getQueryParams().contains(name));
assertEquals(shouldBeInQueryString, DebugServlet.queryString.contains(name + "=" + value));
// in either case, it should be in the parameters
assertNotNull(DebugServlet.parameters.get(name));
assertEquals(1, DebugServlet.parameters.get(name).length);
assertEquals(value, DebugServlet.parameters.get(name)[0]);
}
}
}
}
@Test
public void testQueryString() throws Exception {
final String clientUrl = jetty.getBaseUrl().toString() + "/debug/foo";
try(Http2SolrClient client = getHttp2SolrClient(clientUrl)) {
// test without request query params
DebugServlet.clear();
client.setQueryParams(setOf("serverOnly"));
UpdateRequest req = new UpdateRequest();
setReqParamsOf(req, "serverOnly", "notServer");
try {
client.request(req);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
verifyServletState(client, req);
// test without server query params
DebugServlet.clear();
client.setQueryParams(setOf());
req = new UpdateRequest();
req.setQueryParams(setOf("requestOnly"));
setReqParamsOf(req, "requestOnly", "notRequest");
try {
client.request(req);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
verifyServletState(client, req);
// test with both request and server query params
DebugServlet.clear();
req = new UpdateRequest();
client.setQueryParams(setOf("serverOnly", "both"));
req.setQueryParams(setOf("requestOnly", "both"));
setReqParamsOf(req, "serverOnly", "requestOnly", "both", "neither");
try {
client.request(req);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
verifyServletState(client, req);
// test with both request and server query params with single stream
DebugServlet.clear();
req = new UpdateRequest();
req.add(new SolrInputDocument());
client.setQueryParams(setOf("serverOnly", "both"));
req.setQueryParams(setOf("requestOnly", "both"));
setReqParamsOf(req, "serverOnly", "requestOnly", "both", "neither");
try {
client.request(req);
} catch (BaseHttpSolrClient.RemoteSolrException ignored) {}
// NOTE: single stream requests send all the params
// as part of the query string. So add "neither" to the request
// so it passes the verification step.
req.setQueryParams(setOf("requestOnly", "both", "neither"));
verifyServletState(client, req);
}
}
@Test
public void testGetDefaultSslContextFactory() {
assertNull(Http2SolrClient.getDefaultSslContextFactory().getEndpointIdentificationAlgorithm());
System.setProperty("solr.jetty.ssl.verifyClientHostName", "HTTPS");
System.setProperty("javax.net.ssl.keyStoreType", "foo");
System.setProperty("javax.net.ssl.trustStoreType", "bar");
SslContextFactory.Client sslContextFactory = Http2SolrClient.getDefaultSslContextFactory();
assertEquals("HTTPS", sslContextFactory.getEndpointIdentificationAlgorithm());
assertEquals("foo", sslContextFactory.getKeyStoreType());
assertEquals("bar", sslContextFactory.getTrustStoreType());
System.clearProperty("solr.jetty.ssl.verifyClientHostName");
System.clearProperty("javax.net.ssl.keyStoreType");
System.clearProperty("javax.net.ssl.trustStoreType");
}
protected void expectThrowsAndMessage(Class<? extends Exception> expectedType, ThrowingRunnable executable, String expectedMessage) {
Exception e = expectThrows(expectedType, executable);
assertTrue("Expecting message to contain \"" + expectedMessage + "\" but was: " + e.getMessage(), e.getMessage().contains(expectedMessage));
}
@Test
public void testBadExplicitCredentials() {
expectThrowsAndMessage(IllegalStateException.class, () -> new Http2SolrClient.Builder()
.withBasicAuthCredentials("foo", null), "Invalid Authentication credentials");
expectThrowsAndMessage(IllegalStateException.class, () -> new Http2SolrClient.Builder()
.withBasicAuthCredentials(null, "foo"), "Invalid Authentication credentials");
}
@Test
public void testSetCredentialsExplicitly() {
try (Http2SolrClient client = new Http2SolrClient.Builder(jetty.getBaseUrl().toString() + "/debug/foo")
.withBasicAuthCredentials("foo", "explicit")
.build();) {
QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
try {
ignoreException("Error from server");
client.request(r);
} catch (Exception e) {
// expected
}
unIgnoreException("Error from server");
assertTrue(DebugServlet.headers.size() > 0);
String authorizationHeader = DebugServlet.headers.get("authorization");
assertNotNull("No authorization information in headers found. Headers: " + DebugServlet.headers, authorizationHeader);
assertEquals("Basic " + Base64.byteArrayToBase64("foo:explicit".getBytes(StandardCharsets.UTF_8)), authorizationHeader);
}
}
@Test
public void testSetCredentialsWithSysProps() throws IOException, SolrServerException {
System.setProperty(PreemptiveBasicAuthClientBuilderFactory.SYS_PROP_BASIC_AUTH_CREDENTIALS, "foo:bar");
System.setProperty(HttpClientUtil.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY, PreemptiveBasicAuthClientBuilderFactory.class.getName());
// Hack to ensure we get a new set of parameters for this test
PreemptiveBasicAuthClientBuilderFactory.setDefaultSolrParams(new PreemptiveBasicAuthClientBuilderFactory.CredentialsResolver().defaultParams);
try (Http2SolrClient client = new Http2SolrClient.Builder(jetty.getBaseUrl().toString() + "/debug/foo").build();) {
QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
DebugServlet.addResponseHeader(WWWAuthenticationProtocolHandler.NAME, "Basic realm=\"Debug Servlet\"");
DebugServlet.setErrorCode(HttpStatus.UNAUTHORIZED_401);
try {
client.request(r);
} catch (Exception e) {
// expected
}
assertTrue(DebugServlet.headers.size() > 0);
String authorizationHeader = DebugServlet.headers.get("authorization");
assertNotNull("No authorization information in headers found. Headers: " + DebugServlet.headers, authorizationHeader);
assertEquals("Basic " + Base64.byteArrayToBase64("foo:bar".getBytes(StandardCharsets.UTF_8)), authorizationHeader);
} finally {
System.clearProperty(PreemptiveBasicAuthClientBuilderFactory.SYS_PROP_BASIC_AUTH_CREDENTIALS);
System.clearProperty(HttpClientUtil.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY);
PreemptiveBasicAuthClientBuilderFactory.setDefaultSolrParams(new MapSolrParams(new HashMap<>()));
}
}
@Test
public void testPerRequestCredentialsWin() {
try (Http2SolrClient client = new Http2SolrClient.Builder(jetty.getBaseUrl().toString() + "/debug/foo")
.withBasicAuthCredentials("foo2", "explicit").build();) {
QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
r.setBasicAuthCredentials("foo3", "per-request");
try {
ignoreException("Error from server");
client.request(r);
} catch (Exception e) {
// expected
}
unIgnoreException("Error from server");
assertTrue(DebugServlet.headers.size() > 0);
String authorizationHeader = DebugServlet.headers.get("authorization");
assertNotNull("No authorization information in headers found. Headers: " + DebugServlet.headers, authorizationHeader);
assertEquals("Basic " + Base64.byteArrayToBase64("foo3:per-request".getBytes(StandardCharsets.UTF_8)), authorizationHeader);
} finally {
System.clearProperty("basicauth");
}
}
@Test
public void testNoCredentials() {
try (Http2SolrClient client = new Http2SolrClient.Builder(jetty.getBaseUrl().toString() + "/debug/foo").build();) {
QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
try {
ignoreException("Error from server");
client.request(r);
} catch (Exception e) {
// expected
}
unIgnoreException("Error from server");
assertFalse("Expecting no authorization header but got: " + DebugServlet.headers, DebugServlet.headers.containsKey("authorization"));
}
}
@Test
public void testBadHttpFactory() {
System.setProperty(HttpClientUtil.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY, "FakeClassName");
try {
client = new Http2SolrClient.Builder(jetty.getBaseUrl().toString() + "/debug/foo").build();
fail("Expecting exception");
} catch (RuntimeException e ) {
assertTrue(e.getMessage().contains("Unable to instantiate"));
}
}
/**
* Missed tests :
* - set cookies via interceptor
* - invariant params
* - compression
* - get raw stream
*/
}