package org.zalando.riptide.hystrix; import com.google.common.collect.Iterables; import com.hystrix.junit.HystrixRequestContextRule; import com.netflix.hystrix.HystrixInvokableInfo; import com.netflix.hystrix.HystrixRequestLog; import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.springframework.test.web.client.MockRestServiceServer; import org.zalando.riptide.Rest; import java.util.Collection; import java.util.concurrent.atomic.AtomicReference; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasToString; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static org.springframework.http.HttpStatus.Series.SUCCESSFUL; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; import static org.zalando.riptide.Bindings.anySeries; import static org.zalando.riptide.Bindings.on; import static org.zalando.riptide.Navigators.series; import static org.zalando.riptide.Route.pass; public final class HystrixTest { @Rule public final ExpectedException exception = ExpectedException.none(); @Rule public final HystrixRequestContextRule hystrix = new HystrixRequestContextRule(); private final Rest unit; private final MockRestServiceServer server; public HystrixTest() { final MockSetup setup = new MockSetup(); this.unit = setup.getRestBuilder().plugin(new HystrixPlugin()).build(); this.server = setup.getServer(); } @After public void after() { server.verify(); } @Test public void shouldExecute() { server.expect(requestTo("https://api.example.com/foo")) .andRespond(withSuccess().body("Hello!")); final AtomicReference<String> capture = new AtomicReference<>(); unit.get("/foo") .dispatch(series(), on(SUCCESSFUL).call(String.class, capture::set)) .join(); assertThat(capture.get(), is("Hello!")); } @Test public void shouldUseHostAsGroupKeyAndPathAsCommandKey() { server.expect(requestTo("https://api.example.com/foo?async=true")) .andRespond(withSuccess()); unit.get("/foo") .queryParam("async", "true") .dispatch(series(), anySeries().call(pass())).join(); final HystrixInvokableInfo<?> command = intercept(); assertThat(command.getCommandGroup(), hasToString("api.example.com")); assertThat(command.getCommandKey(), hasToString("GET /foo")); } @Test public void shouldUseUriTemplateAsCommandKeyIfAvailable() { server.expect(requestTo("https://api.example.com/foo")) .andRespond(withSuccess()); unit.get("/{id}", "foo") .dispatch(series(), anySeries().call(pass())).join(); final HystrixInvokableInfo<?> command = intercept(); assertThat(command.getCommandGroup(), hasToString("api.example.com")); assertThat(command.getCommandKey(), hasToString("GET /{id}")); } private HystrixInvokableInfo<?> intercept() { final HystrixRequestLog log = HystrixRequestLog.getCurrentRequest(); final Collection<HystrixInvokableInfo<?>> commands = log.getAllExecutedCommands(); assertThat(commands, hasSize(1)); return Iterables.getOnlyElement(commands); } }