summaryrefslogtreecommitdiffstats
path: root/jaxrs_client_utils/src/test
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /jaxrs_client_utils/src/test
Publish
Diffstat (limited to 'jaxrs_client_utils/src/test')
-rw-r--r--jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/HttpPatchTest.java109
-rw-r--r--jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/NoRetryJaxRsStrategyTest.java74
-rw-r--r--jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/RetryingJaxRsStrategyTest.java142
3 files changed, 325 insertions, 0 deletions
diff --git a/jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/HttpPatchTest.java b/jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/HttpPatchTest.java
new file mode 100644
index 00000000000..ae8f55af551
--- /dev/null
+++ b/jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/HttpPatchTest.java
@@ -0,0 +1,109 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.jaxrs.client;
+
+import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.jaxrs.annotation.PATCH;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.HttpUrlConnectorProvider;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author bakksjo
+ */
+public class HttpPatchTest extends JerseyTest {
+ private final TestResource testResourceSingleton = new TestResource();
+
+ @Override
+ protected Application configure() {
+ return new Application() {
+ @Override
+ public Set<Class<?>> getClasses() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ return new HashSet<>(Arrays.asList(testResourceSingleton));
+ }
+ };
+ }
+
+ @Override
+ protected void configureClient(final ClientConfig config) {
+ config.getConfiguration().property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);
+ }
+
+ private static final String REQUEST_BODY = "Hello there";
+
+ @Test
+ public void clientPatchRequest() throws Exception {
+ final Response response = target(TestResourceApi.PATH)
+ .request()
+ .method("PATCH", Entity.text(REQUEST_BODY));
+ assertThat(testResourceSingleton.invocation.get(60, TimeUnit.SECONDS), is(REQUEST_BODY));
+ assertThat(response.readEntity(String.class), is(REQUEST_BODY));
+ }
+
+ @Test
+ public void clientPatchRequestUsingProxyClass() throws Exception {
+ final URI targetUri = target(TestResourceApi.PATH).getUri();
+ final HostName apiHost = new HostName(targetUri.getHost());
+ final int apiPort = targetUri.getPort();
+ final String apiPath = targetUri.getPath();
+
+ final JaxRsClientFactory jaxRsClientFactory = new JerseyJaxRsClientFactory();
+ final JaxRsStrategyFactory factory = new JaxRsStrategyFactory(
+ Collections.singleton(apiHost), apiPort, jaxRsClientFactory);
+ final JaxRsStrategy<TestResourceApi> client = factory.apiNoRetries(TestResourceApi.class, apiPath);
+
+ final String responseBody;
+ responseBody = client.apply(api ->
+ api.doPatch(REQUEST_BODY));
+
+ assertThat(testResourceSingleton.invocation.get(60, TimeUnit.SECONDS), is(REQUEST_BODY));
+ assertThat(responseBody, is(REQUEST_BODY));
+ }
+
+ public interface TestResourceApi {
+ String PATH = "test";
+
+ @GET
+ String getHello();
+
+ @PATCH
+ String doPatch(final String body);
+ }
+
+ @Path(TestResourceApi.PATH)
+ public static class TestResource implements TestResourceApi {
+ public final CompletableFuture<String> invocation = new CompletableFuture<>();
+
+ @GET
+ public String getHello() {
+ return "Hello World!";
+ }
+
+ @PATCH
+ public String doPatch(final String body) {
+ invocation.complete(body);
+ return body;
+ }
+ }
+}
diff --git a/jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/NoRetryJaxRsStrategyTest.java b/jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/NoRetryJaxRsStrategyTest.java
new file mode 100644
index 00000000000..a03ada20fc5
--- /dev/null
+++ b/jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/NoRetryJaxRsStrategyTest.java
@@ -0,0 +1,74 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.jaxrs.client;
+
+import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.defaults.Defaults;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.ProcessingException;
+import java.io.IOException;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class NoRetryJaxRsStrategyTest {
+ private static final String API_PATH = "/foo/bar";
+
+ @Path(API_PATH)
+ private interface TestJaxRsApi {
+ @GET
+ @Path("/foo/bar")
+ String doSomething();
+ }
+
+ private static final HostName SERVER_HOST = new HostName("host-1");
+ private static final int REST_PORT = Defaults.getDefaults().vespaWebServicePort();
+
+ private final JaxRsClientFactory jaxRsClientFactory = mock(JaxRsClientFactory.class);
+ private final TestJaxRsApi mockApi = mock(TestJaxRsApi.class);
+ private final JaxRsStrategy<TestJaxRsApi> jaxRsStrategy = new NoRetryJaxRsStrategy<>(
+ SERVER_HOST, REST_PORT, jaxRsClientFactory, TestJaxRsApi.class, API_PATH);
+
+ @Before
+ public void setup() {
+ when(jaxRsClientFactory.createClient(eq(TestJaxRsApi.class), any(HostName.class), anyInt(), anyString()))
+ .thenReturn(mockApi);
+ }
+
+ @Test
+ public void noRetryIfNoFailure() throws Exception {
+ jaxRsStrategy.apply(TestJaxRsApi::doSomething);
+
+ verify(mockApi, times(1)).doSomething();
+
+ verify(jaxRsClientFactory, times(1))
+ .createClient(eq(TestJaxRsApi.class), eq(SERVER_HOST), eq(REST_PORT), eq(API_PATH));
+ }
+
+ @Test
+ public void testNoRetryAfterFailure() throws Exception {
+ // Make the first call fail.
+ when(mockApi.doSomething())
+ .thenThrow(new ProcessingException("Fake timeout induced by test"))
+ .thenReturn("a response");
+
+ try {
+ jaxRsStrategy.apply(TestJaxRsApi::doSomething);
+ fail("The above statement should throw");
+ } catch (IOException e) {
+ // As expected.
+ }
+
+ // Check that there was no second attempt.
+ verify(mockApi, times(1)).doSomething();
+ }
+}
diff --git a/jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/RetryingJaxRsStrategyTest.java b/jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/RetryingJaxRsStrategyTest.java
new file mode 100644
index 00000000000..1002ecc996c
--- /dev/null
+++ b/jaxrs_client_utils/src/test/java/com/yahoo/vespa/jaxrs/client/RetryingJaxRsStrategyTest.java
@@ -0,0 +1,142 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.jaxrs.client;
+
+import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.defaults.Defaults;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.ProcessingException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class RetryingJaxRsStrategyTest {
+ private static final String API_PATH = "/";
+
+ @Path(API_PATH)
+ private interface TestJaxRsApi {
+ @GET
+ @Path("/foo/bar")
+ String doSomething();
+ }
+
+ private static final Set<HostName> SERVER_HOSTS = new HashSet<>(Arrays.asList(
+ new HostName("host-1"),
+ new HostName("host-2"),
+ new HostName("host-3")));
+ private static final int REST_PORT = Defaults.getDefaults().vespaWebServicePort();
+
+ private final JaxRsClientFactory jaxRsClientFactory = mock(JaxRsClientFactory.class);
+ private final TestJaxRsApi mockApi = mock(TestJaxRsApi.class);
+ private final JaxRsStrategy<TestJaxRsApi> jaxRsStrategy = new RetryingJaxRsStrategy<>(
+ SERVER_HOSTS, REST_PORT, jaxRsClientFactory, TestJaxRsApi.class, API_PATH);
+
+ @Before
+ public void setup() {
+ when(jaxRsClientFactory.createClient(eq(TestJaxRsApi.class), any(HostName.class), anyInt(), anyString()))
+ .thenReturn(mockApi);
+ }
+
+ @Test
+ public void noRetryIfNoFailure() throws Exception {
+ jaxRsStrategy.apply(TestJaxRsApi::doSomething);
+
+ verify(mockApi, times(1)).doSomething();
+
+ // Check that one of the supplied hosts is contacted.
+ final ArgumentCaptor<HostName> hostNameCaptor = ArgumentCaptor.forClass(HostName.class);
+ verify(jaxRsClientFactory, times(1))
+ .createClient(eq(TestJaxRsApi.class), hostNameCaptor.capture(), eq(REST_PORT), eq(API_PATH));
+ assertThat(SERVER_HOSTS.contains(hostNameCaptor.getValue()), is(true));
+ }
+
+ @Test
+ public void testRetryAfterSingleFailure() throws Exception {
+ // Make the first attempt fail.
+ when(mockApi.doSomething())
+ .thenThrow(new ProcessingException("Fake timeout induced by test"))
+ .thenReturn("a response");
+
+ jaxRsStrategy.apply(TestJaxRsApi::doSomething);
+
+ // Check that there was a second attempt.
+ verify(mockApi, times(2)).doSomething();
+ }
+
+ @Test
+ public void testRetryUsesAllAvailableServers() throws Exception {
+ when(mockApi.doSomething())
+ .thenThrow(new ProcessingException("Fake timeout 1 induced by test"))
+ .thenThrow(new ProcessingException("Fake timeout 2 induced by test"))
+ .thenReturn("a response");
+
+ jaxRsStrategy.apply(TestJaxRsApi::doSomething);
+
+ verify(mockApi, times(3)).doSomething();
+ verifyAllServersContacted(jaxRsClientFactory);
+ }
+
+ @Test
+ public void testRetryLoopsOverAvailableServers() throws Exception {
+ when(mockApi.doSomething())
+ .thenThrow(new ProcessingException("Fake timeout 1 induced by test"))
+ .thenThrow(new ProcessingException("Fake timeout 2 induced by test"))
+ .thenThrow(new ProcessingException("Fake timeout 3 induced by test"))
+ .thenThrow(new ProcessingException("Fake timeout 4 induced by test"))
+ .thenReturn("a response");
+
+ jaxRsStrategy.apply(TestJaxRsApi::doSomething);
+
+ verify(mockApi, times(5)).doSomething();
+ verifyAllServersContacted(jaxRsClientFactory);
+ }
+
+ @Test
+ public void testRetryGivesUpAfterTwoLoopsOverAvailableServers() throws Exception {
+ when(mockApi.doSomething())
+ .thenThrow(new ProcessingException("Fake timeout 1 induced by test"))
+ .thenThrow(new ProcessingException("Fake timeout 2 induced by test"))
+ .thenThrow(new ProcessingException("Fake timeout 3 induced by test"))
+ .thenThrow(new ProcessingException("Fake timeout 4 induced by test"))
+ .thenThrow(new ProcessingException("Fake timeout 5 induced by test"))
+ .thenThrow(new ProcessingException("Fake timeout 6 induced by test"));
+
+ try {
+ jaxRsStrategy.apply(TestJaxRsApi::doSomething);
+ fail("Exception should be thrown from above statement");
+ } catch (IOException e) {
+ // As expected.
+ }
+
+ verify(mockApi, times(6)).doSomething();
+ verifyAllServersContacted(jaxRsClientFactory);
+ }
+
+ private static void verifyAllServersContacted(
+ final JaxRsClientFactory jaxRsClientFactory) {
+ final ArgumentCaptor<HostName> hostNameCaptor = ArgumentCaptor.forClass(HostName.class);
+ verify(jaxRsClientFactory, atLeast(SERVER_HOSTS.size()))
+ .createClient(eq(TestJaxRsApi.class), hostNameCaptor.capture(), eq(REST_PORT), eq(API_PATH));
+ final Set<HostName> actualServerHostsContacted = new HashSet<>(hostNameCaptor.getAllValues());
+ assertThat(actualServerHostsContacted, equalTo(SERVER_HOSTS));
+ }
+}