Added headers to enable overriding counter increment/decrement 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/e6cd8d5d Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e6cd8d5d Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e6cd8d5d Branch: refs/heads/master Commit: e6cd8d5da16c8526619107ad74b34d0e21ac2f54 Parents: 85ca4c1 Author: Lauri Kimmel <lauri.kim...@gmx.com> Authored: Mon May 26 22:13:58 2014 +1000 Committer: Lauri Kimmel <lauri.kim...@gmx.com> Committed: Mon May 26 22:13:58 2014 +1000 ---------------------------------------------------------------------- README.md | 54 ++++++- .../apache/camel/metrics/MetricsComponent.java | 4 +- .../camel/metrics/counter/CounterProducer.java | 13 +- .../metrics/counter/CounterProducerTest.java | 72 +++++++++ .../camel/metrics/counter/CounterRouteTest.java | 149 +++++++++++++++++-- 5 files changed, 268 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/e6cd8d5d/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index 34bbb23..f961937 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Each metric has type and name. Supported types are ```counter```, ```meter```, ` ### Headers -Metric name defined in URI can be overridden by using Header with name ```org.apache.camel.metrics.metricName```. +Metric name defined in URI can be overridden by using Header with name ```CamelMetricsName```. For example @@ -90,19 +90,49 @@ If neither ```increment``` or ```decrement``` is defined counter value will be i ```java // update counter simple.counter by 7 -from("direct:in").to("metric:counter:simple.counter?increment=7").to("direct:out") +from("direct:in") + .to("metric:counter:simple.counter?increment=7") + .to("direct:out") ``` ```java // increment counter simple.counter by 1 -from("direct:in").to("metric:counter:simple.counter").to("direct:out") +from("direct:in") + .to("metric:counter:simple.counter") + .to("direct:out") ``` ```java // decrement counter simple.counter by 3 -from("direct:in").to("metric:counter:simple.counter?decrement=3").to("direct:out") +from("direct:in") + .to("metric:counter:simple.counter?decrement=3") + .to("direct:out") +``` + +### Headers + +| Name | Description +|------------------------------|---------------------------------| +| CamelMetricsCounterIncrement | Override increment value in URI | +| CamelMetricsCounterDecrement | Override decrement value in URI | + +```java +// update counter simple.counter by 417 +from("direct:in") + .setHeader(MetricsComponent.HEADER_COUNTER_INCREMENT, constant(417L)) + .to("metric:counter:simple.counter?increment=7") + .to("direct:out") ``` +```java +// updates counter using simple language to evaluate body.length +from("direct:in") + .setHeader(MetricsComponent.HEADER_COUNTER_INCREMENT, simple("${body.length}")) + .to("metrics:counter:body.length") + .to("mock:out"); +``` + + ## Metric type meter ``` @@ -119,12 +149,16 @@ If ```mark``` is not set ```meter.mark()``` is called without argument. ```java // marks simple.meter without value -from("direct:in").to("metric:simple.meter").to("direct:out") +from("direct:in") + .to("metric:simple.meter") + .to("direct:out") ``` ```java // marks simple.meter with value 81 -from("direct:in").to("metric:meter:simple.meter?mark=81").to("direct:out") +from("direct:in") + .to("metric:meter:simple.meter?mark=81") + .to("direct:out") ``` ## Metric type histogram @@ -143,12 +177,16 @@ If no ```value``` is not set nothing is added to histogram and warning is logged ```java // adds value 9923 to simple.histogram -from("direct:in").to("metric:histogram:simple.histogram?value=9923").to("direct:out") +from("direct:in") + .to("metric:histogram:simple.histogram?value=9923") + .to("direct:out") ``` ```java // nothing is added to simple.histogram; warning is logged -from("direct:in").to("metric:histogram:simple.histogram").to("direct:out") +from("direct:in") + .to("metric:histogram:simple.histogram") + .to("direct:out") ``` ## Metrics type timer http://git-wip-us.apache.org/repos/asf/camel/blob/e6cd8d5d/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 bc4a2af..cc6a64b 100644 --- a/src/main/java/org/apache/camel/metrics/MetricsComponent.java +++ b/src/main/java/org/apache/camel/metrics/MetricsComponent.java @@ -26,7 +26,9 @@ public class MetricsComponent extends DefaultComponent { public static final String METRIC_REGISTRY_NAME = "metricRegistry"; public static final MetricsType DEFAULT_METRICS_TYPE = MetricsType.METER; public static final long DEFAULT_REPORTING_INTERVAL_SECONDS = 60L; - public static final String HEADER_METRIC_NAME = "org.apache.camel.metrics.metricName"; + public static final String HEADER_METRIC_NAME = "CamelMetricsName"; + public static final String HEADER_COUNTER_INCREMENT = "CamelMetricsCounterIncrement"; + public static final String HEADER_COUNTER_DECREMENT = "CamelMetricsCounterDecrement"; private static final Logger LOG = LoggerFactory.getLogger(MetricsComponent.class); http://git-wip-us.apache.org/repos/asf/camel/blob/e6cd8d5d/src/main/java/org/apache/camel/metrics/counter/CounterProducer.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/camel/metrics/counter/CounterProducer.java b/src/main/java/org/apache/camel/metrics/counter/CounterProducer.java index ec9f426..e7db514 100644 --- a/src/main/java/org/apache/camel/metrics/counter/CounterProducer.java +++ b/src/main/java/org/apache/camel/metrics/counter/CounterProducer.java @@ -1,5 +1,8 @@ package org.apache.camel.metrics.counter; +import static org.apache.camel.metrics.MetricsComponent.HEADER_COUNTER_DECREMENT; +import static org.apache.camel.metrics.MetricsComponent.HEADER_COUNTER_INCREMENT; + import org.apache.camel.Endpoint; import org.apache.camel.Exchange; import org.apache.camel.impl.DefaultProducer; @@ -19,11 +22,13 @@ public class CounterProducer extends DefaultProducer { Counter counter = endpoint.getRegistry().counter(metricName); Long increment = endpoint.getIncrement(); Long decrement = endpoint.getDecrement(); - if (increment != null) { - counter.inc(increment); + Long finalIncrement = endpoint.getLongHeader(exchange, HEADER_COUNTER_INCREMENT, increment); + Long finalDecrement = endpoint.getLongHeader(exchange, HEADER_COUNTER_DECREMENT, decrement); + if (finalIncrement != null) { + counter.inc(finalIncrement); } - else if (decrement != null) { - counter.dec(decrement); + else if (finalDecrement != null) { + counter.dec(finalDecrement); } else { counter.inc(); http://git-wip-us.apache.org/repos/asf/camel/blob/e6cd8d5d/src/test/java/org/apache/camel/metrics/counter/CounterProducerTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/camel/metrics/counter/CounterProducerTest.java b/src/test/java/org/apache/camel/metrics/counter/CounterProducerTest.java index c6ecaa4..c136cf8 100644 --- a/src/test/java/org/apache/camel/metrics/counter/CounterProducerTest.java +++ b/src/test/java/org/apache/camel/metrics/counter/CounterProducerTest.java @@ -1,5 +1,7 @@ package org.apache.camel.metrics.counter; +import static org.apache.camel.metrics.MetricsComponent.HEADER_COUNTER_DECREMENT; +import static org.apache.camel.metrics.MetricsComponent.HEADER_COUNTER_INCREMENT; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.times; @@ -58,12 +60,16 @@ public class CounterProducerTest { public void testProcessWithIncrementOnly() throws Exception { when(endpoint.getIncrement()).thenReturn(INCREMENT); when(endpoint.getDecrement()).thenReturn(null); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_INCREMENT, INCREMENT)).thenReturn(INCREMENT); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_DECREMENT, null)).thenReturn(null); producer.process(exchange); inOrder.verify(endpoint, times(1)).getMetricsName(exchange); inOrder.verify(endpoint, times(1)).getRegistry(); inOrder.verify(registry, times(1)).counter(ENDPOINT_NAME); inOrder.verify(endpoint, times(1)).getIncrement(); inOrder.verify(endpoint, times(1)).getDecrement(); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_INCREMENT, INCREMENT); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_DECREMENT, null); inOrder.verify(counter, times(1)).inc(INCREMENT); inOrder.verifyNoMoreInteractions(); } @@ -72,12 +78,16 @@ public class CounterProducerTest { public void testProcessWithDecrementOnly() throws Exception { when(endpoint.getIncrement()).thenReturn(null); when(endpoint.getDecrement()).thenReturn(DECREMENT); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_INCREMENT, null)).thenReturn(null); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_DECREMENT, DECREMENT)).thenReturn(DECREMENT); producer.process(exchange); inOrder.verify(endpoint, times(1)).getMetricsName(exchange); inOrder.verify(endpoint, times(1)).getRegistry(); inOrder.verify(registry, times(1)).counter(ENDPOINT_NAME); inOrder.verify(endpoint, times(1)).getIncrement(); inOrder.verify(endpoint, times(1)).getDecrement(); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_INCREMENT, null); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_DECREMENT, DECREMENT); inOrder.verify(counter, times(1)).dec(DECREMENT); inOrder.verifyNoMoreInteractions(); } @@ -86,12 +96,16 @@ public class CounterProducerTest { public void testProcessWithIncrementAndDecrement() throws Exception { when(endpoint.getIncrement()).thenReturn(INCREMENT); when(endpoint.getDecrement()).thenReturn(DECREMENT); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_INCREMENT, INCREMENT)).thenReturn(INCREMENT); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_DECREMENT, DECREMENT)).thenReturn(DECREMENT); producer.process(exchange); inOrder.verify(endpoint, times(1)).getMetricsName(exchange); inOrder.verify(endpoint, times(1)).getRegistry(); inOrder.verify(registry, times(1)).counter(ENDPOINT_NAME); inOrder.verify(endpoint, times(1)).getIncrement(); inOrder.verify(endpoint, times(1)).getDecrement(); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_INCREMENT, INCREMENT); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_DECREMENT, DECREMENT); inOrder.verify(counter, times(1)).inc(INCREMENT); inOrder.verifyNoMoreInteractions(); } @@ -100,13 +114,71 @@ public class CounterProducerTest { public void testProcessWithOutIncrementAndDecrement() throws Exception { when(endpoint.getIncrement()).thenReturn(null); when(endpoint.getDecrement()).thenReturn(null); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_INCREMENT, null)).thenReturn(null); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_DECREMENT, null)).thenReturn(null); producer.process(exchange); inOrder.verify(endpoint, times(1)).getMetricsName(exchange); inOrder.verify(endpoint, times(1)).getRegistry(); inOrder.verify(registry, times(1)).counter(ENDPOINT_NAME); inOrder.verify(endpoint, times(1)).getIncrement(); inOrder.verify(endpoint, times(1)).getDecrement(); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_INCREMENT, null); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_DECREMENT, null); inOrder.verify(counter, times(1)).inc(); inOrder.verifyNoMoreInteractions(); } + + @Test + public void testProcessWithHeaderValuesOnly() throws Exception { + when(endpoint.getIncrement()).thenReturn(null); + when(endpoint.getDecrement()).thenReturn(null); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_INCREMENT, null)).thenReturn(INCREMENT + 1); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_DECREMENT, null)).thenReturn(DECREMENT - 1); + producer.process(exchange); + inOrder.verify(endpoint, times(1)).getMetricsName(exchange); + inOrder.verify(endpoint, times(1)).getRegistry(); + inOrder.verify(registry, times(1)).counter(ENDPOINT_NAME); + inOrder.verify(endpoint, times(1)).getIncrement(); + inOrder.verify(endpoint, times(1)).getDecrement(); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_INCREMENT, null); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_DECREMENT, null); + inOrder.verify(counter, times(1)).inc(INCREMENT + 1); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testProcessOverridingIncrement() throws Exception { + when(endpoint.getIncrement()).thenReturn(INCREMENT); + when(endpoint.getDecrement()).thenReturn(DECREMENT); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_INCREMENT, INCREMENT)).thenReturn(INCREMENT + 1); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_DECREMENT, DECREMENT)).thenReturn(DECREMENT); + producer.process(exchange); + inOrder.verify(endpoint, times(1)).getMetricsName(exchange); + inOrder.verify(endpoint, times(1)).getRegistry(); + inOrder.verify(registry, times(1)).counter(ENDPOINT_NAME); + inOrder.verify(endpoint, times(1)).getIncrement(); + inOrder.verify(endpoint, times(1)).getDecrement(); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_INCREMENT, INCREMENT); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_DECREMENT, DECREMENT); + inOrder.verify(counter, times(1)).inc(INCREMENT + 1); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testProcessOverridingDecrement() throws Exception { + when(endpoint.getIncrement()).thenReturn(null); + when(endpoint.getDecrement()).thenReturn(DECREMENT); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_INCREMENT, null)).thenReturn(null); + when(endpoint.getLongHeader(exchange, HEADER_COUNTER_DECREMENT, DECREMENT)).thenReturn(DECREMENT - 1); + producer.process(exchange); + inOrder.verify(endpoint, times(1)).getMetricsName(exchange); + inOrder.verify(endpoint, times(1)).getRegistry(); + inOrder.verify(registry, times(1)).counter(ENDPOINT_NAME); + inOrder.verify(endpoint, times(1)).getIncrement(); + inOrder.verify(endpoint, times(1)).getDecrement(); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_INCREMENT, null); + inOrder.verify(endpoint, times(1)).getLongHeader(exchange, HEADER_COUNTER_DECREMENT, DECREMENT); + inOrder.verify(counter, times(1)).dec(DECREMENT - 1); + inOrder.verifyNoMoreInteractions(); + } } http://git-wip-us.apache.org/repos/asf/camel/blob/e6cd8d5d/src/test/java/org/apache/camel/metrics/counter/CounterRouteTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/camel/metrics/counter/CounterRouteTest.java b/src/test/java/org/apache/camel/metrics/counter/CounterRouteTest.java index df9185b..d28e07a 100644 --- a/src/test/java/org/apache/camel/metrics/counter/CounterRouteTest.java +++ b/src/test/java/org/apache/camel/metrics/counter/CounterRouteTest.java @@ -1,18 +1,32 @@ package org.apache.camel.metrics.counter; +import static org.apache.camel.metrics.MetricsComponent.HEADER_COUNTER_DECREMENT; +import static org.apache.camel.metrics.MetricsComponent.HEADER_COUNTER_INCREMENT; +import static org.apache.camel.metrics.MetricsComponent.HEADER_METRIC_NAME; +import static org.apache.camel.metrics.MetricsComponent.METRIC_REGISTRY_NAME; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.CamelExecutionException; import org.apache.camel.EndpointInject; 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.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 +48,23 @@ public class CounterRouteTest { @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; + + @Produce(uri = "direct:in-3") + private ProducerTemplate producer3; + + @Produce(uri = "direct:in-4") + private ProducerTemplate producer4; + + private MetricRegistry mockRegistry; + + private Counter mockCounter; + + private InOrder inOrder; @Configuration public static class TestConfig extends SingleRouteCamelConfiguration { @@ -47,32 +76,130 @@ public class CounterRouteTest { @Override public void configure() throws Exception { - from("direct:in") + from("direct:in-1") .to("metrics:counter:A?increment=5") .to("mock:out"); + + from("direct:in-2") + .to("metrics:counter:A?decrement=9") + .to("mock:out"); + + from("direct:in-3") + .setHeader(HEADER_COUNTER_INCREMENT, constant(417L)) + .to("metrics:counter:A") + .to("mock:out"); + + from("direct:in-4") + .setHeader(HEADER_COUNTER_INCREMENT, simple("${body.length}")) + .to("metrics:counter: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); + mockCounter = mock(Counter.class); + inOrder = Mockito.inOrder(mockRegistry, mockCounter); + } + + @After + public void tearDown() { + endpoint.reset(); + reset(mockRegistry, mockCounter); + } + @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); - Counter mockCounter = Mockito.mock(Counter.class); - InOrder inOrder = Mockito.inOrder(mockRegistry, mockCounter); when(mockRegistry.counter("B")).thenReturn(mockCounter); - endpoint.expectedMessageCount(1); - producer.sendBodyAndHeader(new Object(), MetricsComponent.HEADER_METRIC_NAME, "B"); + producer1.sendBodyAndHeader(new Object(), HEADER_METRIC_NAME, "B"); endpoint.assertIsSatisfied(); inOrder.verify(mockRegistry, times(1)).counter("B"); inOrder.verify(mockCounter, times(1)).inc(5L); inOrder.verifyNoMoreInteractions(); } + + @Test + public void testOverrideIncrement() throws Exception { + when(mockRegistry.counter("A")).thenReturn(mockCounter); + endpoint.expectedMessageCount(1); + producer1.sendBodyAndHeader(new Object(), HEADER_COUNTER_INCREMENT, 14L); + endpoint.assertIsSatisfied(); + inOrder.verify(mockRegistry, times(1)).counter("A"); + inOrder.verify(mockCounter, times(1)).inc(14L); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testOverrideIncrementAndDecrement() throws Exception { + when(mockRegistry.counter("A")).thenReturn(mockCounter); + endpoint.expectedMessageCount(1); + Map<String, Object> headers = new HashMap<String, Object>(); + headers.put(HEADER_COUNTER_INCREMENT, 912L); + headers.put(HEADER_COUNTER_DECREMENT, 43219L); + producer1.sendBodyAndHeaders(new Object(), headers); + endpoint.assertIsSatisfied(); + inOrder.verify(mockRegistry, times(1)).counter("A"); + inOrder.verify(mockCounter, times(1)).inc(912L); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testOverrideDecrement() throws Exception { + when(mockRegistry.counter("A")).thenReturn(mockCounter); + endpoint.expectedMessageCount(1); + producer2.sendBodyAndHeader(new Object(), HEADER_COUNTER_DECREMENT, 7L); + endpoint.assertIsSatisfied(); + inOrder.verify(mockRegistry, times(1)).counter("A"); + inOrder.verify(mockCounter, times(1)).dec(7L); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testOverrideIncrementWithWrongType() throws Exception { + when(mockRegistry.counter("A")).thenReturn(mockCounter); + endpoint.expectedMessageCount(0); + try { + producer1.sendBodyAndHeader(new Object(), HEADER_COUNTER_INCREMENT, "this is not a valid long value"); + fail("Exception expected"); + } + catch (Exception e) { + assertThat(e, instanceOf(CamelExecutionException.class)); + } + endpoint.assertIsSatisfied(); + inOrder.verify(mockRegistry, times(1)).counter("A"); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testOverrideUsingConstantValue() throws Exception { + when(mockRegistry.counter("A")).thenReturn(mockCounter); + endpoint.expectedMessageCount(1); + producer3.sendBody(new Object()); + endpoint.assertIsSatisfied(); + inOrder.verify(mockRegistry, times(1)).counter("A"); + inOrder.verify(mockCounter, times(1)).inc(417L); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testOverrideUsingScriptEvaluation() throws Exception { + when(mockRegistry.counter("A")).thenReturn(mockCounter); + endpoint.expectedMessageCount(1); + String message = "Hello from Camel Metrics!"; + producer4.sendBody(message); + endpoint.assertIsSatisfied(); + inOrder.verify(mockRegistry, times(1)).counter("A"); + inOrder.verify(mockCounter, times(1)).inc(message.length()); + inOrder.verifyNoMoreInteractions(); + } }