Merge 'https://github.com/laurikimmel/camel-metrics.git' into camel-metrics
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/641de098 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/641de098 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/641de098 Branch: refs/heads/master Commit: 641de09867a8ecab71133cf7bf7fc66159323cdc Parents: ed13d4e 03afdee Author: Lauri Kimmel <lauri.kim...@gmx.com> Authored: Tue Jul 1 23:41:27 2014 +1000 Committer: Lauri Kimmel <lauri.kim...@gmx.com> Committed: Tue Jul 1 23:41:27 2014 +1000 ---------------------------------------------------------------------- components/camel-metrics/.gitignore | 8 + components/camel-metrics/.travis.yml | 9 + components/camel-metrics/README.md | 271 +++++++++++++++++++ components/camel-metrics/pom.xml | 137 ++++++++++ .../camel/metrics/AbstractMetricsEndpoint.java | 37 +++ .../camel/metrics/AbstractMetricsProducer.java | 59 ++++ .../apache/camel/metrics/MetricsComponent.java | 121 +++++++++ .../org/apache/camel/metrics/MetricsType.java | 37 +++ .../camel/metrics/counter/CounterEndpoint.java | 50 ++++ .../camel/metrics/counter/CounterProducer.java | 37 +++ .../metrics/histogram/HistogramEndpoint.java | 39 +++ .../metrics/histogram/HistogramProducer.java | 35 +++ .../camel/metrics/meter/MeterEndpoint.java | 39 +++ .../camel/metrics/meter/MeterProducer.java | 31 +++ .../camel/metrics/timer/TimerEndpoint.java | 44 +++ .../camel/metrics/timer/TimerProducer.java | 75 +++++ .../services/org/apache/camel/component/metrics | 1 + .../metrics/AbstractMetricsEndpointTest.java | 96 +++++++ .../metrics/AbstractMetricsProducerTest.java | 172 ++++++++++++ .../metrics/MetricComponentSpringTest.java | 77 ++++++ .../metrics/MetricsComponentRouteTest.java | 99 +++++++ .../camel/metrics/MetricsComponentTest.java | 204 ++++++++++++++ .../apache/camel/metrics/MetricsTypeTest.java | 19 ++ .../metrics/counter/CounterEndpointTest.java | 88 ++++++ .../metrics/counter/CounterProducerTest.java | 181 +++++++++++++ .../camel/metrics/counter/CounterRouteTest.java | 195 +++++++++++++ .../histogram/HistogramEndpointTest.java | 74 +++++ .../histogram/HistogramProducerTest.java | 111 ++++++++ .../metrics/histogram/HistogramRouteTest.java | 109 ++++++++ .../camel/metrics/meter/MeterEndpointTest.java | 75 +++++ .../camel/metrics/meter/MeterProducerTest.java | 112 ++++++++ .../camel/metrics/meter/MeterRouteTest.java | 151 +++++++++++ .../camel/metrics/timer/TimerEndpointTest.java | 75 +++++ .../camel/metrics/timer/TimerProducerTest.java | 215 +++++++++++++++ .../camel/metrics/timer/TimerRouteTest.java | 130 +++++++++ .../src/test/resources/log4j.properties | 14 + 36 files changed, 3227 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/.gitignore ---------------------------------------------------------------------- diff --cc components/camel-metrics/.gitignore index 0000000,0000000..9365f3c new file mode 100644 --- /dev/null +++ b/components/camel-metrics/.gitignore @@@ -1,0 -1,0 +1,8 @@@ ++# Maven ++target ++ ++# Eclipse ++ ++.classpath ++.project ++.settings/ http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/.travis.yml ---------------------------------------------------------------------- diff --cc components/camel-metrics/.travis.yml index 0000000,0000000..5cf3ef3 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/.travis.yml @@@ -1,0 -1,0 +1,9 @@@ ++language: java ++jdk: ++ - oraclejdk7 ++ - openjdk7 ++ - openjdk6 ++ ++branches: ++ only: ++ - master http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/README.md ---------------------------------------------------------------------- diff --cc components/camel-metrics/README.md index 0000000,0000000..b0b7bab new file mode 100644 --- /dev/null +++ b/components/camel-metrics/README.md @@@ -1,0 -1,0 +1,271 @@@ ++# Metrics Component ++ ++[](https://travis-ci.org/laurikimmel/camel-metrics) ++ ++**Available as of Camel 2.13** ++ ++The **metrics:** component allows you to collect various metrics directly from Camel routes. Supported metric types are _counter_, _meter_, _histogram_ and _timer_. [Metrics](http://metrics.codahale.com) provides simple way to measure behaviour of your application. Configurable reporting _backend_ is enabling different integration options for collecting and visualizing statistics. ++ ++Maven users will need to add the following dependency to their pom.xml for this component: ++ ++```xml ++ ++<dependency> ++ <groupId>org.apache.camel</groupId> ++ <artifactId>camel-metrics</artifactId> ++ <version>x.x.x</version> ++ <!-- use the same version as your Camel core version --> ++</dependency> ++``` ++ ++# URI format ++ ++``` ++metrics:[ meter | counter | histogram | timer ]:metricname[?options] ++``` ++ ++# Metric Registry ++ ++If MetricRegistry instance for name `metricRegistry` is not found from Camel registry default one is used. Default MetricRegistry uses Slf4jReporter and 60 second reporting interval. ++MetricRegistry instance can be configured by adding bean with name `metricRegistry` to Camel registry. For example using Spring Java Configuration. ++ ++```java ++ ++ @Configuration ++ public static class MyConfig extends SingleRouteCamelConfiguration { ++ ++ @Bean ++ @Override ++ public RouteBuilder route() { ++ return new RouteBuilder() { ++ ++ @Override ++ public void configure() throws Exception { ++ // define Camel routes here ++ } ++ }; ++ } ++ ++ @Bean(name = MetricsComponent.METRIC_REGISTRY_NAME) ++ public MetricRegistry getMetricRegistry() { ++ MetricRegistry registry = ...; ++ return registry; ++ } ++ } ++ ++``` ++ ++# Usage ++ ++Each metric has type and name. Supported types are `counter`, `meter`, `histogram` and `timer`. Metric name is simple string. If metric type is not provided then type `meter` is used by default. ++ ++### Headers ++ ++Metric name defined in URI can be overridden by using header with name `CamelMetricsName`. ++ ++For example ++ ++```java ++from("direct:in") ++ .setHeader(MetricsComponent.HEADER_METRIC_NAME, constant("new.name")) ++ .to("metrics:counter:name.not.used") ++ .to("direct:out") ++``` ++ ++will update counter with name `new.name` instead of `name.not.used`. ++ ++All Metrics specific headers are removed from the message once Metrics endpoint finishes processing of exchange. ++While processing exchange Metrics endpoint will catch all exceptions and write log entry using level `warn`. ++ ++ ++## Metrics type counter ++ ++``` ++metrics:counter:metricname[?options] ++``` ++ ++Where options are ++ ++| Name | Default | Description | ++|-----------|---------|-----------------------------------------| ++| increment | - | Long value to add to the counter | ++| decrement | - | Long value to subtract from the counter | ++ ++If neither `increment` or `decrement` is defined counter value will be incremented by one. If `increment` and `decrement` are both defined only increment operation is called. ++ ++```java ++// update counter simple.counter by 7 ++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") ++``` ++ ++```java ++// decrement counter simple.counter by 3 ++from("direct:in") ++ .to("metric:counter:simple.counter?decrement=3") ++ .to("direct:out") ++``` ++ ++### Headers ++ ++Message headers can be used to override `increment` and `decrement` values specified in Metrics component URI. ++ ++| Name | Description | Expected type | ++|------------------------------|---------------------------------|---------------| ++| CamelMetricsCounterIncrement | Override increment value in URI | Long | ++| CamelMetricsCounterDecrement | Override decrement value in URI | Long | ++ ++```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 histogram ++ ++``` ++metrics:histogram:metricname[?options] ++``` ++ ++Where options are ++ ++| Name | Default | Description | ++|-------|---------|---------------------------| ++| value | - | Value to use in histogram | ++ ++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") ++``` ++ ++```java ++// nothing is added to simple.histogram; warning is logged ++from("direct:in") ++ .to("metric:histogram:simple.histogram") ++ .to("direct:out") ++``` ++ ++### Headers ++ ++Message header can be used to override `value` specified in Metrics component URI. ++ ++| Name | Description | Expected type | ++|----------------------------|---------------------------------|---------------| ++| CamelMetricsHistogramValue | Override histogram value in URI | Long | ++ ++```java ++// adds value 992 to simple.histogram ++from("direct:in") ++ .setHeader(MetricsComponent.HEADER_HISTOGRAM_VALUE, constant(992L)) ++ .to("metric:histogram:simple.histogram?value=700") ++ .to("direct:out") ++``` ++ ++ ++## Metric type meter ++ ++``` ++metrics:meter:metricname[?options] ++``` ++ ++Where options are ++ ++| Name | Default | Description | ++|------|---------|---------------------------| ++| mark | - | Long value to use as mark | ++ ++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") ++``` ++ ++```java ++// marks simple.meter with value 81 ++from("direct:in") ++ .to("metric:meter:simple.meter?mark=81") ++ .to("direct:out") ++``` ++ ++### Headers ++ ++Message header can be used to override `mark` value specified in Metrics component URI. ++ ++| Name | Description | Expected type | ++|-----------------------|----------------------------|---------------| ++| CamelMetricsMeterMark | Override mark value in URI | Long | ++ ++```java ++// updates meter simple.meter with value 345 ++from("direct:in") ++ .setHeader(MetricsComponent.HEADER_METER_MARK, constant(345L)) ++ .to("metric:meter:simple.meter?mark=123") ++ .to("direct:out") ++``` ++ ++ ++## Metrics type timer ++ ++``` ++metrics:timer:metricname[?options] ++``` ++ ++Where options are ++ ++| Name | Default | Description | ++|--------|---------|-------------------| ++| action | - | `start` or `stop` | ++ ++If no `action` or invalid value is provided warning is logged and no timer is updated. If `action` `start` is called on already running timer or `stop` is called on not running timer nothing is updated and warning is logged. ++ ++```java ++// measure time taken by route calculate ++from("direct:in") ++ .to("metrics:timer:simple.timer?action=start") ++ .to("direct:calculate") ++ .to("metrics:timer:simple.timer?action=stop"); ++``` ++ ++`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/641de098/components/camel-metrics/pom.xml ---------------------------------------------------------------------- diff --cc components/camel-metrics/pom.xml index 0000000,0000000..0f65ab5 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/pom.xml @@@ -1,0 -1,0 +1,137 @@@ ++<?xml version="1.0" encoding="UTF-8"?> ++<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> ++ ++ <modelVersion>4.0.0</modelVersion> ++ ++ <groupId>org.apache.camel</groupId> ++ <artifactId>camel-metrics</artifactId> ++ <packaging>bundle</packaging> ++ <version>2.13.0</version> ++ ++ <name>Camel Metrics Component</name> ++ <url>http://camel.apache.org</url> ++ ++ <properties> ++ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> ++ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> ++ </properties> ++ ++ <dependencies> ++ <dependency> ++ <groupId>org.apache.camel</groupId> ++ <artifactId>camel-core</artifactId> ++ <version>2.13.0</version> ++ </dependency> ++ <dependency> ++ <groupId>com.codahale.metrics</groupId> ++ <artifactId>metrics-core</artifactId> ++ <version>3.0.1</version> ++ </dependency> ++ ++ <!-- logging --> ++ <dependency> ++ <groupId>org.slf4j</groupId> ++ <artifactId>slf4j-api</artifactId> ++ <version>1.7.6</version> ++ </dependency> ++ <dependency> ++ <groupId>org.slf4j</groupId> ++ <artifactId>slf4j-log4j12</artifactId> ++ <version>1.7.6</version> ++ <scope>test</scope> ++ </dependency> ++ <dependency> ++ <groupId>log4j</groupId> ++ <artifactId>log4j</artifactId> ++ <version>1.2.17</version> ++ <scope>test</scope> ++ </dependency> ++ ++ <!-- testing --> ++ <dependency> ++ <groupId>org.apache.camel</groupId> ++ <artifactId>camel-test</artifactId> ++ <version>2.13.0</version> ++ <scope>test</scope> ++ </dependency> ++ <dependency> ++ <groupId>org.apache.camel</groupId> ++ <artifactId>camel-spring</artifactId> ++ <version>2.13.0</version> ++ <scope>test</scope> ++ </dependency> ++ <dependency> ++ <groupId>org.apache.camel</groupId> ++ <artifactId>camel-spring-javaconfig</artifactId> ++ <version>2.13.0</version> ++ <scope>test</scope> ++ </dependency> ++ <dependency> ++ <groupId>org.apache.camel</groupId> ++ <artifactId>camel-test-spring</artifactId> ++ <version>2.13.0</version> ++ <scope>test</scope> ++ </dependency> ++ <dependency> ++ <groupId>org.mockito</groupId> ++ <artifactId>mockito-core</artifactId> ++ <version>1.9.5</version> ++ <scope>test</scope> ++ </dependency> ++ <dependency> ++ <groupId>junit</groupId> ++ <artifactId>junit</artifactId> ++ <version>4.11</version> ++ <scope>test</scope> ++ </dependency> ++ <dependency> ++ <groupId>org.hamcrest</groupId> ++ <artifactId>hamcrest-all</artifactId> ++ <version>1.3</version> ++ <scope>test</scope> ++ </dependency> ++ ++ </dependencies> ++ ++ <build> ++ <defaultGoal>install</defaultGoal> ++ ++ <plugins> ++ ++ <plugin> ++ <groupId>org.apache.maven.plugins</groupId> ++ <artifactId>maven-compiler-plugin</artifactId> ++ <version>2.5.1</version> ++ <configuration> ++ <source>1.6</source> ++ <target>1.6</target> ++ </configuration> ++ </plugin> ++ ++ <plugin> ++ <groupId>org.apache.maven.plugins</groupId> ++ <artifactId>maven-resources-plugin</artifactId> ++ <version>2.6</version> ++ <configuration> ++ <encoding>UTF-8</encoding> ++ </configuration> ++ </plugin> ++ ++ <!-- to generate the MANIFEST-FILE of the bundle --> ++ <plugin> ++ <groupId>org.apache.felix</groupId> ++ <artifactId>maven-bundle-plugin</artifactId> ++ <version>2.3.7</version> ++ <extensions>true</extensions> ++ <configuration> ++ <instructions> ++ <Bundle-SymbolicName>org.apache.camel.camel-metrics</Bundle-SymbolicName> ++ <Export-Service>org.apache.camel.spi.ComponentResolver;component=metrics</Export-Service> ++ </instructions> ++ </configuration> ++ </plugin> ++ ++ </plugins> ++ </build> ++ ++</project> http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/AbstractMetricsEndpoint.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/AbstractMetricsEndpoint.java index 0000000,0000000..d8c8af7 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/AbstractMetricsEndpoint.java @@@ -1,0 -1,0 +1,37 @@@ ++package org.apache.camel.metrics; ++ ++import org.apache.camel.Consumer; ++import org.apache.camel.Processor; ++import org.apache.camel.RuntimeCamelException; ++import org.apache.camel.impl.DefaultEndpoint; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++public abstract class AbstractMetricsEndpoint extends DefaultEndpoint { ++ ++ protected final MetricRegistry registry; ++ protected final String metricsName; ++ ++ public AbstractMetricsEndpoint(MetricRegistry registry, String metricsName) { ++ this.registry = registry; ++ this.metricsName = metricsName; ++ } ++ ++ @Override ++ public Consumer createConsumer(Processor processor) throws Exception { ++ throw new RuntimeCamelException("Cannot consume from " + getClass().getSimpleName() + ": " + getEndpointUri()); ++ } ++ ++ @Override ++ public boolean isSingleton() { ++ return false; ++ } ++ ++ public MetricRegistry getRegistry() { ++ return registry; ++ } ++ ++ public String getMetricsName() { ++ return metricsName; ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/AbstractMetricsProducer.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/AbstractMetricsProducer.java index 0000000,0000000..24149af new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/AbstractMetricsProducer.java @@@ -1,0 -1,0 +1,59 @@@ ++package org.apache.camel.metrics; ++ ++import static org.apache.camel.metrics.MetricsComponent.HEADER_METRIC_NAME; ++import static org.apache.camel.metrics.MetricsComponent.HEADER_PERFIX; ++ ++import org.apache.camel.Exchange; ++import org.apache.camel.Message; ++import org.apache.camel.impl.DefaultProducer; ++import org.apache.camel.util.ObjectHelper; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++public abstract class AbstractMetricsProducer<T extends AbstractMetricsEndpoint> extends DefaultProducer { ++ ++ public static final String HEADER_PATTERN = HEADER_PERFIX + "*"; ++ private static final Logger LOG = LoggerFactory.getLogger(AbstractMetricsProducer.class); ++ ++ public AbstractMetricsProducer(T endpoint) { ++ super(endpoint); ++ } ++ ++ @Override ++ public void process(Exchange exchange) throws Exception { ++ @SuppressWarnings("unchecked") ++ T endpoint = (T) getEndpoint(); ++ Message in = exchange.getIn(); ++ String defaultMetricsName = endpoint.getMetricsName(); ++ String finalMetricsName = getMetricsName(in, defaultMetricsName); ++ MetricRegistry registry = endpoint.getRegistry(); ++ try { ++ doProcess(exchange, endpoint, registry, finalMetricsName); ++ } ++ catch (Exception e) { ++ LOG.warn("Failed to produce metrics for {} in {} - {}", finalMetricsName, getClass().getSimpleName(), e.getMessage()); ++ } ++ clearMetricsHeaders(in); ++ } ++ ++ protected abstract void doProcess(Exchange exchange, T endpoint, MetricRegistry registry, String metricsName) throws Exception; ++ ++ public String getMetricsName(Message in, String defaultValue) { ++ return getStringHeader(in, HEADER_METRIC_NAME, defaultValue); ++ } ++ ++ public String getStringHeader(Message in, String header, String defaultValue) { ++ String headerValue = in.getHeader(header, String.class); ++ return ObjectHelper.isNotEmpty(headerValue) ? headerValue : defaultValue; ++ } ++ ++ public Long getLongHeader(Message in, String header, Long defaultValue) { ++ return in.getHeader(header, defaultValue, Long.class); ++ } ++ ++ protected boolean clearMetricsHeaders(Message in) { ++ return in.removeHeaders(HEADER_PATTERN); ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/MetricsComponent.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/MetricsComponent.java index 0000000,0000000..c803e4f new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/MetricsComponent.java @@@ -1,0 -1,0 +1,121 @@@ ++package org.apache.camel.metrics; ++ ++import java.util.Map; ++import java.util.concurrent.TimeUnit; ++ ++import org.apache.camel.Endpoint; ++import org.apache.camel.RuntimeCamelException; ++import org.apache.camel.impl.DefaultComponent; ++import org.apache.camel.metrics.counter.CounterEndpoint; ++import org.apache.camel.metrics.histogram.HistogramEndpoint; ++import org.apache.camel.metrics.meter.MeterEndpoint; ++import org.apache.camel.metrics.timer.TimerEndpoint; ++import org.apache.camel.spi.Registry; ++import org.apache.camel.util.ObjectHelper; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++ ++import com.codahale.metrics.MetricRegistry; ++import com.codahale.metrics.Slf4jReporter; ++ ++/** ++ * Represents the component that manages {@link MetricsEndpoint}. ++ */ ++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_PERFIX = "CamelMetrics"; ++ public static final String HEADER_METRIC_NAME = HEADER_PERFIX + "Name"; ++ public static final String HEADER_COUNTER_INCREMENT = HEADER_PERFIX + "CounterIncrement"; ++ 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); ++ ++ private MetricRegistry metricRegistry; ++ ++ @Override ++ protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { ++ if (metricRegistry == null) { ++ Registry camelRegistry = getCamelContext().getRegistry(); ++ metricRegistry = getOrCreateMetricRegistry(camelRegistry, METRIC_REGISTRY_NAME); ++ } ++ String metricsName = getMetricsName(remaining); ++ MetricsType metricsType = getMetricsType(remaining); ++ LOG.info("Metrics type: {}; name: {}", metricsType, metricsName); ++ Endpoint endpoint = createNewEndpoint(metricRegistry, metricsType, metricsName); ++ setProperties(endpoint, parameters); ++ return endpoint; ++ } ++ ++ String getMetricsName(String remaining) { ++ String name = ObjectHelper.after(remaining, ":"); ++ return name == null ? remaining : name; ++ } ++ ++ Endpoint createNewEndpoint(MetricRegistry registry, MetricsType type, String metricsName) { ++ Endpoint endpoint; ++ switch (type) { ++ case COUNTER: ++ endpoint = new CounterEndpoint(registry, metricsName); ++ break; ++ case METER: ++ endpoint = new MeterEndpoint(registry, metricsName); ++ break; ++ case HISTOGRAM: ++ endpoint = new HistogramEndpoint(registry, metricsName); ++ break; ++ case TIMER: ++ endpoint = new TimerEndpoint(registry, metricsName); ++ break; ++ default: ++ throw new RuntimeCamelException("Metrics type \"" + type.toString() + "\" not supported"); ++ } ++ return endpoint; ++ } ++ ++ MetricsType getMetricsType(String remaining) { ++ String name = ObjectHelper.before(remaining, ":"); ++ MetricsType type; ++ if (name == null) { ++ type = DEFAULT_METRICS_TYPE; ++ } ++ else { ++ type = MetricsType.getByName(name); ++ } ++ if (type == null) { ++ throw new RuntimeCamelException("Unknow metrics type \"" + name + "\""); ++ } ++ return type; ++ } ++ ++ MetricRegistry getOrCreateMetricRegistry(Registry camelRegistry, String registryName) { ++ LOG.debug("Looking up MetricRegistry from Camel Registry for name \"{}\"", registryName); ++ MetricRegistry result = getMetricRegistryFromCamelRegistry(camelRegistry, registryName); ++ if (result == null) { ++ LOG.debug("MetricRegistry not found from Camel Registry for name \"{}\"", registryName); ++ LOG.info("Creating new default MetricRegistry"); ++ result = createMetricRegistry(); ++ } ++ return result; ++ } ++ ++ MetricRegistry getMetricRegistryFromCamelRegistry(Registry camelRegistry, String registryName) { ++ return camelRegistry.lookupByNameAndType(registryName, MetricRegistry.class); ++ } ++ ++ MetricRegistry createMetricRegistry() { ++ MetricRegistry registry = new MetricRegistry(); ++ final Slf4jReporter reporter = Slf4jReporter.forRegistry(registry) ++ .outputTo(LOG) ++ .convertRatesTo(TimeUnit.SECONDS) ++ .convertDurationsTo(TimeUnit.MILLISECONDS) ++ .build(); ++ reporter.start(DEFAULT_REPORTING_INTERVAL_SECONDS, TimeUnit.SECONDS); ++ return registry; ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/MetricsType.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/MetricsType.java index 0000000,0000000..f602647 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/MetricsType.java @@@ -1,0 -1,0 +1,37 @@@ ++package org.apache.camel.metrics; ++ ++import java.util.EnumSet; ++import java.util.HashMap; ++import java.util.Map; ++ ++public enum MetricsType { ++ ++ GAUGE("gauge"), ++ COUNTER("counter"), ++ HISTOGRAM("histogram"), ++ METER("meter"), ++ TIMER("timer"), ; ++ ++ private static final Map<String, MetricsType> map = new HashMap<String, MetricsType>(); ++ ++ private final String name; ++ ++ static { ++ for (MetricsType type : EnumSet.allOf(MetricsType.class)) { ++ map.put(type.name, type); ++ } ++ } ++ ++ private MetricsType(String name) { ++ this.name = name; ++ } ++ ++ @Override ++ public String toString() { ++ return name; ++ } ++ ++ public static MetricsType getByName(String name) { ++ return map.get(name); ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/counter/CounterEndpoint.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/counter/CounterEndpoint.java index 0000000,0000000..8d0b34e new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/counter/CounterEndpoint.java @@@ -1,0 -1,0 +1,50 @@@ ++package org.apache.camel.metrics.counter; ++ ++import org.apache.camel.Producer; ++import org.apache.camel.metrics.AbstractMetricsEndpoint; ++import org.apache.camel.spi.UriEndpoint; ++import org.apache.camel.spi.UriParam; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++@UriEndpoint(scheme = "metrics:counter") ++public class CounterEndpoint extends AbstractMetricsEndpoint { ++ ++ public static final String ENDPOINT_URI = "metrics:counter"; ++ ++ @UriParam ++ private Long increment; ++ ++ @UriParam ++ private Long decrement; ++ ++ public CounterEndpoint(MetricRegistry registry, String metricsName) { ++ super(registry, metricsName); ++ } ++ ++ @Override ++ public Producer createProducer() throws Exception { ++ return new CounterProducer(this); ++ } ++ ++ public Long getIncrement() { ++ return increment; ++ } ++ ++ public void setIncrement(Long increment) { ++ this.increment = increment; ++ } ++ ++ public Long getDecrement() { ++ return decrement; ++ } ++ ++ public void setDecrement(Long decrement) { ++ this.decrement = decrement; ++ } ++ ++ @Override ++ protected String createEndpointUri() { ++ return ENDPOINT_URI; ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/counter/CounterProducer.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/counter/CounterProducer.java index 0000000,0000000..2d9431c new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/counter/CounterProducer.java @@@ -1,0 -1,0 +1,37 @@@ ++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.Exchange; ++import org.apache.camel.Message; ++import org.apache.camel.metrics.AbstractMetricsProducer; ++ ++import com.codahale.metrics.Counter; ++import com.codahale.metrics.MetricRegistry; ++ ++public class CounterProducer extends AbstractMetricsProducer<CounterEndpoint> { ++ ++ public CounterProducer(CounterEndpoint endpoint) { ++ super(endpoint); ++ } ++ ++ @Override ++ protected void doProcess(Exchange exchange, CounterEndpoint endpoint, MetricRegistry registry, String metricsName) throws Exception { ++ Message in = exchange.getIn(); ++ Counter counter = registry.counter(metricsName); ++ Long increment = endpoint.getIncrement(); ++ Long decrement = endpoint.getDecrement(); ++ Long finalIncrement = getLongHeader(in, HEADER_COUNTER_INCREMENT, increment); ++ Long finalDecrement = getLongHeader(in, HEADER_COUNTER_DECREMENT, decrement); ++ if (finalIncrement != null) { ++ counter.inc(finalIncrement); ++ } ++ else if (finalDecrement != null) { ++ counter.dec(finalDecrement); ++ } ++ else { ++ counter.inc(); ++ } ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/histogram/HistogramEndpoint.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/histogram/HistogramEndpoint.java index 0000000,0000000..8024289 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/histogram/HistogramEndpoint.java @@@ -1,0 -1,0 +1,39 @@@ ++package org.apache.camel.metrics.histogram; ++ ++import org.apache.camel.Producer; ++import org.apache.camel.metrics.AbstractMetricsEndpoint; ++import org.apache.camel.spi.UriEndpoint; ++import org.apache.camel.spi.UriParam; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++@UriEndpoint(scheme = "metrics:histogram") ++public class HistogramEndpoint extends AbstractMetricsEndpoint { ++ ++ public static String ENDPOINT_URI = "metrics:histogram"; ++ ++ @UriParam ++ private Long value; ++ ++ public HistogramEndpoint(MetricRegistry registry, String metricsName) { ++ super(registry, metricsName); ++ } ++ ++ @Override ++ public Producer createProducer() throws Exception { ++ return new HistogramProducer(this); ++ } ++ ++ public Long getValue() { ++ return value; ++ } ++ ++ public void setValue(Long value) { ++ this.value = value; ++ } ++ ++ @Override ++ protected String createEndpointUri() { ++ return ENDPOINT_URI; ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/histogram/HistogramProducer.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/histogram/HistogramProducer.java index 0000000,0000000..46c586d new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/histogram/HistogramProducer.java @@@ -1,0 -1,0 +1,35 @@@ ++package org.apache.camel.metrics.histogram; ++ ++import static org.apache.camel.metrics.MetricsComponent.HEADER_HISTOGRAM_VALUE; ++ ++import org.apache.camel.Exchange; ++import org.apache.camel.Message; ++import org.apache.camel.metrics.AbstractMetricsProducer; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++ ++import com.codahale.metrics.Histogram; ++import com.codahale.metrics.MetricRegistry; ++ ++public class HistogramProducer extends AbstractMetricsProducer<HistogramEndpoint> { ++ ++ private static final Logger LOG = LoggerFactory.getLogger(HistogramProducer.class); ++ ++ public HistogramProducer(HistogramEndpoint endpoint) { ++ super(endpoint); ++ } ++ ++ @Override ++ protected void doProcess(Exchange exchange, HistogramEndpoint endpoint, MetricRegistry registry, String metricsName) throws Exception { ++ Message in = exchange.getIn(); ++ Histogram histogram = registry.histogram(metricsName); ++ Long value = endpoint.getValue(); ++ Long finalValue = getLongHeader(in, HEADER_HISTOGRAM_VALUE, value); ++ if (finalValue != null) { ++ histogram.update(finalValue); ++ } ++ else { ++ LOG.warn("Cannot update histogram \"{}\" with null value", metricsName); ++ } ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/meter/MeterEndpoint.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/meter/MeterEndpoint.java index 0000000,0000000..d0b609e new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/meter/MeterEndpoint.java @@@ -1,0 -1,0 +1,39 @@@ ++package org.apache.camel.metrics.meter; ++ ++import org.apache.camel.Producer; ++import org.apache.camel.metrics.AbstractMetricsEndpoint; ++import org.apache.camel.spi.UriEndpoint; ++import org.apache.camel.spi.UriParam; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++@UriEndpoint(scheme = "metrics:meter") ++public class MeterEndpoint extends AbstractMetricsEndpoint { ++ ++ public static final String ENDPOINT_URI = "metrics:meter"; ++ ++ @UriParam ++ private Long mark; ++ ++ public MeterEndpoint(MetricRegistry registry, String metricsName) { ++ super(registry, metricsName); ++ } ++ ++ @Override ++ public Producer createProducer() throws Exception { ++ return new MeterProducer(this); ++ } ++ ++ public Long getMark() { ++ return mark; ++ } ++ ++ public void setMark(Long mark) { ++ this.mark = mark; ++ } ++ ++ @Override ++ protected String createEndpointUri() { ++ return ENDPOINT_URI; ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/meter/MeterProducer.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/meter/MeterProducer.java index 0000000,0000000..7622112 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/meter/MeterProducer.java @@@ -1,0 -1,0 +1,31 @@@ ++package org.apache.camel.metrics.meter; ++ ++import static org.apache.camel.metrics.MetricsComponent.HEADER_METER_MARK; ++ ++import org.apache.camel.Exchange; ++import org.apache.camel.Message; ++import org.apache.camel.metrics.AbstractMetricsProducer; ++ ++import com.codahale.metrics.Meter; ++import com.codahale.metrics.MetricRegistry; ++ ++public class MeterProducer extends AbstractMetricsProducer<MeterEndpoint> { ++ ++ public MeterProducer(MeterEndpoint endpoint) { ++ super(endpoint); ++ } ++ ++ @Override ++ protected void doProcess(Exchange exchange, MeterEndpoint endpoint, MetricRegistry registry, String metricsName) throws Exception { ++ Message in = exchange.getIn(); ++ Meter meter = registry.meter(metricsName); ++ Long mark = endpoint.getMark(); ++ Long finalMark = getLongHeader(in, HEADER_METER_MARK, mark); ++ if (finalMark == null) { ++ meter.mark(); ++ } ++ else { ++ meter.mark(finalMark); ++ } ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/timer/TimerEndpoint.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/timer/TimerEndpoint.java index 0000000,0000000..6de4e32 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/timer/TimerEndpoint.java @@@ -1,0 -1,0 +1,44 @@@ ++package org.apache.camel.metrics.timer; ++ ++import org.apache.camel.Producer; ++import org.apache.camel.metrics.AbstractMetricsEndpoint; ++import org.apache.camel.spi.UriEndpoint; ++import org.apache.camel.spi.UriParam; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++@UriEndpoint(scheme = "metrics:timer") ++public class TimerEndpoint extends AbstractMetricsEndpoint { ++ ++ public static final String ENDPOINT_URI = "metrics:timer"; ++ ++ public enum TimerAction { ++ start, ++ stop; ++ } ++ ++ @UriParam ++ private TimerAction action; ++ ++ public TimerEndpoint(MetricRegistry registry, String metricsName) { ++ super(registry, metricsName); ++ } ++ ++ @Override ++ public Producer createProducer() throws Exception { ++ return new TimerProducer(this); ++ } ++ ++ public TimerAction getAction() { ++ return action; ++ } ++ ++ public void setAction(TimerAction action) { ++ this.action = action; ++ } ++ ++ @Override ++ protected String createEndpointUri() { ++ return ENDPOINT_URI; ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/java/org/apache/camel/metrics/timer/TimerProducer.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/java/org/apache/camel/metrics/timer/TimerProducer.java index 0000000,0000000..9586bbd new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/java/org/apache/camel/metrics/timer/TimerProducer.java @@@ -1,0 -1,0 +1,75 @@@ ++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; ++import org.slf4j.LoggerFactory; ++ ++import com.codahale.metrics.MetricRegistry; ++import com.codahale.metrics.Timer; ++ ++public class TimerProducer extends AbstractMetricsProducer<TimerEndpoint> { ++ ++ private static final Logger LOG = LoggerFactory.getLogger(TimerProducer.class); ++ ++ public TimerProducer(TimerEndpoint endpoint) { ++ super(endpoint); ++ } ++ ++ @Override ++ protected void doProcess(Exchange exchange, TimerEndpoint endpoint, MetricRegistry registry, String metricsName) throws Exception { ++ Message in = exchange.getIn(); ++ TimerAction action = endpoint.getAction(); ++ TimerAction finalAction = in.getHeader(HEADER_TIMER_ACTION, action, TimerAction.class); ++ if (finalAction == TimerAction.start) { ++ handleStart(exchange, registry, metricsName); ++ } ++ else if (finalAction == TimerAction.stop) { ++ handleStop(exchange, registry, metricsName); ++ } ++ else { ++ LOG.warn("No action provided for timer \"{}\"", metricsName); ++ } ++ } ++ ++ void handleStart(Exchange exchange, MetricRegistry registry, String metricsName) { ++ String propertyName = getPropertyName(metricsName); ++ Timer.Context context = getTimerContextFromExchange(exchange, propertyName); ++ if (context == null) { ++ Timer timer = registry.timer(metricsName); ++ context = timer.time(); ++ exchange.setProperty(propertyName, context); ++ } ++ else { ++ LOG.warn("Timer \"{}\" already running", metricsName); ++ } ++ } ++ ++ void handleStop(Exchange exchange, MetricRegistry registry, String metricsName) { ++ String propertyName = getPropertyName(metricsName); ++ Timer.Context context = getTimerContextFromExchange(exchange, propertyName); ++ if (context != null) { ++ context.stop(); ++ exchange.removeProperty(propertyName); ++ } ++ else { ++ LOG.warn("Timer \"{}\" not found", metricsName); ++ } ++ } ++ ++ String getPropertyName(String metricsName) { ++ return new StringBuilder(ENDPOINT_URI) ++ .append(":") ++ .append(metricsName) ++ .toString(); ++ } ++ ++ Timer.Context getTimerContextFromExchange(Exchange exchange, String propertyName) { ++ return exchange.getProperty(propertyName, Timer.Context.class); ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/main/resources/META-INF/services/org/apache/camel/component/metrics ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/main/resources/META-INF/services/org/apache/camel/component/metrics index 0000000,0000000..debbe31 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/main/resources/META-INF/services/org/apache/camel/component/metrics @@@ -1,0 -1,0 +1,1 @@@ ++class=org.apache.camel.metrics.MetricsComponent http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/test/java/org/apache/camel/metrics/AbstractMetricsEndpointTest.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/test/java/org/apache/camel/metrics/AbstractMetricsEndpointTest.java index 0000000,0000000..1a7543e new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/metrics/AbstractMetricsEndpointTest.java @@@ -1,0 -1,0 +1,96 @@@ ++package org.apache.camel.metrics; ++ ++import static org.hamcrest.CoreMatchers.is; ++import static org.hamcrest.MatcherAssert.assertThat; ++import static org.mockito.Mockito.when; ++ ++import org.apache.camel.Exchange; ++import org.apache.camel.Message; ++import org.apache.camel.Processor; ++import org.apache.camel.Producer; ++import org.apache.camel.RuntimeCamelException; ++import org.junit.After; ++import org.junit.Before; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.mockito.InOrder; ++import org.mockito.Mock; ++import org.mockito.Mockito; ++import org.mockito.runners.MockitoJUnitRunner; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++@RunWith(MockitoJUnitRunner.class) ++public class AbstractMetricsEndpointTest { ++ ++ private static final String METRICS_NAME = "metrics.name"; ++ private static final String HEADER = "header"; ++ private static final String STRING_VALUE = "string-value"; ++ private static final String DEFAULT_STRING_VALUE = "default-value"; ++ private static final Long LONG_VALUE = System.currentTimeMillis(); ++ private static final Long DEFAULT_LONG_VALUE = -10101L; ++ ++ @Mock ++ private MetricRegistry registry; ++ ++ @Mock ++ private Processor processor; ++ ++ @Mock ++ private Exchange exchange; ++ ++ @Mock ++ private Message in; ++ ++ private AbstractMetricsEndpoint endpoint; ++ ++ private InOrder inOrder; ++ ++ @Before ++ public void setUp() throws Exception { ++ endpoint = new AbstractMetricsEndpoint(registry, METRICS_NAME) { ++ @Override ++ public Producer createProducer() throws Exception { ++ return null; ++ } ++ ++ @Override ++ protected String createEndpointUri() { ++ return "not real endpoint"; ++ } ++ }; ++ inOrder = Mockito.inOrder(registry, processor, exchange, in); ++ when(exchange.getIn()).thenReturn(in); ++ } ++ ++ @After ++ public void tearDown() throws Exception { ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testAbstractMetricsEndpoint() throws Exception { ++ assertThat(endpoint.getMetricsName(), is(METRICS_NAME)); ++ assertThat(endpoint.getRegistry(), is(registry)); ++ } ++ ++ @Test(expected = RuntimeCamelException.class) ++ public void testCreateConsumer() throws Exception { ++ endpoint.createConsumer(processor); ++ } ++ ++ @Test ++ public void testIsSingleton() throws Exception { ++ assertThat(endpoint.isSingleton(), is(false)); ++ } ++ ++ @Test ++ public void testGetRegistry() throws Exception { ++ assertThat(endpoint.getRegistry(), is(registry)); ++ } ++ ++ @Test ++ public void testGetMetricsName() throws Exception { ++ assertThat(endpoint.getMetricsName(), is(METRICS_NAME)); ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/test/java/org/apache/camel/metrics/AbstractMetricsProducerTest.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/test/java/org/apache/camel/metrics/AbstractMetricsProducerTest.java index 0000000,0000000..3435247 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/metrics/AbstractMetricsProducerTest.java @@@ -1,0 -1,0 +1,172 @@@ ++package org.apache.camel.metrics; ++ ++import static org.apache.camel.metrics.AbstractMetricsProducer.HEADER_PATTERN; ++import static org.apache.camel.metrics.MetricsComponent.HEADER_HISTOGRAM_VALUE; ++import static org.apache.camel.metrics.MetricsComponent.HEADER_METRIC_NAME; ++import static org.hamcrest.CoreMatchers.is; ++import static org.hamcrest.MatcherAssert.assertThat; ++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.impl.DefaultMessage; ++import org.junit.Before; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.mockito.InOrder; ++import org.mockito.Mock; ++import org.mockito.Mockito; ++import org.mockito.runners.MockitoJUnitRunner; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++@RunWith(MockitoJUnitRunner.class) ++public class AbstractMetricsProducerTest { ++ ++ public static final String METRIC_NAME = "a metric"; ++ ++ @Mock ++ private AbstractMetricsEndpoint endpoint; ++ ++ @Mock ++ private Exchange exchange; ++ ++ @Mock ++ private Message in; ++ ++ @Mock ++ private MetricRegistry registry; ++ ++ private AbstractMetricsProducer<AbstractMetricsEndpoint> okProducer; ++ ++ private AbstractMetricsProducer<AbstractMetricsEndpoint> failProducer; ++ ++ private InOrder inOrder; ++ ++ @Before ++ public void setUp() throws Exception { ++ okProducer = new AbstractMetricsProducer<AbstractMetricsEndpoint>(endpoint) { ++ @Override ++ protected void doProcess(Exchange exchange, AbstractMetricsEndpoint endpoint, MetricRegistry registry, String metricsName) throws Exception { ++ } ++ }; ++ failProducer = new AbstractMetricsProducer<AbstractMetricsEndpoint>(endpoint) { ++ ++ @Override ++ protected void doProcess(Exchange exchange, AbstractMetricsEndpoint endpoint, MetricRegistry registry, String metricsName) throws Exception { ++ throw new Exception("Muchos problemos"); ++ } ++ }; ++ inOrder = Mockito.inOrder(endpoint, exchange, in, registry); ++ when(exchange.getIn()).thenReturn(in); ++ when(endpoint.getMetricsName()).thenReturn(METRIC_NAME); ++ when(endpoint.getRegistry()).thenReturn(registry); ++ } ++ ++ @Test ++ public void testDoProcess() throws Exception { ++ when(in.getHeader(HEADER_METRIC_NAME, String.class)).thenReturn(null); ++ when(in.removeHeaders(HEADER_PATTERN)).thenReturn(true); ++ okProducer.process(exchange); ++ inOrder.verify(exchange, times(1)).getIn(); ++ inOrder.verify(endpoint, times(1)).getMetricsName(); ++ inOrder.verify(in, times(1)).getHeader(HEADER_METRIC_NAME, String.class); ++ inOrder.verify(endpoint, times(1)).getRegistry(); ++ inOrder.verify(in, times(1)).removeHeaders(HEADER_PATTERN); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testDoProcessWithException() throws Exception { ++ when(in.getHeader(HEADER_METRIC_NAME, String.class)).thenReturn(null); ++ when(in.removeHeaders(HEADER_PATTERN)).thenReturn(true); ++ failProducer.process(exchange); ++ inOrder.verify(exchange, times(1)).getIn(); ++ inOrder.verify(endpoint, times(1)).getMetricsName(); ++ inOrder.verify(in, times(1)).getHeader(HEADER_METRIC_NAME, String.class); ++ inOrder.verify(endpoint, times(1)).getRegistry(); ++ inOrder.verify(in, times(1)).removeHeaders(HEADER_PATTERN); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetMetricsName() throws Exception { ++ when(in.getHeader(HEADER_METRIC_NAME, String.class)).thenReturn("A"); ++ assertThat(okProducer.getMetricsName(in, "value"), is("A")); ++ inOrder.verify(in, times(1)).getHeader(HEADER_METRIC_NAME, String.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetMetricsNameNotSet() throws Exception { ++ when(in.getHeader(HEADER_METRIC_NAME, String.class)).thenReturn(null); ++ assertThat(okProducer.getMetricsName(in, "name"), is("name")); ++ inOrder.verify(in, times(1)).getHeader(HEADER_METRIC_NAME, String.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetStringHeader() throws Exception { ++ when(in.getHeader(HEADER_METRIC_NAME, String.class)).thenReturn("A"); ++ assertThat(okProducer.getStringHeader(in, HEADER_METRIC_NAME, "value"), is("A")); ++ inOrder.verify(in, times(1)).getHeader(HEADER_METRIC_NAME, String.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetStringHeaderWithNullValue() throws Exception { ++ when(in.getHeader(HEADER_METRIC_NAME, String.class)).thenReturn(null); ++ assertThat(okProducer.getStringHeader(in, HEADER_METRIC_NAME, "value"), is("value")); ++ inOrder.verify(in, times(1)).getHeader(HEADER_METRIC_NAME, String.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetStringHeaderWithWhiteSpaces() throws Exception { ++ when(in.getHeader(HEADER_METRIC_NAME, String.class)).thenReturn(" "); ++ assertThat(okProducer.getStringHeader(in, HEADER_METRIC_NAME, "value"), is("value")); ++ inOrder.verify(in, times(1)).getHeader(HEADER_METRIC_NAME, String.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetStringHeaderWithEmptySrting() throws Exception { ++ when(in.getHeader(HEADER_METRIC_NAME, String.class)).thenReturn(""); ++ assertThat(okProducer.getStringHeader(in, HEADER_METRIC_NAME, "value"), is("value")); ++ inOrder.verify(in, times(1)).getHeader(HEADER_METRIC_NAME, String.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetLongHeader() throws Exception { ++ when(in.getHeader(HEADER_HISTOGRAM_VALUE, 19L, Long.class)).thenReturn(201L); ++ assertThat(okProducer.getLongHeader(in, HEADER_HISTOGRAM_VALUE, 19L), is(201L)); ++ inOrder.verify(in, times(1)).getHeader(HEADER_HISTOGRAM_VALUE, 19L, Long.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testClearMetricsHeaders() throws Exception { ++ when(in.removeHeaders(HEADER_PATTERN)).thenReturn(true); ++ assertThat(okProducer.clearMetricsHeaders(in), is(true)); ++ inOrder.verify(in, times(1)).removeHeaders(HEADER_PATTERN); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testClearRealHeaders() throws Exception { ++ Message msg = new DefaultMessage(); ++ Object val = new Object(); ++ msg.setHeader(HEADER_HISTOGRAM_VALUE, 109L); ++ msg.setHeader(HEADER_METRIC_NAME, "the metric"); ++ msg.setHeader("notRemoved", val); ++ assertThat(msg.getHeaders().size(), is(3)); ++ assertThat(msg.getHeader(HEADER_HISTOGRAM_VALUE, Long.class), is(109L)); ++ assertThat(msg.getHeader(HEADER_METRIC_NAME, String.class), is("the metric")); ++ assertThat(msg.getHeader("notRemoved"), is(val)); ++ okProducer.clearMetricsHeaders(msg); ++ assertThat(msg.getHeaders().size(), is(1)); ++ assertThat(msg.getHeader("notRemoved"), is(val)); ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricComponentSpringTest.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricComponentSpringTest.java index 0000000,0000000..a6590c5 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricComponentSpringTest.java @@@ -1,0 -1,0 +1,77 @@@ ++package org.apache.camel.metrics; ++ ++import static org.mockito.Mockito.times; ++import static org.mockito.Mockito.when; ++ ++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.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.Test; ++import org.junit.runner.RunWith; ++import org.mockito.InOrder; ++import org.mockito.Mockito; ++import org.springframework.context.annotation.Bean; ++import org.springframework.context.annotation.Configuration; ++import org.springframework.test.context.ContextConfiguration; ++ ++import com.codahale.metrics.Counter; ++import com.codahale.metrics.MetricRegistry; ++ ++@RunWith(CamelSpringJUnit4ClassRunner.class) ++@ContextConfiguration( ++ classes = { MetricComponentSpringTest.TestConfig.class }, ++ loader = CamelSpringDelegatingTestContextLoader.class) ++@MockEndpoints ++public class MetricComponentSpringTest { ++ ++ @EndpointInject(uri = "mock:out") ++ private MockEndpoint endpoint; ++ ++ @Produce(uri = "direct:in") ++ private ProducerTemplate producer; ++ ++ @Configuration ++ public static class TestConfig extends SingleRouteCamelConfiguration { ++ ++ @Bean ++ @Override ++ public RouteBuilder route() { ++ return new RouteBuilder() { ++ ++ @Override ++ public void configure() throws Exception { ++ from("direct:in") ++ .to("metrics:counter:A?increment=512") ++ .to("mock:out"); ++ } ++ }; ++ } ++ ++ @Bean(name = MetricsComponent.METRIC_REGISTRY_NAME) ++ public MetricRegistry getMetricRegistry() { ++ return Mockito.mock(MetricRegistry.class); ++ } ++ } ++ ++ @Test ++ public void testMetricsRegistryFromCamelRegistry() 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("A")).thenReturn(mockCounter); ++ ++ endpoint.expectedMessageCount(1); ++ producer.sendBody(new Object()); ++ endpoint.assertIsSatisfied(); ++ inOrder.verify(mockRegistry, times(1)).counter("A"); ++ inOrder.verify(mockCounter, times(1)).inc(512L); ++ inOrder.verifyNoMoreInteractions(); ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricsComponentRouteTest.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricsComponentRouteTest.java index 0000000,0000000..4ef44f3 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricsComponentRouteTest.java @@@ -1,0 -1,0 +1,99 @@@ ++package org.apache.camel.metrics; ++ ++import static org.apache.camel.metrics.MetricsComponent.HEADER_HISTOGRAM_VALUE; ++import static org.apache.camel.metrics.MetricsComponent.HEADER_METRIC_NAME; ++import static org.apache.camel.metrics.MetricsComponent.HEADER_PERFIX; ++ ++import java.util.Date; ++import java.util.HashMap; ++import java.util.Map; ++ ++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.test.junit4.CamelTestSupport; ++import org.junit.Test; ++ ++public class MetricsComponentRouteTest extends CamelTestSupport { ++ ++ @Produce(uri = "direct:start-1") ++ protected ProducerTemplate template1; ++ ++ @Produce(uri = "direct:start-2") ++ protected ProducerTemplate template2; ++ ++ @Test ++ public void testMetrics() throws Exception { ++ MockEndpoint mock = getMockEndpoint("mock:result"); ++ mock.expectedMinimumMessageCount(1); ++ template1.sendBody(new Object()); ++ assertMockEndpointsSatisfied(); ++ } ++ ++ @Test ++ public void testMessageContentDelivery() throws Exception { ++ MockEndpoint mock = getMockEndpoint("mock:result"); ++ String body = "Message Body"; ++ String header1 = "Header 1"; ++ String header2 = "Header 2"; ++ Object value1 = new Date(); ++ Object value2 = System.currentTimeMillis(); ++ mock.expectedBodiesReceived(body); ++ mock.expectedHeaderReceived(header1, value1); ++ mock.expectedHeaderReceived(header2, value2); ++ Map<String, Object> headers = new HashMap<String, Object>(); ++ headers.put(header1, value1); ++ headers.put(header2, value2); ++ template1.sendBodyAndHeaders(body, headers); ++ assertMockEndpointsSatisfied(); ++ } ++ ++ @Test ++ public void testHeaderRemoval() throws Exception { ++ MockEndpoint mock = getMockEndpoint("mock:result"); ++ Object body = new Object(); ++ Date now = new Date(); ++ ++ mock.expectedBodiesReceived(body); ++ mock.expectedHeaderReceived("." + HEADER_PERFIX, "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("date", now); ++ ++ template2.sendBodyAndHeaders(body, headers); ++ assertMockEndpointsSatisfied(); ++ } ++ ++ @Override ++ protected RouteBuilder createRouteBuilder() throws Exception { ++ return new RouteBuilder() { ++ @Override ++ public void configure() { ++ from("direct:start-1") ++ .to("metrics:timer:T?action=start") ++ .to("metrics:A") ++ .to("metrics:counter://B") ++ .to("metrics:counter:C?increment=19291") ++ .to("metrics:counter:C?decrement=19292") ++ .to("metrics:counter:C") ++ .to("metrics:meter:D") ++ .to("metrics:meter:D?mark=90001") ++ .to("metrics:histogram:E") ++ .to("metrics:timer:T") ++ .to("metrics:histogram:E?value=12000000031") ++ .to("metrics:timer:T?action=stop") ++ .to("mock:result"); ++ ++ from("direct:start-2") ++ .to("metrics:meter:F?mark=88") ++ .to("mock:result"); ++ } ++ }; ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricsComponentTest.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricsComponentTest.java index 0000000,0000000..74d91c2 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricsComponentTest.java @@@ -1,0 -1,0 +1,204 @@@ ++package org.apache.camel.metrics; ++ ++import static org.hamcrest.CoreMatchers.is; ++import static org.hamcrest.Matchers.instanceOf; ++import static org.hamcrest.Matchers.not; ++import static org.hamcrest.Matchers.notNullValue; ++import static org.junit.Assert.assertThat; ++import static org.mockito.Mockito.times; ++import static org.mockito.Mockito.when; ++ ++import java.util.EnumSet; ++import java.util.HashMap; ++import java.util.Map; ++ ++import org.apache.camel.CamelContext; ++import org.apache.camel.Endpoint; ++import org.apache.camel.RuntimeCamelException; ++import org.apache.camel.metrics.counter.CounterEndpoint; ++import org.apache.camel.metrics.histogram.HistogramEndpoint; ++import org.apache.camel.metrics.meter.MeterEndpoint; ++import org.apache.camel.metrics.timer.TimerEndpoint; ++import org.apache.camel.spi.Registry; ++import org.junit.Before; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.mockito.InOrder; ++import org.mockito.Mock; ++import org.mockito.Mockito; ++import org.mockito.runners.MockitoJUnitRunner; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++@RunWith(MockitoJUnitRunner.class) ++public class MetricsComponentTest { ++ ++ @Mock ++ private CamelContext camelContext; ++ ++ @Mock ++ private Registry camelRegistry; ++ ++ @Mock ++ private MetricRegistry metricRegistry; ++ ++ private InOrder inOrder; ++ ++ private MetricsComponent component; ++ ++ @Before ++ public void setUp() throws Exception { ++ component = new MetricsComponent(); ++ inOrder = Mockito.inOrder(camelContext, camelRegistry, metricRegistry); ++ ++ } ++ ++ @Test ++ public void testCreateEndpoint() throws Exception { ++ component.setCamelContext(camelContext); ++ when(camelContext.getRegistry()).thenReturn(camelRegistry); ++ when(camelRegistry.lookupByNameAndType(MetricsComponent.METRIC_REGISTRY_NAME, MetricRegistry.class)).thenReturn(metricRegistry); ++ Map<String, Object> params = new HashMap<String, Object>(); ++ Long value = System.currentTimeMillis(); ++ params.put("mark", value); ++ Endpoint result = component.createEndpoint("metrics:meter:long.meter", "meter:long.meter", params); ++ assertThat(result, is(notNullValue())); ++ assertThat(result, is(instanceOf(MeterEndpoint.class))); ++ MeterEndpoint me = (MeterEndpoint) result; ++ assertThat(me.getMark(), is(value)); ++ assertThat(me.getMetricsName(), is("long.meter")); ++ assertThat(me.getRegistry(), is(metricRegistry)); ++ inOrder.verify(camelContext, times(1)).getRegistry(); ++ inOrder.verify(camelRegistry, times(1)).lookupByNameAndType(MetricsComponent.METRIC_REGISTRY_NAME, MetricRegistry.class); ++ inOrder.verify(camelContext, times(1)).getTypeConverter(); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testCreateEndpoints() throws Exception { ++ component.setCamelContext(camelContext); ++ when(camelContext.getRegistry()).thenReturn(camelRegistry); ++ when(camelRegistry.lookupByNameAndType(MetricsComponent.METRIC_REGISTRY_NAME, MetricRegistry.class)).thenReturn(metricRegistry); ++ Map<String, Object> params = new HashMap<String, Object>(); ++ Long value = System.currentTimeMillis(); ++ params.put("mark", value); ++ Endpoint result = component.createEndpoint("metrics:meter:long.meter", "meter:long.meter", params); ++ assertThat(result, is(notNullValue())); ++ assertThat(result, is(instanceOf(MeterEndpoint.class))); ++ MeterEndpoint me = (MeterEndpoint) result; ++ assertThat(me.getMark(), is(value)); ++ assertThat(me.getMetricsName(), is("long.meter")); ++ assertThat(me.getRegistry(), is(metricRegistry)); ++ ++ params = new HashMap<String, Object>(); ++ params.put("increment", value + 1); ++ params.put("decrement", value - 1); ++ ++ result = component.createEndpoint("metrics:counter:long.counter", "counter:long.counter", params); ++ assertThat(result, is(notNullValue())); ++ assertThat(result, is(instanceOf(CounterEndpoint.class))); ++ CounterEndpoint ce = (CounterEndpoint) result; ++ assertThat(ce.getIncrement(), is(value + 1)); ++ assertThat(ce.getDecrement(), is(value - 1)); ++ assertThat(ce.getMetricsName(), is("long.counter")); ++ assertThat(ce.getRegistry(), is(metricRegistry)); ++ ++ inOrder.verify(camelContext, times(1)).getRegistry(); ++ inOrder.verify(camelRegistry, times(1)).lookupByNameAndType(MetricsComponent.METRIC_REGISTRY_NAME, MetricRegistry.class); ++ inOrder.verify(camelContext, times(2)).getTypeConverter(); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetMetricsName() throws Exception { ++ assertThat(component.getMetricsName("meter:metric-a"), is("metric-a")); ++ assertThat(component.getMetricsName("meter:metric-a:sub-b"), is("metric-a:sub-b")); ++ assertThat(component.getMetricsName("metric-a"), is("metric-a")); ++ assertThat(component.getMetricsName("//metric-a"), is("//metric-a")); ++ assertThat(component.getMetricsName("meter://metric-a"), is("//metric-a")); ++ } ++ ++ @Test ++ public void testCreateNewEndpointForCounter() throws Exception { ++ Endpoint endpoint = component.createNewEndpoint(metricRegistry, MetricsType.COUNTER, "a name"); ++ assertThat(endpoint, is(notNullValue())); ++ assertThat(endpoint, is(instanceOf(CounterEndpoint.class))); ++ } ++ ++ @Test ++ public void testCreateNewEndpointForMeter() throws Exception { ++ Endpoint endpoint = component.createNewEndpoint(metricRegistry, MetricsType.METER, "a name"); ++ assertThat(endpoint, is(notNullValue())); ++ assertThat(endpoint, is(instanceOf(MeterEndpoint.class))); ++ } ++ ++ @Test(expected = RuntimeCamelException.class) ++ public void testCreateNewEndpointForGauge() throws Exception { ++ component.createNewEndpoint(metricRegistry, MetricsType.GAUGE, "a name"); ++ } ++ ++ @Test ++ public void testCreateNewEndpointForHistogram() throws Exception { ++ Endpoint endpoint = component.createNewEndpoint(metricRegistry, MetricsType.HISTOGRAM, "a name"); ++ assertThat(endpoint, is(notNullValue())); ++ assertThat(endpoint, is(instanceOf(HistogramEndpoint.class))); ++ } ++ ++ @Test ++ public void testCreateNewEndpointForTimer() throws Exception { ++ Endpoint endpoint = component.createNewEndpoint(metricRegistry, MetricsType.TIMER, "a name"); ++ assertThat(endpoint, is(notNullValue())); ++ assertThat(endpoint, is(instanceOf(TimerEndpoint.class))); ++ } ++ ++ @Test ++ public void testGetMetricsType() throws Exception { ++ for (MetricsType type : EnumSet.allOf(MetricsType.class)) { ++ assertThat(component.getMetricsType(type.toString() + ":metrics-name"), is(type)); ++ } ++ } ++ ++ @Test ++ public void testGetMetricsTypeNotSet() throws Exception { ++ assertThat(component.getMetricsType("no-metrics-type"), is(MetricsComponent.DEFAULT_METRICS_TYPE)); ++ } ++ ++ @Test(expected = RuntimeCamelException.class) ++ public void testGetMetricsTypeNotFound() throws Exception { ++ component.getMetricsType("unknown-metrics:metrics-name"); ++ } ++ ++ @Test ++ public void testGetOrCreateMetricRegistryFoundInCamelRegistry() throws Exception { ++ when(camelRegistry.lookupByNameAndType("name", MetricRegistry.class)).thenReturn(metricRegistry); ++ MetricRegistry result = component.getOrCreateMetricRegistry(camelRegistry, "name"); ++ assertThat(result, is(metricRegistry)); ++ inOrder.verify(camelRegistry, times(1)).lookupByNameAndType("name", MetricRegistry.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetOrCreateMetricRegistryNotFoundInCamelRegistry() throws Exception { ++ when(camelRegistry.lookupByNameAndType("name", MetricRegistry.class)).thenReturn(null); ++ MetricRegistry result = component.getOrCreateMetricRegistry(camelRegistry, "name"); ++ assertThat(result, is(notNullValue())); ++ assertThat(result, is(not(metricRegistry))); ++ inOrder.verify(camelRegistry, times(1)).lookupByNameAndType("name", MetricRegistry.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testGetMetricRegistryFromCamelRegistry() throws Exception { ++ when(camelRegistry.lookupByNameAndType("name", MetricRegistry.class)).thenReturn(metricRegistry); ++ MetricRegistry result = component.getMetricRegistryFromCamelRegistry(camelRegistry, "name"); ++ assertThat(result, is(metricRegistry)); ++ inOrder.verify(camelRegistry, times(1)).lookupByNameAndType("name", MetricRegistry.class); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testCreateMetricRegistry() throws Exception { ++ MetricRegistry registry = component.createMetricRegistry(); ++ assertThat(registry, is(notNullValue())); ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricsTypeTest.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricsTypeTest.java index 0000000,0000000..2d0d28d new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/metrics/MetricsTypeTest.java @@@ -1,0 -1,0 +1,19 @@@ ++package org.apache.camel.metrics; ++ ++import static org.hamcrest.CoreMatchers.is; ++import static org.hamcrest.MatcherAssert.assertThat; ++ ++import java.util.EnumSet; ++ ++import org.junit.Test; ++ ++public class MetricsTypeTest { ++ ++ @Test ++ public void testGetByName() throws Exception { ++ for (MetricsType type : EnumSet.allOf(MetricsType.class)) { ++ MetricsType t = MetricsType.getByName(type.toString()); ++ assertThat(t, is(type)); ++ } ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/test/java/org/apache/camel/metrics/counter/CounterEndpointTest.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/test/java/org/apache/camel/metrics/counter/CounterEndpointTest.java index 0000000,0000000..8f713a2 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/metrics/counter/CounterEndpointTest.java @@@ -1,0 -1,0 +1,88 @@@ ++package org.apache.camel.metrics.counter; ++ ++import static org.hamcrest.CoreMatchers.is; ++import static org.hamcrest.MatcherAssert.assertThat; ++import static org.hamcrest.Matchers.instanceOf; ++import static org.hamcrest.Matchers.notNullValue; ++import static org.hamcrest.Matchers.nullValue; ++ ++import org.apache.camel.Producer; ++import org.junit.After; ++import org.junit.Before; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.mockito.InOrder; ++import org.mockito.Mock; ++import org.mockito.Mockito; ++import org.mockito.runners.MockitoJUnitRunner; ++ ++import com.codahale.metrics.MetricRegistry; ++ ++@RunWith(MockitoJUnitRunner.class) ++public class CounterEndpointTest { ++ ++ private static final String METRICS_NAME = "metrics.name"; ++ private static final Long VALUE = System.currentTimeMillis(); ++ ++ @Mock ++ private MetricRegistry registry; ++ ++ private CounterEndpoint endpoint; ++ ++ private InOrder inOrder; ++ ++ @Before ++ public void setUp() throws Exception { ++ endpoint = new CounterEndpoint(registry, METRICS_NAME); ++ inOrder = Mockito.inOrder(registry); ++ } ++ ++ @After ++ public void tearDown() { ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testCounterEndpoint() throws Exception { ++ assertThat(endpoint.getRegistry(), is(registry)); ++ assertThat(endpoint.getMetricsName(), is(METRICS_NAME)); ++ assertThat(endpoint.getIncrement(), is(nullValue())); ++ assertThat(endpoint.getDecrement(), is(nullValue())); ++ } ++ ++ @Test ++ public void testCreateProducer() throws Exception { ++ Producer producer = endpoint.createProducer(); ++ assertThat(producer, is(notNullValue())); ++ assertThat(producer, is(instanceOf(CounterProducer.class))); ++ } ++ ++ @Test ++ public void testGetIncrement() throws Exception { ++ assertThat(endpoint.getIncrement(), is(nullValue())); ++ } ++ ++ @Test ++ public void testSetIncrement() throws Exception { ++ assertThat(endpoint.getIncrement(), is(nullValue())); ++ endpoint.setIncrement(VALUE); ++ assertThat(endpoint.getIncrement(), is(VALUE)); ++ } ++ ++ @Test ++ public void testGetDecrement() throws Exception { ++ assertThat(endpoint.getDecrement(), is(nullValue())); ++ } ++ ++ @Test ++ public void testSetDecrement() throws Exception { ++ assertThat(endpoint.getDecrement(), is(nullValue())); ++ endpoint.setDecrement(VALUE); ++ assertThat(endpoint.getDecrement(), is(VALUE)); ++ } ++ ++ @Test ++ public void testCreateEndpointUri() throws Exception { ++ assertThat(endpoint.createEndpointUri(), is(CounterEndpoint.ENDPOINT_URI)); ++ } ++} http://git-wip-us.apache.org/repos/asf/camel/blob/641de098/components/camel-metrics/src/test/java/org/apache/camel/metrics/counter/CounterProducerTest.java ---------------------------------------------------------------------- diff --cc components/camel-metrics/src/test/java/org/apache/camel/metrics/counter/CounterProducerTest.java index 0000000,0000000..6351814 new file mode 100644 --- /dev/null +++ b/components/camel-metrics/src/test/java/org/apache/camel/metrics/counter/CounterProducerTest.java @@@ -1,0 -1,0 +1,181 @@@ ++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; ++import static org.mockito.Mockito.when; ++ ++import org.apache.camel.Exchange; ++import org.apache.camel.Message; ++import org.junit.Before; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.mockito.InOrder; ++import org.mockito.Mock; ++import org.mockito.Mockito; ++import org.mockito.runners.MockitoJUnitRunner; ++ ++import com.codahale.metrics.Counter; ++import com.codahale.metrics.MetricRegistry; ++ ++@RunWith(MockitoJUnitRunner.class) ++public class CounterProducerTest { ++ ++ private static final String METRICS_NAME = "metrics.name"; ++ private static final Long INCREMENT = 100000L; ++ private static final Long DECREMENT = 91929199L; ++ ++ @Mock ++ private CounterEndpoint endpoint; ++ ++ @Mock ++ private Exchange exchange; ++ ++ @Mock ++ private MetricRegistry registry; ++ ++ @Mock ++ private Counter counter; ++ ++ @Mock ++ private Message in; ++ ++ private CounterProducer producer; ++ ++ private InOrder inOrder; ++ ++ @Before ++ public void setUp() throws Exception { ++ producer = new CounterProducer(endpoint); ++ inOrder = Mockito.inOrder(endpoint, exchange, registry, counter, in); ++ when(endpoint.getRegistry()).thenReturn(registry); ++ when(registry.counter(METRICS_NAME)).thenReturn(counter); ++ when(exchange.getIn()).thenReturn(in); ++ } ++ ++ @Test ++ public void testCounterProducer() throws Exception { ++ assertThat(producer.getEndpoint().equals(endpoint), is(true)); ++ } ++ ++ @Test ++ public void testProcessWithIncrementOnly() throws Exception { ++ when(endpoint.getIncrement()).thenReturn(INCREMENT); ++ when(endpoint.getDecrement()).thenReturn(null); ++ when(in.getHeader(HEADER_COUNTER_INCREMENT, INCREMENT, Long.class)).thenReturn(INCREMENT); ++ when(in.getHeader(HEADER_COUNTER_DECREMENT, null, Long.class)).thenReturn(null); ++ producer.doProcess(exchange, endpoint, registry, METRICS_NAME); ++ inOrder.verify(exchange, times(1)).getIn(); ++ inOrder.verify(registry, times(1)).counter(METRICS_NAME); ++ inOrder.verify(endpoint, times(1)).getIncrement(); ++ inOrder.verify(endpoint, times(1)).getDecrement(); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_INCREMENT, INCREMENT, Long.class); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_DECREMENT, null, Long.class); ++ inOrder.verify(counter, times(1)).inc(INCREMENT); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testProcessWithDecrementOnly() throws Exception { ++ when(endpoint.getIncrement()).thenReturn(null); ++ when(endpoint.getDecrement()).thenReturn(DECREMENT); ++ when(in.getHeader(HEADER_COUNTER_INCREMENT, null, Long.class)).thenReturn(null); ++ when(in.getHeader(HEADER_COUNTER_DECREMENT, DECREMENT, Long.class)).thenReturn(DECREMENT); ++ producer.doProcess(exchange, endpoint, registry, METRICS_NAME); ++ inOrder.verify(exchange, times(1)).getIn(); ++ inOrder.verify(registry, times(1)).counter(METRICS_NAME); ++ inOrder.verify(endpoint, times(1)).getIncrement(); ++ inOrder.verify(endpoint, times(1)).getDecrement(); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_INCREMENT, null, Long.class); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_DECREMENT, DECREMENT, Long.class); ++ inOrder.verify(counter, times(1)).dec(DECREMENT); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testDoProcessWithIncrementAndDecrement() throws Exception { ++ when(endpoint.getIncrement()).thenReturn(INCREMENT); ++ when(endpoint.getDecrement()).thenReturn(DECREMENT); ++ when(in.getHeader(HEADER_COUNTER_INCREMENT, INCREMENT, Long.class)).thenReturn(INCREMENT); ++ when(in.getHeader(HEADER_COUNTER_DECREMENT, DECREMENT, Long.class)).thenReturn(DECREMENT); ++ producer.doProcess(exchange, endpoint, registry, METRICS_NAME); ++ inOrder.verify(exchange, times(1)).getIn(); ++ inOrder.verify(registry, times(1)).counter(METRICS_NAME); ++ inOrder.verify(endpoint, times(1)).getIncrement(); ++ inOrder.verify(endpoint, times(1)).getDecrement(); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_INCREMENT, INCREMENT, Long.class); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_DECREMENT, DECREMENT, Long.class); ++ inOrder.verify(counter, times(1)).inc(INCREMENT); ++ inOrder.verifyNoMoreInteractions(); ++ } ++ ++ @Test ++ public void testProcessWithOutIncrementAndDecrement() throws Exception { ++ when(endpoint.getIncrement()).thenReturn(null); ++ when(endpoint.getDecrement()).thenReturn(null); ++ when(in.getHeader(HEADER_COUNTER_INCREMENT, null, Long.class)).thenReturn(null); ++ when(in.getHeader(HEADER_COUNTER_DECREMENT, null, Long.class)).thenReturn(null); ++ producer.doProcess(exchange, endpoint, registry, METRICS_NAME); ++ inOrder.verify(exchange, times(1)).getIn(); ++ inOrder.verify(registry, times(1)).counter(METRICS_NAME); ++ inOrder.verify(endpoint, times(1)).getIncrement(); ++ inOrder.verify(endpoint, times(1)).getDecrement(); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_INCREMENT, null, Long.class); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_DECREMENT, null, Long.class); ++ 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(in.getHeader(HEADER_COUNTER_INCREMENT, null, Long.class)).thenReturn(INCREMENT + 1); ++ when(in.getHeader(HEADER_COUNTER_DECREMENT, null, Long.class)).thenReturn(DECREMENT - 1); ++ producer.doProcess(exchange, endpoint, registry, METRICS_NAME); ++ inOrder.verify(exchange, times(1)).getIn(); ++ inOrder.verify(registry, times(1)).counter(METRICS_NAME); ++ inOrder.verify(endpoint, times(1)).getIncrement(); ++ inOrder.verify(endpoint, times(1)).getDecrement(); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_INCREMENT, null, Long.class); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_DECREMENT, null, Long.class); ++ 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(in.getHeader(HEADER_COUNTER_INCREMENT, INCREMENT, Long.class)).thenReturn(INCREMENT + 1); ++ when(in.getHeader(HEADER_COUNTER_DECREMENT, DECREMENT, Long.class)).thenReturn(DECREMENT); ++ producer.doProcess(exchange, endpoint, registry, METRICS_NAME); ++ inOrder.verify(exchange, times(1)).getIn(); ++ inOrder.verify(registry, times(1)).counter(METRICS_NAME); ++ inOrder.verify(endpoint, times(1)).getIncrement(); ++ inOrder.verify(endpoint, times(1)).getDecrement(); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_INCREMENT, INCREMENT, Long.class); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_DECREMENT, DECREMENT, Long.class); ++ 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(in.getHeader(HEADER_COUNTER_INCREMENT, null, Long.class)).thenReturn(null); ++ when(in.getHeader(HEADER_COUNTER_DECREMENT, DECREMENT, Long.class)).thenReturn(DECREMENT - 1); ++ producer.doProcess(exchange, endpoint, registry, METRICS_NAME); ++ inOrder.verify(exchange, times(1)).getIn(); ++ inOrder.verify(registry, times(1)).counter(METRICS_NAME); ++ inOrder.verify(endpoint, times(1)).getIncrement(); ++ inOrder.verify(endpoint, times(1)).getDecrement(); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_INCREMENT, null, Long.class); ++ inOrder.verify(in, times(1)).getHeader(HEADER_COUNTER_DECREMENT, DECREMENT, Long.class); ++ inOrder.verify(counter, times(1)).dec(DECREMENT - 1); ++ inOrder.verifyNoMoreInteractions(); ++ } ++}