Added header to enable overriding timer action in the URI.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/5845dbe7 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/5845dbe7 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/5845dbe7 Branch: refs/heads/master Commit: 5845dbe77f6c7908e0cf81f679496cecd6776f58 Parents: 10f5c7c Author: Lauri Kimmel <lauri.kim...@gmx.com> Authored: Mon Jun 2 23:46:18 2014 +1000 Committer: Lauri Kimmel <lauri.kim...@gmx.com> Committed: Mon Jun 16 21:04:22 2014 +1000 ---------------------------------------------------------------------- README.md | 16 +++++ .../apache/camel/metrics/MetricsComponent.java | 1 + .../camel/metrics/timer/TimerProducer.java | 12 +++- .../camel/metrics/timer/TimerProducerTest.java | 63 ++++++++++++++++- .../camel/metrics/timer/TimerRouteTest.java | 74 +++++++++++++++++--- 5 files changed, 151 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/5845dbe7/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index 10a1e4c..b0b7bab 100644 --- a/README.md +++ b/README.md @@ -253,3 +253,19 @@ from("direct:in") ``` `Timer Context` objects are stored as `Exchange` properties between different Metrics component calls. + +### Headers + +Message header can be used to override `action` value specified in Metrics component URI. + +| Name | Description | Expected type | +|-------------------------|------------------------------|----------------------------------------------------------| +| CamelMetricsTimerAction | Override timer action in URI | org.apache.camel.metrics.timer.TimerEndpoint.TimerAction | + +```java +// sets timer action using header +from("direct:in") + .setHeader(MetricsComponent.HEADER_TIMER_ACTION, TimerAction.start) + .to("metric:timer:simple.timer") + .to("direct:out") +``` http://git-wip-us.apache.org/repos/asf/camel/blob/5845dbe7/src/main/java/org/apache/camel/metrics/MetricsComponent.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/camel/metrics/MetricsComponent.java b/src/main/java/org/apache/camel/metrics/MetricsComponent.java index ba04c23..c803e4f 100644 --- a/src/main/java/org/apache/camel/metrics/MetricsComponent.java +++ b/src/main/java/org/apache/camel/metrics/MetricsComponent.java @@ -32,6 +32,7 @@ public class MetricsComponent extends DefaultComponent { public static final String HEADER_COUNTER_DECREMENT = HEADER_PERFIX + "CounterDecrement"; public static final String HEADER_HISTOGRAM_VALUE = HEADER_PERFIX + "HistogramValue"; public static final String HEADER_METER_MARK = HEADER_PERFIX + "MeterMark"; + public static final String HEADER_TIMER_ACTION = HEADER_PERFIX + "TimerAction"; private static final Logger LOG = LoggerFactory.getLogger(MetricsComponent.class); http://git-wip-us.apache.org/repos/asf/camel/blob/5845dbe7/src/main/java/org/apache/camel/metrics/timer/TimerProducer.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/camel/metrics/timer/TimerProducer.java b/src/main/java/org/apache/camel/metrics/timer/TimerProducer.java index 4f5b809..9586bbd 100644 --- a/src/main/java/org/apache/camel/metrics/timer/TimerProducer.java +++ b/src/main/java/org/apache/camel/metrics/timer/TimerProducer.java @@ -1,6 +1,10 @@ package org.apache.camel.metrics.timer; +import static org.apache.camel.metrics.MetricsComponent.HEADER_TIMER_ACTION; +import static org.apache.camel.metrics.timer.TimerEndpoint.ENDPOINT_URI; + import org.apache.camel.Exchange; +import org.apache.camel.Message; import org.apache.camel.metrics.AbstractMetricsProducer; import org.apache.camel.metrics.timer.TimerEndpoint.TimerAction; import org.slf4j.Logger; @@ -19,11 +23,13 @@ public class TimerProducer extends AbstractMetricsProducer<TimerEndpoint> { @Override protected void doProcess(Exchange exchange, TimerEndpoint endpoint, MetricRegistry registry, String metricsName) throws Exception { + Message in = exchange.getIn(); TimerAction action = endpoint.getAction(); - if (action == TimerAction.start) { + TimerAction finalAction = in.getHeader(HEADER_TIMER_ACTION, action, TimerAction.class); + if (finalAction == TimerAction.start) { handleStart(exchange, registry, metricsName); } - else if (action == TimerAction.stop) { + else if (finalAction == TimerAction.stop) { handleStop(exchange, registry, metricsName); } else { @@ -57,7 +63,7 @@ public class TimerProducer extends AbstractMetricsProducer<TimerEndpoint> { } String getPropertyName(String metricsName) { - return new StringBuilder(TimerEndpoint.ENDPOINT_URI) + return new StringBuilder(ENDPOINT_URI) .append(":") .append(metricsName) .toString(); http://git-wip-us.apache.org/repos/asf/camel/blob/5845dbe7/src/test/java/org/apache/camel/metrics/timer/TimerProducerTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/camel/metrics/timer/TimerProducerTest.java b/src/test/java/org/apache/camel/metrics/timer/TimerProducerTest.java index e61da97..ff7c1f6 100644 --- a/src/test/java/org/apache/camel/metrics/timer/TimerProducerTest.java +++ b/src/test/java/org/apache/camel/metrics/timer/TimerProducerTest.java @@ -1,5 +1,6 @@ package org.apache.camel.metrics.timer; +import static org.apache.camel.metrics.MetricsComponent.HEADER_TIMER_ACTION; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.notNullValue; @@ -8,6 +9,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; import org.apache.camel.Exchange; +import org.apache.camel.Message; import org.apache.camel.metrics.timer.TimerEndpoint.TimerAction; import org.junit.Before; import org.junit.Test; @@ -41,6 +43,9 @@ public class TimerProducerTest { @Mock private Timer.Context context; + @Mock + private Message in; + private TimerProducer producer; @Mock @@ -49,10 +54,11 @@ public class TimerProducerTest { @Before public void setUp() throws Exception { producer = new TimerProducer(endpoint); - inOrder = Mockito.inOrder(endpoint, exchange, registry, timer, context); + inOrder = Mockito.inOrder(endpoint, exchange, registry, timer, context, in); when(endpoint.getRegistry()).thenReturn(registry); when(registry.timer(METRICS_NAME)).thenReturn(timer); when(timer.time()).thenReturn(context); + when(exchange.getIn()).thenReturn(in); } @Test @@ -64,9 +70,12 @@ public class TimerProducerTest { @Test public void testProcessStart() throws Exception { when(endpoint.getAction()).thenReturn(TimerAction.start); + when(in.getHeader(HEADER_TIMER_ACTION, TimerAction.start, TimerAction.class)).thenReturn(TimerAction.start); when(exchange.getProperty(PROPERTY_NAME, Timer.Context.class)).thenReturn(null); producer.doProcess(exchange, endpoint, registry, METRICS_NAME); + inOrder.verify(exchange, times(1)).getIn(); inOrder.verify(endpoint, times(1)).getAction(); + inOrder.verify(in, times(1)).getHeader(HEADER_TIMER_ACTION, TimerAction.start, TimerAction.class); inOrder.verify(exchange, times(1)).getProperty(PROPERTY_NAME, Timer.Context.class); inOrder.verify(registry, times(1)).timer(METRICS_NAME); inOrder.verify(timer, times(1)).time(); @@ -75,11 +84,29 @@ public class TimerProducerTest { } @Test + public void testProcessStartWithOverride() throws Exception { + when(endpoint.getAction()).thenReturn(TimerAction.start); + when(in.getHeader(HEADER_TIMER_ACTION, TimerAction.start, TimerAction.class)).thenReturn(TimerAction.stop); + when(exchange.getProperty(PROPERTY_NAME, Timer.Context.class)).thenReturn(context); + producer.doProcess(exchange, endpoint, registry, METRICS_NAME); + inOrder.verify(exchange, times(1)).getIn(); + inOrder.verify(endpoint, times(1)).getAction(); + inOrder.verify(in, times(1)).getHeader(HEADER_TIMER_ACTION, TimerAction.start, TimerAction.class); + inOrder.verify(exchange, times(1)).getProperty(PROPERTY_NAME, Timer.Context.class); + inOrder.verify(context, times(1)).stop(); + inOrder.verify(exchange, times(1)).removeProperty(PROPERTY_NAME); + inOrder.verifyNoMoreInteractions(); + } + + @Test public void testProcessStop() throws Exception { when(endpoint.getAction()).thenReturn(TimerAction.stop); + when(in.getHeader(HEADER_TIMER_ACTION, TimerAction.stop, TimerAction.class)).thenReturn(TimerAction.stop); when(exchange.getProperty(PROPERTY_NAME, Timer.Context.class)).thenReturn(context); producer.doProcess(exchange, endpoint, registry, METRICS_NAME); + inOrder.verify(exchange, times(1)).getIn(); inOrder.verify(endpoint, times(1)).getAction(); + inOrder.verify(in, times(1)).getHeader(HEADER_TIMER_ACTION, TimerAction.stop, TimerAction.class); inOrder.verify(exchange, times(1)).getProperty(PROPERTY_NAME, Timer.Context.class); inOrder.verify(context, times(1)).stop(); inOrder.verify(exchange, times(1)).removeProperty(PROPERTY_NAME); @@ -87,10 +114,44 @@ public class TimerProducerTest { } @Test + public void testProcessStopWithOverride() throws Exception { + when(endpoint.getAction()).thenReturn(TimerAction.stop); + when(in.getHeader(HEADER_TIMER_ACTION, TimerAction.stop, TimerAction.class)).thenReturn(TimerAction.start); + when(exchange.getProperty(PROPERTY_NAME, Timer.Context.class)).thenReturn(null); + producer.doProcess(exchange, endpoint, registry, METRICS_NAME); + inOrder.verify(exchange, times(1)).getIn(); + inOrder.verify(endpoint, times(1)).getAction(); + inOrder.verify(in, times(1)).getHeader(HEADER_TIMER_ACTION, TimerAction.stop, TimerAction.class); + inOrder.verify(exchange, times(1)).getProperty(PROPERTY_NAME, Timer.Context.class); + inOrder.verify(registry, times(1)).timer(METRICS_NAME); + inOrder.verify(timer, times(1)).time(); + inOrder.verify(exchange, times(1)).setProperty(PROPERTY_NAME, context); + inOrder.verifyNoMoreInteractions(); + } + + @Test public void testProcessNoAction() throws Exception { when(endpoint.getAction()).thenReturn(null); + when(in.getHeader(HEADER_TIMER_ACTION, null, TimerAction.class)).thenReturn(null); + producer.doProcess(exchange, endpoint, registry, METRICS_NAME); + inOrder.verify(exchange, times(1)).getIn(); + inOrder.verify(endpoint, times(1)).getAction(); + inOrder.verify(in, times(1)).getHeader(HEADER_TIMER_ACTION, null, TimerAction.class); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testProcessNoActionOverride() throws Exception { + when(endpoint.getAction()).thenReturn(null); + when(in.getHeader(HEADER_TIMER_ACTION, null, TimerAction.class)).thenReturn(TimerAction.start); producer.doProcess(exchange, endpoint, registry, METRICS_NAME); + inOrder.verify(exchange, times(1)).getIn(); inOrder.verify(endpoint, times(1)).getAction(); + inOrder.verify(in, times(1)).getHeader(HEADER_TIMER_ACTION, null, TimerAction.class); + inOrder.verify(exchange, times(1)).getProperty(PROPERTY_NAME, Timer.Context.class); + inOrder.verify(registry, times(1)).timer(METRICS_NAME); + inOrder.verify(timer, times(1)).time(); + inOrder.verify(exchange, times(1)).setProperty(PROPERTY_NAME, context); inOrder.verifyNoMoreInteractions(); } http://git-wip-us.apache.org/repos/asf/camel/blob/5845dbe7/src/test/java/org/apache/camel/metrics/timer/TimerRouteTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/camel/metrics/timer/TimerRouteTest.java b/src/test/java/org/apache/camel/metrics/timer/TimerRouteTest.java index 279be95..1a6581c 100644 --- a/src/test/java/org/apache/camel/metrics/timer/TimerRouteTest.java +++ b/src/test/java/org/apache/camel/metrics/timer/TimerRouteTest.java @@ -1,5 +1,9 @@ package org.apache.camel.metrics.timer; +import static org.apache.camel.metrics.MetricsComponent.HEADER_METRIC_NAME; +import static org.apache.camel.metrics.MetricsComponent.HEADER_TIMER_ACTION; +import static org.apache.camel.metrics.MetricsComponent.METRIC_REGISTRY_NAME; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; @@ -8,11 +12,13 @@ import org.apache.camel.Produce; import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; -import org.apache.camel.metrics.MetricsComponent; +import org.apache.camel.metrics.timer.TimerEndpoint.TimerAction; import org.apache.camel.spring.javaconfig.SingleRouteCamelConfiguration; import org.apache.camel.test.spring.CamelSpringDelegatingTestContextLoader; import org.apache.camel.test.spring.CamelSpringJUnit4ClassRunner; import org.apache.camel.test.spring.MockEndpoints; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; @@ -34,8 +40,17 @@ public class TimerRouteTest { @EndpointInject(uri = "mock:out") private MockEndpoint endpoint; - @Produce(uri = "direct:in") - private ProducerTemplate producer; + @Produce(uri = "direct:in-1") + private ProducerTemplate producer1; + + @Produce(uri = "direct:in-2") + private ProducerTemplate producer2; + + private MetricRegistry mockRegistry; + + private Timer mockTimer; + + private InOrder inOrder; @Configuration public static class TestConfig extends SingleRouteCamelConfiguration { @@ -47,32 +62,69 @@ public class TimerRouteTest { @Override public void configure() throws Exception { - from("direct:in") + from("direct:in-1") .to("metrics:timer:A?action=start") .to("mock:out"); + + from("direct:in-2") + .to("metrics:timer:A") + .to("mock:out"); } }; } - @Bean(name = MetricsComponent.METRIC_REGISTRY_NAME) + @Bean(name = METRIC_REGISTRY_NAME) public MetricRegistry getMetricRegistry() { return Mockito.mock(MetricRegistry.class); } } + @Before + public void setup() { + // TODO - 12.05.2014, Lauri - is there any better way to set this up? + mockRegistry = endpoint.getCamelContext().getRegistry().lookupByNameAndType(METRIC_REGISTRY_NAME, MetricRegistry.class); + mockTimer = Mockito.mock(Timer.class); + inOrder = Mockito.inOrder(mockRegistry, mockTimer); + } + + @After + public void tearDown() { + endpoint.reset(); + reset(mockRegistry, mockTimer); + } + @Test public void testOverrideMetricsName() throws Exception { - // TODO - 12.05.2014, Lauri - is there any better way to set this up? - MetricRegistry mockRegistry = endpoint.getCamelContext().getRegistry().lookupByNameAndType(MetricsComponent.METRIC_REGISTRY_NAME, MetricRegistry.class); - Timer mockTimer = Mockito.mock(Timer.class); - InOrder inOrder = Mockito.inOrder(mockRegistry, mockTimer); when(mockRegistry.timer("B")).thenReturn(mockTimer); - endpoint.expectedMessageCount(1); - producer.sendBodyAndHeader(new Object(), MetricsComponent.HEADER_METRIC_NAME, "B"); + Object body = new Object(); + endpoint.expectedBodiesReceived(body); + producer1.sendBodyAndHeader(body, HEADER_METRIC_NAME, "B"); endpoint.assertIsSatisfied(); inOrder.verify(mockRegistry, times(1)).timer("B"); inOrder.verify(mockTimer, times(1)).time(); inOrder.verifyNoMoreInteractions(); } + + @Test + public void testOverrideExistingAction() throws Exception { + when(mockRegistry.timer("A")).thenReturn(mockTimer); + Object body = new Object(); + endpoint.expectedBodiesReceived(body); + producer1.sendBodyAndHeader(body, HEADER_TIMER_ACTION, TimerAction.stop); + endpoint.assertIsSatisfied(); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testOverrideNoAction() throws Exception { + when(mockRegistry.timer("A")).thenReturn(mockTimer); + Object body = new Object(); + endpoint.expectedBodiesReceived(body); + producer2.sendBodyAndHeader(body, HEADER_TIMER_ACTION, TimerAction.start); + endpoint.assertIsSatisfied(); + inOrder.verify(mockRegistry, times(1)).timer("A"); + inOrder.verify(mockTimer, times(1)).time(); + inOrder.verifyNoMoreInteractions(); + } }