package io.searchbox.client.http;
import java.io.IOException;
import java.util.concurrent.Semaphore;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.JestResult;
import io.searchbox.client.JestResultHandler;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.indices.Stats;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
/** Test the situation where there's a misconfigured proxy between the Jest
* client and the server. If the proxy speaks text/html instead of
* application/json, we should not throw a generic JsonSyntaxException.
*/
public class FailingProxyTest {
JestClientFactory factory = new JestClientFactory();
private FailingProxy proxy;
private JestHttpClient client;
private Stats status;
@Before
public void setUp() throws IOException {
proxy = new FailingProxy();
String url = proxy.getUrl();
factory.setHttpClientConfig(new HttpClientConfig.Builder(url).build());
client = (JestHttpClient) factory.getObject();
assertThat(client, is(not(nullValue())));
status = new Stats.Builder().build();
}
@After
public void tearDown() throws IOException {
client.shutdownClient();
proxy.stop();
}
@Test
public void testWithFailingProxy() throws InterruptedException, IOException {
Exception exception = runSynchronously();
validateFailingProxyException(exception);
}
@Test
public void testAsyncWithFailingProxy() throws InterruptedException, IOException {
Exception exception = runAsynchronously();
validateFailingProxyException(exception);
}
private void validateFailingProxyException(final Exception e) {
assertThat(e, is(not(Matchers.nullValue())));
final String message = e.toString();
assertThat(message, not(containsString("Use JsonReader.setLenient(true)")));
assertThat(message, containsString("text/html"));
assertThat(message, containsString("should be json: HTTP/1.1 400 Bad Request"));
}
@Test
public void testWithBrokenResponse() throws InterruptedException, IOException {
proxy.setErrorStatus(HttpResponseStatus.FORBIDDEN);
proxy.setErrorContentType("application/json");
proxy.setErrorMessage("banana"); // <-- this is not json at all!
Exception exception = runSynchronously();
validateBrokenResponseException(exception);
}
@Test
public void testAsyncWithBrokenResponse() throws InterruptedException, IOException {
proxy.setErrorStatus(HttpResponseStatus.FORBIDDEN);
proxy.setErrorContentType("application/json");
proxy.setErrorMessage("banana"); // <-- this is not json at all!
Exception exception = runAsynchronously();
validateBrokenResponseException(exception);
}
private void validateBrokenResponseException(final Exception e) {
assertThat(e, is(not(Matchers.nullValue())));
final String message = e.toString();
assertThat(message, not(containsString("Use JsonReader.setLenient(true)")));
assertThat(message, containsString("should be json: HTTP/1.1 400 Bad Request"));
}
private Exception runSynchronously() {
Exception exception = null;
try {
final JestResult result = client.execute(status);
} catch (Exception e) {
exception = e;
}
return exception;
}
private Exception runAsynchronously() throws InterruptedException {
final ResultHandler resultHandler = new ResultHandler();
client.executeAsync(status, resultHandler);
return resultHandler.get();
}
private class ResultHandler implements JestResultHandler {
private final Semaphore sema = new Semaphore(0);
private Exception exception = null;
@Override
public void completed(final Object result) {
sema.release();
}
@Override
public void failed(final Exception ex) {
exception = ex;
sema.release();
}
public Exception get() throws InterruptedException {
sema.acquire();
return exception;
}
}
}