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
++
++[![Build 
Status](https://travis-ci.org/laurikimmel/camel-metrics.svg?branch=master)](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();
++    }
++}

Reply via email to