Repository: camel Updated Branches: refs/heads/master c99c49e60 -> 3c1dc946d
CAMEL-10356 camel-metrics - Add support for gauge type Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/3c1dc946 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/3c1dc946 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/3c1dc946 Branch: refs/heads/master Commit: 3c1dc946d17b2175ae0dd2499b779a40ef08ab12 Parents: c99c49e Author: Tomohisa Igarashi <tm.igara...@gmail.com> Authored: Thu Oct 6 23:37:15 2016 +0900 Committer: Tomohisa Igarashi <tm.igara...@gmail.com> Committed: Fri Oct 7 15:21:36 2016 +0900 ---------------------------------------------------------------------- .../src/main/docs/metrics-component.adoc | 65 +++++++- .../metrics/AbstractMetricsProducer.java | 2 +- .../camel/component/metrics/GaugeProducer.java | 84 ++++++++++ .../component/metrics/MetricsConstants.java | 15 +- .../component/metrics/MetricsEndpoint.java | 12 ++ .../component/metrics/GaugeEndpointTest.java | 74 +++++++++ .../component/metrics/GaugeProducerTest.java | 104 ++++++++++++ .../camel/component/metrics/GaugeRouteTest.java | 164 +++++++++++++++++++ .../metrics/MetricsComponentRouteTest.java | 8 +- .../component/metrics/MetricsComponentTest.java | 5 +- 10 files changed, 513 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/main/docs/metrics-component.adoc ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/main/docs/metrics-component.adoc b/components/camel-metrics/src/main/docs/metrics-component.adoc index 82174ac..dcc8557 100644 --- a/components/camel-metrics/src/main/docs/metrics-component.adoc +++ b/components/camel-metrics/src/main/docs/metrics-component.adoc @@ -15,7 +15,7 @@ Metrics Component The **metrics:** component allows to collect various metrics directly from Camel routes. Supported metric types are link:#MetricsComponent-counter[counter], link:#MetricsComponent-histogram[histogram], -link:#MetricsComponent-meter[meter] and link:#MetricsComponent-timer[timer]. http://metrics.dropwizard.io[Metrics] provides +link:#MetricsComponent-meter[meter], link:#MetricsComponent-timer[timer] and link:#MetricsComponent-gauge[gauge]. http://metrics.dropwizard.io[Metrics] provides simple way to measure behaviour of application. Configurable reporting backend is enabling different integration options for collecting and visualizing statistics. The component also provides @@ -41,7 +41,7 @@ URI format [source] ---- -metrics:[ meter | counter | histogram | timer ]:metricname[?options] +metrics:[ meter | counter | histogram | timer | gauge ]:metricname[?options] ---- [[MetricsComponent-options]] @@ -64,7 +64,7 @@ The Metrics component supports 1 options which are listed below. // endpoint options: START -The Metrics component supports 8 endpoint options which are listed below: +The Metrics component supports 9 endpoint options which are listed below: {% raw %} [width="100%",cols="2,1,1m,1m,5",options="header"] @@ -76,6 +76,7 @@ The Metrics component supports 8 endpoint options which are listed below: | decrement | producer | | Long | Decrement value when using counter type | increment | producer | | Long | Increment value when using counter type | mark | producer | | Long | Mark when using meter type +| subject | producer | | Object | Subject value when using gauge type | value | producer | | Long | Value value when using histogram type | synchronous | advanced | false | boolean | Sets whether synchronous processing should be strictly used or Camel is allowed to use asynchronous processing (if supported). |======================================================================= @@ -154,9 +155,9 @@ Usage Each metric has type and name. Supported types are link:#MetricsComponent-counter[counter], -link:#MetricsComponent-histogram[histogram], link:#MetricsComponent-meter[meter] and -link:#MetricsComponent-timer[timer]. Metric name is simple string. If -metric type is not provided then type meter is used by default. +link:#MetricsComponent-histogram[histogram], link:#MetricsComponent-meter[meter], +link:#MetricsComponent-timer[timer] and link:#MetricsComponent-gauge[gauge]. +Metric name is simple string. If metric type is not provided then type meter is used by default. [[MetricsComponent-Headers]] Headers @@ -443,6 +444,58 @@ from("direct:in") .to("direct:out"); ---- +[[MetricsComponent-gaugeMetrictypegauge]] +[[MetricsComponent-gauge]]Metric type gauge +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +[source] +---- +metrics:gauge:metricname[?options] +---- + +[[MetricsComponent-Options.4]] +Options ++++++++ + +[width="100%",cols="10%,10%,80%",options="header",] +|===================================================== +|Name |Default |Description +|subject |- |Any object to be observed by the gauge +|===================================================== + +If `subject` is not defined it's simply ignored, i.e. the gauge is not registered. + +[source,java] +---- +// update gauge "simple.gauge" by a bean "mySubjectBean" +from("direct:in") + .to("metric:gauge:simple.gauge?subject=#mySubjectBean") + .to("direct:out"); +---- + +[[MetricsComponent-Headers.5]] +Headers ++++++++ + +Message headers can be used to override `subject` values specified in Metrics component URI. +Note: if `CamelMetricsName` header is specified, then new gauge is registered in addition to +default one specified in a URI. + +[width="100%",cols="10%,80%,10%",options="header",] +|==================================================================== +|Name |Description |Expected type +|CamelMetricsGaugeSubject |Override subject value in URI |Object +|==================================================================== + +[source,java] +---- +// update gauge simple.gauge by a String literal "myUpdatedSubject" +from("direct:in") + .setHeader(MetricsConstants.HEADER_GAUGE_SUBJECT, constant("myUpdatedSubject")) + .to("metric:counter:simple.gauge?subject=#mySubjectBean") + .to("direct:out"); +---- + [[MetricsComponent-MetricsRoutePolicyFactory]] MetricsRoutePolicyFactory ^^^^^^^^^^^^^^^^^^^^^^^^^ http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/AbstractMetricsProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/AbstractMetricsProducer.java b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/AbstractMetricsProducer.java index 538b0c4..79acbe6 100644 --- a/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/AbstractMetricsProducer.java +++ b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/AbstractMetricsProducer.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; public abstract class AbstractMetricsProducer extends DefaultProducer { - public static final String HEADER_PATTERN = MetricsConstants.HEADER_PERFIX + "*"; + public static final String HEADER_PATTERN = MetricsConstants.HEADER_PREFIX + "*"; private static final Logger LOG = LoggerFactory.getLogger(AbstractMetricsProducer.class); public AbstractMetricsProducer(MetricsEndpoint endpoint) { http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/GaugeProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/GaugeProducer.java b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/GaugeProducer.java new file mode 100644 index 0000000..7271250 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/GaugeProducer.java @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.metrics; + +import com.codahale.metrics.Gauge; +import com.codahale.metrics.MetricRegistry; +import org.apache.camel.Exchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.camel.component.metrics.MetricsConstants.HEADER_GAUGE_SUBJECT; + +public class GaugeProducer extends AbstractMetricsProducer { + + private static final Logger LOG = LoggerFactory.getLogger(GaugeProducer.class); + + public GaugeProducer(MetricsEndpoint endpoint) { + super(endpoint); + Gauge<?> gauge = endpoint.getRegistry().getGauges().get(endpoint.getMetricsName()); + if (gauge instanceof CamelMetricsGauge) { + CamelMetricsGauge camelMetricsGauge = (CamelMetricsGauge)gauge; + if (endpoint.getSubject() != null) { + camelMetricsGauge.setValue(endpoint.getSubject()); + } + } else { + if (endpoint.getSubject() != null) { + endpoint.getRegistry().register(endpoint.getMetricsName(), new CamelMetricsGauge(endpoint.getSubject())); + } else { + LOG.info("No subject found for Gauge \"{}\". Ignoring...", endpoint.getMetricsName()); + } + } + } + + @Override + protected void doProcess(Exchange exchange, MetricsEndpoint endpoint, MetricRegistry registry, String metricsName) throws Exception { + Gauge<?> gauge = registry.getGauges().get(metricsName); + if (gauge instanceof CamelMetricsGauge) { + CamelMetricsGauge camelMetricsGauge = (CamelMetricsGauge)gauge; + Object subject = exchange.getIn().getHeader(HEADER_GAUGE_SUBJECT, Object.class); + if (subject != null) { + camelMetricsGauge.setValue(subject); + } + } else { + Object subject = exchange.getIn().getHeader(HEADER_GAUGE_SUBJECT, Object.class); + Object finalSubject = subject != null ? subject : endpoint.getSubject(); + if (finalSubject != null) { + registry.register(metricsName, new CamelMetricsGauge(finalSubject)); + } else { + LOG.info("No subject found for Gauge \"{}\". Ignoring...", metricsName); + } + } + } + + class CamelMetricsGauge implements Gauge<Object> { + private Object subject; + + CamelMetricsGauge(Object subject) { + this.subject = subject; + } + + @Override + public Object getValue() { + return subject; + } + + public void setValue(Object subject) { + this.subject = subject; + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsConstants.java b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsConstants.java index 0bfe35f..900a571 100644 --- a/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsConstants.java +++ b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsConstants.java @@ -18,13 +18,14 @@ package org.apache.camel.component.metrics; public final class MetricsConstants { - public static final String HEADER_PERFIX = "CamelMetrics"; - public static final String HEADER_TIMER_ACTION = HEADER_PERFIX + "TimerAction"; - public static final String HEADER_METER_MARK = HEADER_PERFIX + "MeterMark"; - public static final String HEADER_HISTOGRAM_VALUE = HEADER_PERFIX + "HistogramValue"; - public static final String HEADER_COUNTER_DECREMENT = HEADER_PERFIX + "CounterDecrement"; - public static final String HEADER_COUNTER_INCREMENT = HEADER_PERFIX + "CounterIncrement"; - public static final String HEADER_METRIC_NAME = HEADER_PERFIX + "Name"; + public static final String HEADER_PREFIX = "CamelMetrics"; + public static final String HEADER_TIMER_ACTION = HEADER_PREFIX + "TimerAction"; + public static final String HEADER_METER_MARK = HEADER_PREFIX + "MeterMark"; + public static final String HEADER_HISTOGRAM_VALUE = HEADER_PREFIX + "HistogramValue"; + public static final String HEADER_COUNTER_DECREMENT = HEADER_PREFIX + "CounterDecrement"; + public static final String HEADER_COUNTER_INCREMENT = HEADER_PREFIX + "CounterIncrement"; + public static final String HEADER_GAUGE_SUBJECT = HEADER_PREFIX + "GaugeSubject"; + public static final String HEADER_METRIC_NAME = HEADER_PREFIX + "Name"; private MetricsConstants() { } http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsEndpoint.java b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsEndpoint.java index 7fe7e15..b7fd3a1 100644 --- a/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsEndpoint.java +++ b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/MetricsEndpoint.java @@ -50,6 +50,8 @@ public class MetricsEndpoint extends DefaultEndpoint { private Long increment; @UriParam(description = "Decrement value when using counter type") private Long decrement; + @UriParam(description = "Subject value when using gauge type") + private Object subject; public MetricsEndpoint(String uri, Component component, MetricRegistry registry, MetricsType metricsType, String metricsName) { super(uri, component); @@ -73,6 +75,8 @@ public class MetricsEndpoint extends DefaultEndpoint { return new MeterProducer(this); } else if (metricsType == MetricsType.TIMER) { return new TimerProducer(this); + } else if (metricsType == MetricsType.GAUGE) { + return new GaugeProducer(this); } else { throw new IllegalArgumentException("Metrics type " + metricsType + " is not supported"); } @@ -134,4 +138,12 @@ public class MetricsEndpoint extends DefaultEndpoint { public void setDecrement(Long decrement) { this.decrement = decrement; } + + public Object getSubject() { + return subject; + } + + public void setSubject(Object subject) { + this.subject = subject; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeEndpointTest.java ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeEndpointTest.java b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeEndpointTest.java new file mode 100644 index 0000000..778ea82 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeEndpointTest.java @@ -0,0 +1,74 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.metrics; + +import com.codahale.metrics.MetricRegistry; +import org.apache.camel.Producer; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +@RunWith(MockitoJUnitRunner.class) +public class GaugeEndpointTest { + + private static final String METRICS_NAME = "metrics.name"; + private static final Object VALUE = "subject"; + + @Mock + private MetricRegistry registry; + + private MetricsEndpoint endpoint; + + @Before + public void setUp() throws Exception { + endpoint = new MetricsEndpoint(null, null, registry, MetricsType.GAUGE, METRICS_NAME); + } + + @Test + public void testGaugeEndpoint() throws Exception { + assertThat(endpoint.getRegistry(), is(registry)); + assertThat(endpoint.getMetricsName(), is(METRICS_NAME)); + assertThat(endpoint.getSubject(), is(nullValue())); + } + + @Test + public void testCreateProducer() throws Exception { + Producer producer = endpoint.createProducer(); + assertThat(producer, is(notNullValue())); + assertThat(producer, is(instanceOf(GaugeProducer.class))); + } + + @Test + public void testGetSubject() throws Exception { + assertThat(endpoint.getSubject(), is(nullValue())); + } + + @Test + public void testSetSubject() throws Exception { + endpoint.setSubject(VALUE); + assertThat(endpoint.getSubject(), is(VALUE)); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeProducerTest.java ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeProducerTest.java b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeProducerTest.java new file mode 100644 index 0000000..6fd3b92 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeProducerTest.java @@ -0,0 +1,104 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.metrics; + +import com.codahale.metrics.MetricRegistry; +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.component.metrics.GaugeProducer.CamelMetricsGauge; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.apache.camel.component.metrics.MetricsConstants.HEADER_GAUGE_SUBJECT; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GaugeProducerTest { + + private static final String METRICS_NAME = "metrics.name"; + private static final String METRICS_NAME_HEADER = "metrics.name.header"; + private static final Object VALUE = "my subject"; + private static final Object VALUE_HEADER = "my subject header"; + + @Mock + private MetricsEndpoint endpoint; + + @Mock + private Exchange exchange; + + @Mock + private MetricRegistry registry; + + @Mock + private Message in; + + private GaugeProducer producer; + + @Before + public void setUp() throws Exception { + when(endpoint.getRegistry()).thenReturn(registry); + when(endpoint.getSubject()).thenReturn(VALUE); + when(endpoint.getMetricsName()).thenReturn(METRICS_NAME); + when(exchange.getIn()).thenReturn(in); + producer = new GaugeProducer(endpoint); + } + + @Test + public void testGaugeProducer() throws Exception { + assertThat(producer.getEndpoint().equals(endpoint), is(true)); + } + + @Test + public void testDefault() throws Exception { + verify(registry, times(1)).register(eq(METRICS_NAME), argThat(new ArgumentMatcher<CamelMetricsGauge>() { + @Override + public boolean matches(Object argument) { + return argument instanceof CamelMetricsGauge && VALUE.equals(((CamelMetricsGauge)argument).getValue()); + } + })); + } + + @Test + public void testProcessWithHeaderValues() throws Exception { + when(in.getHeader(HEADER_GAUGE_SUBJECT, Object.class)).thenReturn(VALUE_HEADER); + producer.doProcess(exchange, endpoint, registry, METRICS_NAME_HEADER); + verify(in, times(1)).getHeader(HEADER_GAUGE_SUBJECT, Object.class); + verify(registry, times(1)).register(eq(METRICS_NAME), argThat(new ArgumentMatcher<CamelMetricsGauge>() { + @Override + public boolean matches(Object argument) { + return argument instanceof CamelMetricsGauge && VALUE.equals(((CamelMetricsGauge)argument).getValue()); + } + })); + verify(registry, times(1)).register(eq(METRICS_NAME_HEADER), argThat(new ArgumentMatcher<CamelMetricsGauge>() { + @Override + public boolean matches(Object argument) { + return argument instanceof CamelMetricsGauge && VALUE_HEADER.equals(((CamelMetricsGauge)argument).getValue()); + } + })); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeRouteTest.java b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeRouteTest.java new file mode 100644 index 0000000..9058faa --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/GaugeRouteTest.java @@ -0,0 +1,164 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.metrics; + +import java.util.SortedMap; +import java.util.TreeMap; + +import com.codahale.metrics.Gauge; +import com.codahale.metrics.MetricRegistry; +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.metrics.GaugeProducer.CamelMetricsGauge; +import org.apache.camel.component.mock.MockEndpoint; +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.ArgumentMatcher; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +import static org.apache.camel.component.metrics.MetricsComponent.METRIC_REGISTRY_NAME; +import static org.apache.camel.component.metrics.MetricsConstants.HEADER_GAUGE_SUBJECT; +import static org.apache.camel.component.metrics.MetricsConstants.HEADER_METRIC_NAME; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(CamelSpringJUnit4ClassRunner.class) +@ContextConfiguration( + classes = { GaugeRouteTest.TestConfig.class }, + loader = CamelSpringDelegatingTestContextLoader.class) +@MockEndpoints +public class GaugeRouteTest { + + private static SortedMap<String, Gauge> mockGauges = new TreeMap<String, Gauge>();; + + @EndpointInject(uri = "mock:out") + private MockEndpoint endpoint; + + @Produce(uri = "direct:in-1") + private ProducerTemplate producer1; + + @Produce(uri = "direct:in-2") + private ProducerTemplate producer2; + + private MetricRegistry mockRegistry; + + @Configuration + public static class TestConfig extends SingleRouteCamelConfiguration { + + @Bean + @Override + public RouteBuilder route() { + return new RouteBuilder() { + + @Override + public void configure() throws Exception { + from("direct:in-1") + .to("metrics:gauge:A?subject=#mySubject") + .to("mock:out"); + + from("direct:in-2") + .setHeader(HEADER_METRIC_NAME, constant("B")) + .setHeader(HEADER_GAUGE_SUBJECT, constant("my overriding subject")) + .to("metrics:gauge:A?subject=#mySubject") + .to("mock:out"); + + } + }; + } + + @Bean(name = METRIC_REGISTRY_NAME) + public MetricRegistry getMetricRegistry() { + MetricRegistry registry = Mockito.mock(MetricRegistry.class); + when(registry.getGauges()).thenReturn(mockGauges); + when(registry.register(Mockito.anyString(), Mockito.any(CamelMetricsGauge.class))).then( + new Answer<CamelMetricsGauge>() { + @Override + public CamelMetricsGauge answer(InvocationOnMock invocation) throws Throwable { + mockGauges.put(invocation.getArgumentAt(0, String.class), invocation.getArgumentAt(1, CamelMetricsGauge.class)); + return invocation.getArgumentAt(1, CamelMetricsGauge.class); + } + }); + return registry; + } + + @Bean(name = "mySubject") + public String getSubject() { + return "my subject"; + } + } + + @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); + } + + @After + public void tearDown() { + endpoint.reset(); + mockGauges.clear(); + } + + @Test + public void testDefault() throws Exception { + endpoint.expectedMessageCount(1); + producer1.sendBody(new Object()); + endpoint.assertIsSatisfied(); + verify(mockRegistry, times(1)).register(eq("A"), argThat(new ArgumentMatcher<CamelMetricsGauge>() { + @Override + public boolean matches(Object argument) { + return argument instanceof CamelMetricsGauge && "my subject".equals(((CamelMetricsGauge)argument).getValue()); + } + })); + } + + @Test + public void testOverride() throws Exception { + verify(mockRegistry, times(1)).register(eq("A"), argThat(new ArgumentMatcher<CamelMetricsGauge>() { + @Override + public boolean matches(Object argument) { + return argument instanceof CamelMetricsGauge && "my subject".equals(((CamelMetricsGauge)argument).getValue()); + } + })); + endpoint.expectedMessageCount(1); + producer2.sendBody(new Object()); + endpoint.assertIsSatisfied(); + verify(mockRegistry, times(1)).register(eq("B"), argThat(new ArgumentMatcher<CamelMetricsGauge>() { + @Override + public boolean matches(Object argument) { + return argument instanceof CamelMetricsGauge && "my overriding subject".equals(((CamelMetricsGauge)argument).getValue()); + } + })); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentRouteTest.java b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentRouteTest.java index 7459a19..26fadb8 100644 --- a/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentRouteTest.java +++ b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentRouteTest.java @@ -29,7 +29,7 @@ import org.junit.Test; import static org.apache.camel.component.metrics.MetricsConstants.HEADER_HISTOGRAM_VALUE; import static org.apache.camel.component.metrics.MetricsConstants.HEADER_METRIC_NAME; -import static org.apache.camel.component.metrics.MetricsConstants.HEADER_PERFIX; +import static org.apache.camel.component.metrics.MetricsConstants.HEADER_PREFIX; public class MetricsComponentRouteTest extends CamelTestSupport { @@ -72,14 +72,14 @@ public class MetricsComponentRouteTest extends CamelTestSupport { Date now = new Date(); mock.expectedBodiesReceived(body); - mock.expectedHeaderReceived("." + HEADER_PERFIX, "value"); + mock.expectedHeaderReceived("." + HEADER_PREFIX, "value"); mock.expectedHeaderReceived("date", now); Map<String, Object> headers = new HashMap<String, Object>(); headers.put(HEADER_METRIC_NAME, "a name"); headers.put(HEADER_HISTOGRAM_VALUE, 34L); - headers.put(HEADER_PERFIX + "notExistingHeader", "?"); - headers.put("." + HEADER_PERFIX, "value"); + headers.put(HEADER_PREFIX + "notExistingHeader", "?"); + headers.put("." + HEADER_PREFIX, "value"); headers.put("date", now); template2.sendBodyAndHeaders(body, headers); http://git-wip-us.apache.org/repos/asf/camel/blob/3c1dc946/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentTest.java ---------------------------------------------------------------------- diff --git a/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentTest.java b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentTest.java index 569933f..0f1ec94 100644 --- a/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentTest.java +++ b/components/camel-metrics/src/test/java/org/apache/camel/component/metrics/MetricsComponentTest.java @@ -143,10 +143,11 @@ public class MetricsComponentTest { assertThat(endpoint, is(instanceOf(MetricsEndpoint.class))); } - @Test(expected = IllegalArgumentException.class) + @Test public void testCreateNewEndpointForGauge() throws Exception { MetricsEndpoint endpoint = new MetricsEndpoint(null, null, metricRegistry, MetricsType.GAUGE, "a name"); - endpoint.createProducer(); + assertThat(endpoint, is(notNullValue())); + assertThat(endpoint, is(instanceOf(MetricsEndpoint.class))); } @Test