CAMEL-9098 camel-hystrix (WIP): Add tests for Hystrix Endpoints.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/d8fc17c7 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/d8fc17c7 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/d8fc17c7 Branch: refs/heads/feature/camel-hystrix Commit: d8fc17c74408ef20ded2704242b28576f49c37e2 Parents: edc0ba8 Author: Raul Kripalani <ra...@apache.org> Authored: Thu Aug 27 13:24:39 2015 +0100 Committer: Raul Kripalani <ra...@apache.org> Committed: Thu Aug 27 13:24:39 2015 +0100 ---------------------------------------------------------------------- .../component/hystrix/AbstractHystrixTest.java | 18 ++ .../component/hystrix/HystrixEndpointTest.java | 225 +++++++++++++++++++ .../component/hystrix/HystrixProcessorTest.java | 6 - 3 files changed, 243 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/d8fc17c7/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/AbstractHystrixTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/AbstractHystrixTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/AbstractHystrixTest.java index 785c764..ae76e71 100644 --- a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/AbstractHystrixTest.java +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/AbstractHystrixTest.java @@ -19,9 +19,11 @@ package org.apache.camel.component.hystrix; import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixObservableCommand; +import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.After; /** * Abstract Hystrix test. @@ -54,4 +56,20 @@ public abstract class AbstractHystrixTest extends CamelTestSupport { hystrix = context.getComponent("hystrix", HystrixComponent.class); } + /** + * Remove the HystrixRequestContext from the current thread, if one is present. + * @throws Exception + */ + @After + public void tearDown() throws Exception { + super.tearDown(); + HystrixRequestContext.setContextOnCurrentThread(null); + } + + protected class DummyException extends RuntimeException { + public DummyException(String message) { + super(message); + } + } + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/d8fc17c7/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixEndpointTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixEndpointTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixEndpointTest.java index ddabbb3..cb42762 100644 --- a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixEndpointTest.java +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixEndpointTest.java @@ -16,7 +16,17 @@ */ package org.apache.camel.component.hystrix; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; +import org.apache.camel.CamelExecutionException; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.ExpressionBuilder; +import org.apache.camel.util.ObjectHelper; import org.junit.Test; +import rx.functions.Action2; /** * Tests for Hystrix endpoints. @@ -36,7 +46,222 @@ public class HystrixEndpointTest extends AbstractHystrixTest { assertEquals("Hello World 0", template.requestBody(hystrixE, "Hello World")); assertMockEndpointsSatisfied(); + } + + @Test + public void testEndpointFallbackExceptionThrown() throws Exception { + HystrixDelegateEndpoint hystrixE = hystrix.wrapper() + .forStaticEndpoint("mock:test", setter) + .withFallbackProcessor(fallback) + .build(); + hystrixE.setCamelContext(context); + + getMockEndpoint("mock:test").whenAnyExchangeReceived(new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + throw new DummyException("Bang!"); + } + }); + getMockEndpoint("mock:test").message(0).body().isEqualTo("Hello World"); + + assertEquals("Hello Fallback", template.requestBody(hystrixE, "Hello World")); + + } + + @Test + public void testEndpointFallbackExceptionSet() throws Exception { + HystrixDelegateEndpoint hystrixE = hystrix.wrapper() + .forStaticEndpoint("mock:test", setter) + .withFallbackProcessor(fallback) + .build(); + hystrixE.setCamelContext(context); + + getMockEndpoint("mock:test").whenAnyExchangeReceived(new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.setException(new DummyException("Bang!")); + } + }); + getMockEndpoint("mock:test").message(0).body().isEqualTo("Hello World"); + + assertEquals("Hello Fallback", template.requestBody(hystrixE, "Hello World")); + } + + @Test + public void testEndpointNoFallbackSuppressedExceptionThrown() throws Exception { + HystrixDelegateEndpoint hystrixE = hystrix.wrapper() + .forStaticEndpoint("mock:test", setter) + .withFallbackProcessor(fallback) + .suppressFallbackForExceptions(DummyException.class) + .build(); + hystrixE.setCamelContext(context); + + getMockEndpoint("mock:test").whenAnyExchangeReceived(new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + throw new DummyException("Bang!"); + } + }); + getMockEndpoint("mock:test").message(0).body().isEqualTo("Hello World"); + + // producer template will throw the exception, as it's suppressed for fallback + try { + template.requestBody(hystrixE, "Hello World"); + } catch (CamelExecutionException e) { + assertEquals(DummyException.class, ObjectHelper.getException(DummyException.class, e).getClass()); + return; + } + + fail("Should have thrown the exception, as fallback is suppressed"); + } + + @Test + public void testEndpointNoFallbackSuppressedExceptionSet() throws Exception { + HystrixDelegateEndpoint hystrixE = hystrix.wrapper() + .forStaticEndpoint("mock:test", setter) + .withFallbackProcessor(fallback) + .suppressFallbackForExceptions(DummyException.class) + .build(); + hystrixE.setCamelContext(context); + + getMockEndpoint("mock:test").whenAnyExchangeReceived(new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.setException(new DummyException("Bang!")); + } + }); + getMockEndpoint("mock:test").message(0).body().isEqualTo("Hello World"); + + // producer template will throw the exception, as it's suppressed for fallback + try { + template.requestBody(hystrixE, "Hello World"); + } catch (CamelExecutionException e) { + assertEquals(DummyException.class, ObjectHelper.getException(DummyException.class, e).getClass()); + return; + } + + fail("Should have thrown the exception, as fallback is suppressed"); + } + + @Test + public void testEndpointWithAndWithoutCache() throws Exception { + HystrixDelegateEndpoint hystrixE = hystrix.wrapper() + .forStaticEndpoint("mock:test", setter) + .withCacheKey(ExpressionBuilder.bodyExpression()) + .build(); + hystrixE.setCamelContext(context); + + getMockEndpoint("mock:test").whenAnyExchangeReceived(target); + getMockEndpoint("mock:test").expectedMessageCount(1); + getMockEndpoint("mock:test").message(0).body().isEqualTo("Hello World"); + + assertEquals("Hello World 0", template.requestBody(hystrixE, "Hello World")); + assertEquals("Hello World 0", template.requestBody(hystrixE, "Hello World")); + + assertMockEndpointsSatisfied(); + + // now remove the cache from that endpoint, and we should receive different responses now + getMockEndpoint("mock:test").expectedMessageCount(3); + + hystrixE = hystrix.wrapper() + .forStaticEndpoint("mock:test", setter) + .build(); + hystrixE.setCamelContext(context); + + assertEquals("Hello World 1", template.requestBody(hystrixE, "Hello World")); + assertEquals("Hello World 2", template.requestBody(hystrixE, "Hello World")); + + assertMockEndpointsSatisfied(); + + } + + @Test + public void testEndpointWithCacheAndCustomMergeFunction() throws Exception { + HystrixDelegateEndpoint hystrixE = hystrix.wrapper() + .forStaticEndpoint("mock:test", setter) + .withCacheKey(ExpressionBuilder.bodyExpression()) + .withCacheMergeStrategy(new Action2<Exchange, Exchange>() { + @Override + public void call(Exchange incoming, Exchange result) { + incoming.getIn().setBody("MERGED: " + result.getIn().getBody(String.class)); + } + }) + .build(); + + hystrixE.setCamelContext(context); + + getMockEndpoint("mock:test").whenAnyExchangeReceived(target); + getMockEndpoint("mock:test").expectedMessageCount(1); + getMockEndpoint("mock:test").message(0).body().isEqualTo("Hello World"); + + assertEquals("Hello World 0", template.requestBody(hystrixE, "Hello World")); + assertEquals("MERGED: Hello World 0", template.requestBody(hystrixE, "Hello World")); + + assertMockEndpointsSatisfied(); + } + + @Test + public void testEndpointWithNoRequestPropagation() throws Exception { + final HystrixDelegateEndpoint hystrixE = hystrix.wrapper() + .forStaticEndpoint("mock:test", setter) + .withCacheKey(ExpressionBuilder.bodyExpression()) + .withPropagateRequestContext(false) + .build(); + hystrixE.setCamelContext(context); + + getMockEndpoint("mock:test").whenAnyExchangeReceived(target); + getMockEndpoint("mock:test").message(0).body().isEqualTo("Hello World"); + getMockEndpoint("mock:test").message(1).body().isEqualTo("Hello World"); + + final HystrixRequestContext context = HystrixRequestContext.initializeContext(); + assertEquals("Hello World 0", template.requestBodyAndHeader(hystrixE, "Hello World", + HystrixComponent.HYSTRIX_REQUEST_CONTEXT_HEADER_NAME, context)); + + // now run the second request in a different thread with the same request context + // ensure that cache is not used, because request context was not propagated + final CountDownLatch latch = new CountDownLatch(1); + new Thread(new Runnable() { + @Override + public void run() { + assertEquals("Hello World 1", template.requestBodyAndHeader(hystrixE, "Hello World", + HystrixComponent.HYSTRIX_REQUEST_CONTEXT_HEADER_NAME, context)); + latch.countDown(); + } + }).start(); + + latch.await(5, TimeUnit.SECONDS); + } + + @Test + public void testEndpointWithRequestPropagation() throws Exception { + final HystrixDelegateEndpoint hystrixE = hystrix.wrapper() + .forStaticEndpoint("mock:test", setter) + .withCacheKey(ExpressionBuilder.bodyExpression()) + .withPropagateRequestContext(true) + .build(); + hystrixE.setCamelContext(context); + + getMockEndpoint("mock:test").whenAnyExchangeReceived(target); + getMockEndpoint("mock:test").message(0).body().isEqualTo("Hello World"); + getMockEndpoint("mock:test").message(1).body().isEqualTo("Hello World"); + + final HystrixRequestContext context = HystrixRequestContext.initializeContext(); + assertEquals("Hello World 0", template.requestBodyAndHeader(hystrixE, "Hello World", + HystrixComponent.HYSTRIX_REQUEST_CONTEXT_HEADER_NAME, context)); + + // now run the second request in a different thread with the same request context + // ensure that cache IS used; response should be the same as the initial one + final CountDownLatch latch = new CountDownLatch(1); + new Thread(new Runnable() { + @Override + public void run() { + assertEquals("Hello World 0", template.requestBodyAndHeader(hystrixE, "Hello World", + HystrixComponent.HYSTRIX_REQUEST_CONTEXT_HEADER_NAME, context)); + latch.countDown(); + } + }).start(); + latch.await(5, TimeUnit.SECONDS); } } http://git-wip-us.apache.org/repos/asf/camel/blob/d8fc17c7/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixProcessorTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixProcessorTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixProcessorTest.java index 210fa14..b3d0856 100644 --- a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixProcessorTest.java +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/HystrixProcessorTest.java @@ -226,10 +226,4 @@ public class HystrixProcessorTest extends AbstractHystrixTest { assertEquals("Hello World 0", exchange.getIn().getBody()); } - private class DummyException extends RuntimeException { - public DummyException(String message) { - super(message); - } - } - }