You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2018/02/08 08:37:29 UTC

[camel] branch master updated: [XChange] Get the list of supported currency pairs

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 4a264d4  [XChange] Get the list of supported currency pairs
4a264d4 is described below

commit 4a264d445fd53bbce3e1edc4e04bb600cc28892c
Author: Thomas Diesler <td...@redhat.com>
AuthorDate: Tue Feb 6 15:32:54 2018 +0100

    [XChange] Get the list of supported currency pairs
    
    Resolves CAMEL-12167
---
 .../src/main/docs/xchange-component.adoc           | 28 ++-----
 .../camel/component/xchange/XChangeComponent.java  | 17 +++-
 .../component/xchange/XChangeConfiguration.java    | 64 ++++++++++++++-
 .../camel/component/xchange/XChangeEndpoint.java   | 59 +++++++++++---
 ...onsumer.java => XChangeMarketDataProducer.java} | 40 ++++-----
 .../component/xchange/XChangeMetaDataProducer.java | 69 ++++++++++++++++
 .../market}/TickerConsumerTest.java                | 26 +++---
 .../xchange/metadata/MetaDataConsumerTest.java     | 94 ++++++++++++++++++++++
 8 files changed, 319 insertions(+), 78 deletions(-)

diff --git a/components/camel-xchange/src/main/docs/xchange-component.adoc b/components/camel-xchange/src/main/docs/xchange-component.adoc
index b6a87a6..d351375 100644
--- a/components/camel-xchange/src/main/docs/xchange-component.adoc
+++ b/components/camel-xchange/src/main/docs/xchange-component.adoc
@@ -54,32 +54,16 @@ with the following path and query parameters:
 | *name* | *Required* The exchange to connect to |  | String
 |===
 
-==== Query Parameters (21 parameters):
+==== Query Parameters (5 parameters):
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *currencyPair* (common) | The currency pair |  | CurrencyPair
-| *method* (common) | *Required* The method to execute |  | String
-| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler which mean any exceptions occurred while the consumer is trying to pickup incoming messages or the likes will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions that will be logged at WARN or ERROR level and ignored. | false | boolean
-| *sendEmptyMessageWhenIdle* (consumer) | If the polling consumer did not poll any files you can enable this option to send an empty message (no body) instead. | false | boolean
-| *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this options is not in use. By default the consumer will deal with exceptions that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
-| *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. |  | ExchangePattern
-| *pollStrategy* (consumer) | A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your custom implementation to control error handling usually occurred during the poll operation before an Exchange have been created and being routed in Camel. |  | PollingConsumerPoll Strategy
+| *currency* (producer) | The currency |  | Currency
+| *currencyPair* (producer) | The currency pair |  | CurrencyPair
+| *method* (producer) | *Required* The method to execute |  | XChangeMethod
+| *service* (producer) | *Required* The service to call |  | XChangeService
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used or Camel is allowed to use asynchronous processing (if supported). | false | boolean
-| *backoffErrorThreshold* (scheduler) | The number of subsequent error polls (failed due some error) that should happen before the backoffMultipler should kick-in. |  | int
-| *backoffIdleThreshold* (scheduler) | The number of subsequent idle polls that should happen before the backoffMultipler should kick-in. |  | int
-| *backoffMultiplier* (scheduler) | To let the scheduled polling consumer backoff if there has been a number of subsequent idles/errors in a row. The multiplier is then the number of polls that will be skipped before the next actual attempt is happening again. When this option is in use then backoffIdleThreshold and/or backoffErrorThreshold must also be configured. |  | int
-| *delay* (scheduler) | Milliseconds before the next poll. You can also specify time values using units such as 60s (60 seconds) 5m30s (5 minutes and 30 seconds) and 1h (1 hour). | 500 | long
-| *greedy* (scheduler) | If greedy is enabled then the ScheduledPollConsumer will run immediately again if the previous run polled 1 or more messages. | false | boolean
-| *initialDelay* (scheduler) | Milliseconds before the first poll starts. You can also specify time values using units such as 60s (60 seconds) 5m30s (5 minutes and 30 seconds) and 1h (1 hour). | 1000 | long
-| *runLoggingLevel* (scheduler) | The consumer logs a start/complete log line when it polls. This option allows you to configure the logging level for that. | TRACE | LoggingLevel
-| *scheduledExecutorService* (scheduler) | Allows for configuring a custom/shared thread pool to use for the consumer. By default each consumer has its own single threaded thread pool. |  | ScheduledExecutor Service
-| *scheduler* (scheduler) | To use a cron scheduler from either camel-spring or camel-quartz2 component | none | ScheduledPollConsumer Scheduler
-| *schedulerProperties* (scheduler) | To configure additional properties when using a custom scheduler or any of the Quartz2 Spring based scheduler. |  | Map
-| *startScheduler* (scheduler) | Whether the scheduler should be auto started. | true | boolean
-| *timeUnit* (scheduler) | Time unit for initialDelay and delay options. | MILLISECONDS | TimeUnit
-| *useFixedDelay* (scheduler) | Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in JDK for details. | true | boolean
 |===
 // endpoint options: END
 
@@ -98,4 +82,4 @@ In this sample we find the current Bitcoin market price in USDT:
 [source,java]
 ---------------------------------------------------------------------------------------------
 from("xchange:binance?method=ticker&currencyPair=BTC/USDT").to("jms:queue:btc");
----------------------------------------------------------------------------------------------
\ No newline at end of file
+---------------------------------------------------------------------------------------------
diff --git a/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeComponent.java b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeComponent.java
index 6b96ca1..13b151a 100644
--- a/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeComponent.java
+++ b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeComponent.java
@@ -20,19 +20,28 @@ import java.util.Map;
 
 import org.apache.camel.Endpoint;
 import org.apache.camel.impl.DefaultComponent;
+import org.knowm.xchange.Exchange;
 import org.knowm.xchange.ExchangeFactory;
-import org.knowm.xchange.binance.BinanceExchange;
+import org.knowm.xchange.utils.Assert;
 
 public class XChangeComponent extends DefaultComponent {
 
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
-        XChangeConfiguration configuration = new XChangeConfiguration(this);
 
-        // and then override from parameters
+        // Init the configuration
+        XChangeConfiguration configuration = new XChangeConfiguration(this);
         setProperties(configuration, parameters);
 
-        XChange exchange = new XChange(ExchangeFactory.INSTANCE.createExchange(BinanceExchange.class));
+        // Set the the required name of the exchange
+        configuration.setName(remaining);
+
+        // Get the XChange implementation
+        Class<? extends Exchange> exchangeClass = configuration.getXChangeClass();
+        Assert.notNull(exchangeClass, "XChange not supported: " + configuration.getName());
+        
+        // Create the XChange and associated Endpoint
+        XChange exchange = new XChange(ExchangeFactory.INSTANCE.createExchange(exchangeClass));
         XChangeEndpoint endpoint = new XChangeEndpoint(uri, this, configuration, exchange);
         
         return endpoint;
diff --git a/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeConfiguration.java b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeConfiguration.java
index 03763a7..3e82d2d 100644
--- a/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeConfiguration.java
+++ b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeConfiguration.java
@@ -17,23 +17,45 @@
 package org.apache.camel.component.xchange;
 
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriParams;
 import org.apache.camel.spi.UriPath;
 import org.apache.camel.util.ObjectHelper;
+import org.knowm.xchange.Exchange;
+import org.knowm.xchange.currency.Currency;
 import org.knowm.xchange.currency.CurrencyPair;
 
 @UriParams
 public class XChangeConfiguration {
 
+    public enum XChangeService { marketdata, metadata }
+    public enum XChangeMethod { currencies, currencyMetaData, currencyPairs, currencyPairMetaData, ticker }
+    
+    public static final String HEADER_CURRENCY = "Currency";
+    public static final String HEADER_CURRENCY_PAIR = "CurrencyPair";
+    
     @UriPath(description = "The exchange to connect to") @Metadata(required = "true")
     private String name;
+    @UriParam(description = "The service to call") @Metadata(required = "true")
+    private XChangeService service;
     @UriParam(description = "The method to execute") @Metadata(required = "true")
-    private String method;
+    private XChangeMethod method;
+    @UriParam(description = "The currency") 
+    private Currency currency;
     @UriParam(description = "The currency pair") 
     private CurrencyPair currencyPair;
 
+    static Map<String, Class<? extends Exchange>> xchangeMapping = new HashMap<>();
+    static {
+        // Add name mappings here that do not follow the convention 
+        // nameMapping.put("binance", BinanceExchange.class);
+    }
+    
     public XChangeConfiguration(XChangeComponent component) {
         ObjectHelper.notNull(component, "component");
     }
@@ -46,14 +68,30 @@ public class XChangeConfiguration {
         this.name = name;
     }
 
-    public String getMethod() {
+    public XChangeService getService() {
+        return service;
+    }
+
+    public void setService(XChangeService service) {
+        this.service = service;
+    }
+
+    public XChangeMethod getMethod() {
         return method;
     }
 
-    public void setMethod(String method) {
+    public void setMethod(XChangeMethod method) {
         this.method = method;
     }
 
+    public Currency getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String curr) {
+        this.currency = Currency.getInstanceNoCreate(curr);
+    }
+
     public CurrencyPair getCurrencyPair() {
         return currencyPair;
     }
@@ -61,4 +99,24 @@ public class XChangeConfiguration {
     public void setCurrencyPair(String pair) {
         this.currencyPair = new CurrencyPair(pair);
     }
+
+    @SuppressWarnings("unchecked")
+    public Class<? extends Exchange> getXChangeClass() {
+        Class<? extends Exchange> xchangeClass = xchangeMapping.get(name);
+        if (xchangeClass == null) {
+            String firstUpper = name.substring(0, 1).toUpperCase() + name.substring(1);
+            String className = "org.knowm.xchange." + name + "." + firstUpper + "Exchange";
+            ClassLoader classLoader = getClass().getClassLoader();
+            try {
+                xchangeClass = (Class<? extends Exchange>) classLoader.loadClass(className);
+            } catch (ClassNotFoundException e) {
+                // ignore
+            }
+        }
+        return xchangeClass;
+    }
+
+    public Set<String> getSupportedXChangeNames() {
+        return xchangeMapping.keySet();
+    }
 }
diff --git a/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeEndpoint.java b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeEndpoint.java
index 70a0fe1..43250fe 100644
--- a/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeEndpoint.java
+++ b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeEndpoint.java
@@ -16,15 +16,25 @@
  */
 package org.apache.camel.component.xchange;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
-import org.apache.camel.impl.DefaultPollingEndpoint;
+import org.apache.camel.component.xchange.XChangeConfiguration.XChangeService;
+import org.apache.camel.impl.DefaultEndpoint;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
+import org.knowm.xchange.currency.Currency;
+import org.knowm.xchange.currency.CurrencyPair;
+import org.knowm.xchange.dto.meta.CurrencyMetaData;
+import org.knowm.xchange.dto.meta.CurrencyPairMetaData;
+import org.knowm.xchange.dto.meta.ExchangeMetaData;
+import org.knowm.xchange.utils.Assert;
 
-@UriEndpoint(firstVersion = "2.21.0", scheme = "xchange", title = "XChange", syntax = "xchange:name", consumerClass = XChangeConsumer.class, label = "api")
-public class XChangeEndpoint extends DefaultPollingEndpoint {
+@UriEndpoint(firstVersion = "2.21.0", scheme = "xchange", title = "XChange", syntax = "xchange:name", producerOnly = true, label = "blockchain")
+public class XChangeEndpoint extends DefaultEndpoint {
 
     @UriParam
     private XChangeConfiguration configuration;
@@ -38,18 +48,23 @@ public class XChangeEndpoint extends DefaultPollingEndpoint {
 
     @Override
     public Consumer createConsumer(Processor processor) throws Exception {
-        XChangeConsumer answer = new XChangeConsumer(this, processor);
-
-        // ScheduledPollConsumer default delay is 500 millis and that is too often for polling a feed, so we override
-        // with a new default value. End user can override this value by providing a consumer.delay parameter
-        answer.setDelay(XChangeConsumer.DEFAULT_CONSUMER_DELAY);
-        configureConsumer(answer);
-        return answer;
+        throw new UnsupportedOperationException();
     }
 
     @Override
     public Producer createProducer() throws Exception {
-        throw new UnsupportedOperationException();
+        
+        Producer producer = null;
+        
+        XChangeService service = getConfiguration().getService();
+        if (XChangeService.metadata == service) {
+            producer = new XChangeMetaDataProducer(this);
+        } else if (XChangeService.marketdata == service) {
+            producer = new XChangeMarketDataProducer(this);
+        }
+        
+        Assert.notNull(producer, "Unsupported service: " + service);
+        return producer;
     }
 
     @Override
@@ -64,4 +79,26 @@ public class XChangeEndpoint extends DefaultPollingEndpoint {
     public XChange getXChange() {
         return exchange;
     }
+    
+    public List<Currency> getCurrencies() {
+        ExchangeMetaData metaData = exchange.getExchangeMetaData();
+        return metaData.getCurrencies().keySet().stream().sorted().collect(Collectors.toList());
+    }
+    
+    public CurrencyMetaData getCurrencyMetaData(Currency curr) {
+        Assert.notNull(curr, "Null currency");
+        ExchangeMetaData metaData = exchange.getExchangeMetaData();
+        return metaData.getCurrencies().get(curr);
+    }
+    
+    public List<CurrencyPair> getCurrencyPairs() {
+        ExchangeMetaData metaData = exchange.getExchangeMetaData();
+        return metaData.getCurrencyPairs().keySet().stream().sorted().collect(Collectors.toList());
+    }
+    
+    public CurrencyPairMetaData getCurrencyPairMetaData(CurrencyPair pair) {
+        Assert.notNull(pair, "Null currency");
+        ExchangeMetaData metaData = exchange.getExchangeMetaData();
+        return metaData.getCurrencyPairs().get(pair);
+    }
 }
diff --git a/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeConsumer.java b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeMarketDataProducer.java
similarity index 59%
rename from components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeConsumer.java
rename to components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeMarketDataProducer.java
index d14cda2..03e397f 100644
--- a/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeConsumer.java
+++ b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeMarketDataProducer.java
@@ -16,26 +16,21 @@
  */
 package org.apache.camel.component.xchange;
 
+import static org.apache.camel.component.xchange.XChangeConfiguration.HEADER_CURRENCY_PAIR;
+
 import org.apache.camel.Exchange;
-import org.apache.camel.Processor;
-import org.apache.camel.impl.ScheduledPollConsumer;
+import org.apache.camel.component.xchange.XChangeConfiguration.XChangeMethod;
+import org.apache.camel.impl.DefaultProducer;
 import org.knowm.xchange.currency.CurrencyPair;
 import org.knowm.xchange.dto.marketdata.Ticker;
 import org.knowm.xchange.service.marketdata.MarketDataService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-public class XChangeConsumer extends ScheduledPollConsumer {
-    
-    public static final long DEFAULT_CONSUMER_DELAY = 60 * 60 * 1000L;
+public class XChangeMarketDataProducer extends DefaultProducer {
     
-    private static final Logger LOG = LoggerFactory.getLogger(XChangeConsumer.class);
-
     private final MarketDataService marketService;
     
-    public XChangeConsumer(XChangeEndpoint endpoint, Processor processor) {
-        super(endpoint, processor);
-        
+    public XChangeMarketDataProducer(XChangeEndpoint endpoint) {
+        super(endpoint);
         marketService = endpoint.getXChange().getMarketDataService();
     }
 
@@ -45,17 +40,16 @@ public class XChangeConsumer extends ScheduledPollConsumer {
     }
 
     @Override
-    protected int poll() throws Exception {
-        CurrencyPair pair = getEndpoint().getConfiguration().getCurrencyPair();
-        LOG.info("Going to execute ticker query for {}", pair);
-        
-        Ticker ticker = marketService.getTicker(pair);
-        
-        Exchange exchange = getEndpoint().createExchange();
-        exchange.getIn().setBody(ticker);
-        getProcessor().process(exchange);
+    public void process(Exchange exchange) throws Exception {
+
+        XChangeEndpoint endpoint = getEndpoint();
+        XChangeMethod method = endpoint.getConfiguration().getMethod();
         
-        return 1;
+        if (XChangeMethod.ticker == method) {
+            CurrencyPair pair = exchange.getIn().getHeader(HEADER_CURRENCY_PAIR, CurrencyPair.class);
+            pair = pair != null ? pair : exchange.getMessage().getBody(CurrencyPair.class);
+            Ticker ticker = marketService.getTicker(pair);
+            exchange.getMessage().setBody(ticker);
+        }
     }
-
 }
\ No newline at end of file
diff --git a/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeMetaDataProducer.java b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeMetaDataProducer.java
new file mode 100644
index 0000000..8fb4de8
--- /dev/null
+++ b/components/camel-xchange/src/main/java/org/apache/camel/component/xchange/XChangeMetaDataProducer.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.xchange;
+
+import static org.apache.camel.component.xchange.XChangeConfiguration.HEADER_CURRENCY;
+import static org.apache.camel.component.xchange.XChangeConfiguration.HEADER_CURRENCY_PAIR;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.xchange.XChangeConfiguration.XChangeMethod;
+import org.apache.camel.impl.DefaultProducer;
+import org.knowm.xchange.currency.Currency;
+import org.knowm.xchange.currency.CurrencyPair;
+
+public class XChangeMetaDataProducer extends DefaultProducer {
+    
+    public XChangeMetaDataProducer(XChangeEndpoint endpoint) {
+        super(endpoint);
+    }
+
+    @Override
+    public XChangeEndpoint getEndpoint() {
+        return (XChangeEndpoint) super.getEndpoint();
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+
+        XChangeEndpoint endpoint = getEndpoint();
+        XChangeMethod method = endpoint.getConfiguration().getMethod();
+        
+        if (XChangeMethod.currencies == method) {
+            Object body = endpoint.getCurrencies();
+            exchange.getMessage().setBody(body);
+        } 
+        
+        else if (XChangeMethod.currencyPairs == method) {
+            Object body = endpoint.getCurrencyPairs();
+            exchange.getMessage().setBody(body);
+        } 
+        
+        else if (XChangeMethod.currencyMetaData == method) {
+            Currency curr = exchange.getMessage().getHeader(HEADER_CURRENCY, Currency.class);
+            curr = curr != null ? curr : exchange.getMessage().getBody(Currency.class);
+            Object body = endpoint.getCurrencyMetaData(curr);
+            exchange.getMessage().setBody(body);
+        } 
+        
+        else if (XChangeMethod.currencyPairMetaData == method) {
+            CurrencyPair pair = exchange.getIn().getHeader(HEADER_CURRENCY_PAIR, CurrencyPair.class);
+            pair = pair != null ? pair : exchange.getMessage().getBody(CurrencyPair.class);
+            Object body = endpoint.getCurrencyPairMetaData(pair);
+            exchange.getMessage().setBody(body);
+        }
+    }
+}
\ No newline at end of file
diff --git a/components/camel-xchange/src/test/java/org/apache/camel/component/weather/TickerConsumerTest.java b/components/camel-xchange/src/test/java/org/apache/camel/component/xchange/market/TickerConsumerTest.java
similarity index 66%
rename from components/camel-xchange/src/test/java/org/apache/camel/component/weather/TickerConsumerTest.java
rename to components/camel-xchange/src/test/java/org/apache/camel/component/xchange/market/TickerConsumerTest.java
index e6404c5..0ad79e2 100644
--- a/components/camel-xchange/src/test/java/org/apache/camel/component/weather/TickerConsumerTest.java
+++ b/components/camel-xchange/src/test/java/org/apache/camel/component/xchange/market/TickerConsumerTest.java
@@ -14,15 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.component.weather;
+package org.apache.camel.component.xchange.market;
 
-import java.util.concurrent.TimeUnit;
+import static org.apache.camel.component.xchange.XChangeConfiguration.HEADER_CURRENCY_PAIR;
 
-import org.apache.camel.Exchange;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Assert;
 import org.junit.Test;
+import org.knowm.xchange.currency.CurrencyPair;
 import org.knowm.xchange.dto.marketdata.Ticker;
 
 public class TickerConsumerTest extends CamelTestSupport {
@@ -32,8 +32,8 @@ public class TickerConsumerTest extends CamelTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("xchange:binance?method=ticker&currencyPair=BTC/USDT")
-                        .to("mock:result");
+                from("direct:ticker")
+                .to("xchange:binance?service=marketdata&method=ticker");
             }
         };
     }
@@ -41,15 +41,11 @@ public class TickerConsumerTest extends CamelTestSupport {
     @Test
     public void testTicker() throws Exception {
         
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
-
-        // give the route a bit time to start and fetch the ticker info
-        assertMockEndpointsSatisfied(20, TimeUnit.SECONDS);
-
-        Exchange exchange = mock.getExchanges().get(0);
-        Ticker ticker = exchange.getIn().getBody(Ticker.class);
-        assertNotNull(ticker);
+        Ticker ticker = template.requestBody("direct:ticker", CurrencyPair.EOS_ETH, Ticker.class);
+        Assert.assertNotNull("Ticker not null", ticker);
+        
+        ticker = template.requestBodyAndHeader("direct:ticker", null, HEADER_CURRENCY_PAIR, CurrencyPair.EOS_ETH, Ticker.class);
+        Assert.assertNotNull("Ticker not null", ticker);
     }
 }
 
diff --git a/components/camel-xchange/src/test/java/org/apache/camel/component/xchange/metadata/MetaDataConsumerTest.java b/components/camel-xchange/src/test/java/org/apache/camel/component/xchange/metadata/MetaDataConsumerTest.java
new file mode 100644
index 0000000..a37164d
--- /dev/null
+++ b/components/camel-xchange/src/test/java/org/apache/camel/component/xchange/metadata/MetaDataConsumerTest.java
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.xchange.metadata;
+
+import static org.apache.camel.component.xchange.XChangeConfiguration.HEADER_CURRENCY;
+import static org.apache.camel.component.xchange.XChangeConfiguration.HEADER_CURRENCY_PAIR;
+
+import java.util.List;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Assert;
+import org.junit.Test;
+import org.knowm.xchange.currency.Currency;
+import org.knowm.xchange.currency.CurrencyPair;
+import org.knowm.xchange.dto.meta.CurrencyMetaData;
+import org.knowm.xchange.dto.meta.CurrencyPairMetaData;
+
+public class MetaDataConsumerTest extends CamelTestSupport {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                
+                from("direct:currencies")
+                .to("xchange:binance?service=metadata&method=currencies");
+                
+                from("direct:currencyMetaData")
+                .to("xchange:binance?service=metadata&method=currencyMetaData");
+                
+                from("direct:currencyPairs")
+                .to("xchange:binance?service=metadata&method=currencyPairs");
+                
+                from("direct:currencyPairMetaData")
+                .to("xchange:binance?service=metadata&method=currencyPairMetaData");
+            }
+        };
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testCurrencies() throws Exception {
+        
+        List<Currency> currencies = template.requestBody("direct:currencies", null, List.class);
+        Assert.assertNotNull("Currencies not null", currencies);
+        Assert.assertTrue("Contains ETH", currencies.contains(Currency.ETH));
+    }
+
+    @Test
+    public void testCurrencyMetaData() throws Exception {
+        
+        CurrencyMetaData metadata = template.requestBody("direct:currencyMetaData", Currency.ETH, CurrencyMetaData.class);
+        Assert.assertNotNull("CurrencyMetaData not null", metadata);
+        
+        metadata = template.requestBodyAndHeader("direct:currencyMetaData", null, HEADER_CURRENCY, Currency.ETH, CurrencyMetaData.class);
+        Assert.assertNotNull("CurrencyMetaData not null", metadata);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testCurrencyPairs() throws Exception {
+        
+        List<CurrencyPair> pairs = template.requestBody("direct:currencyPairs", null, List.class);
+        Assert.assertNotNull("Pairs not null", pairs);
+        Assert.assertTrue("Contains EOS/ETH", pairs.contains(CurrencyPair.EOS_ETH));
+    }
+
+    @Test
+    public void testCurrencyPairMetaData() throws Exception {
+        
+        CurrencyPairMetaData metadata = template.requestBody("direct:currencyPairMetaData", CurrencyPair.EOS_ETH, CurrencyPairMetaData.class);
+        Assert.assertNotNull("CurrencyPairMetaData not null", metadata);
+        
+        metadata = template.requestBodyAndHeader("direct:currencyPairMetaData", null, HEADER_CURRENCY_PAIR, CurrencyPair.EOS_ETH, CurrencyPairMetaData.class);
+        Assert.assertNotNull("CurrencyPairMetaData not null", metadata);
+    }
+}
+

-- 
To stop receiving notification emails like this one, please contact
davsclaus@apache.org.