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
commit bef1ea4e6348ca21f08e6ea2dfcf48c19885e9fe Author: Carl-Philipp Harmant <[email protected]> AuthorDate: Wed Nov 1 16:20:14 2017 -0500 Add remaining YQL options and update doc and javadoc --- .../camel-yql/src/main/docs/yql-component.adoc | 157 ++++++++++++++++++--- .../apache/camel/component/yql/YqlComponent.java | 9 +- .../apache/camel/component/yql/YqlProducer.java | 9 +- .../camel/component/yql/client/YqlClient.java | 36 +++-- .../yql/configuration/YqlConfiguration.java | 108 ++++++++++++-- .../configuration/YqlConfigurationValidator.java | 8 ++ .../component/yql/YqlComponentIntegrationTest.java | 130 ++++++++++++++--- .../YqlConfigurationValidatorTest.java | 37 ++++- components/readme.adoc | 4 +- docs/user-manual/en/SUMMARY.md | 1 - .../yql/springboot/YqlComponentConfiguration.java | 16 +++ 11 files changed, 434 insertions(+), 81 deletions(-) diff --git a/components/camel-yql/src/main/docs/yql-component.adoc b/components/camel-yql/src/main/docs/yql-component.adoc index efc13cb..8319a89 100644 --- a/components/camel-yql/src/main/docs/yql-component.adoc +++ b/components/camel-yql/src/main/docs/yql-component.adoc @@ -55,17 +55,22 @@ with the following path and query parameters: [width="100%",cols="2,5,^1,2",options="header"] |=== | Name | Description | Default | Type -| *query* | *Required* The YQL query to be sent. | | String +| *query* | *Required* The YQL statement to execute. | | String |=== -==== Query Parameters (5 parameters): +==== Query Parameters (10 parameters): [width="100%",cols="2,5,^1,2",options="header"] |=== | Name | Description | Default | Type -| *callback* (producer) | If specified the option will be included in the HTTP request to YQL. If the format is json then the response will contain a JSONP callback method. If the format is xml then the response will contain a JSONP-X callback method. More information: https://developer.yahoo.com/yql/guide/response.html | | String -| *diagnostics* (producer) | If true the option will be included in the HTTP request to YQL and the response will contain some diagnostics data. | false | boolean -| *format* (producer) | The expected format. Can only be json or xml. | json | String +| *callback* (producer) | The name of the JavaScript callback function for JSONP format. If callback is set and if format=json then the response format is JSON. For more information on using XML instead of JSON see JSONP-X. https://developer.yahoo.com/yql/guide/response.html | | String +| *crossProduct* (producer) | When given the value optimized the projected fields in SELECT statements that may be returned in separate item elements in the response are optimized to be in a single item element instead. The only allowed value is optimized. More information https://developer.yahoo.com/yql/guide/response.htmlresponse-optimizing= | | String +| *debug* (producer) | If true and if diagnostic is set to true debug data is returned with the response. More information: https://developer.yahoo.com/yql/guide/dev-external_tables.htmlodt-enable-logging= | false | boolean +| *diagnostics* (producer) | If true diagnostic information is returned with the response. | false | boolean +| *env* (producer) | Allows you to use multiple Open Data Tables through a YQL environment file. More information https://developer.yahoo.com/yql/guide/yql_storage.htmlusing-records-env-files= | | String +| *format* (producer) | The expected format. Allowed values: xml or json. | json | String +| *https* (producer) | Option to use HTTPS to communicate with YQL. | true | boolean +| *jsonCompat* (producer) | Enables lossless JSON processing. The only allowed value is new. More information https://developer.yahoo.com/yql/guide/response.htmljson-to-json= | | String | *throwExceptionOnFailure* (producer) | Option to disable throwing the YqlHttpException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code. | true | boolean | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used or Camel is allowed to use asynchronous processing (if supported). | false | boolean |=== @@ -81,18 +86,20 @@ the `format` option above). [width="100%",cols="10%,90%",options="header",] |======================================================================= |Header |Description -|`CamelYqlHttpRequest` | Http request sent to YQL -|`CamelYqlHttpStatus` | Status code from the response +|`CamelYqlHttpRequest` | Original HTTP request sent to YQL. +|`CamelYqlHttpStatus` | Status code from the response. |======================================================================= ### Samples -In this example we query YQL to obtain Google quote: +# Sample 1 + +In this example we query YQL to obtain the current wind and atmosphere data in Chicago: [source,java] -------------------------------------------------------- from("direct:start") - .to("yql://select * from yahoo.finance.quotes where symbol in ('GOOG')?format=json"); + .to("yql://select wind, atmosphere from weather.forecast where woeid in (select woeid from geo.places(1) where text='chicago, il'"); -------------------------------------------------------- Which will setup the body as: @@ -100,20 +107,26 @@ Which will setup the body as: [source,json] -------------------------------------------------------- { - "query": { - "count": 1, - "created": "2017-10-29T03:17:28Z", - "lang": "en-US", - "results": { - "quote": { - "symbol": "GOOG", - "Ask": "1024.50", - "AverageDailyVolume": "1356700", - "Bid": "1019.27", - ... + "query":{ + "count":1, + "created":"2017-11-01T19:37:26Z", + "lang":"en-US", + "results":{ + "channel":{ + "wind":{ + "chill":"32", + "direction":"165", + "speed":"22" + }, + "atmosphere":{ + "humidity":"71", + "pressure":"994.0", + "rising":"0", + "visibility":"16.1" + } + } + } } - } - } } -------------------------------------------------------- @@ -122,6 +135,104 @@ and the headers: [width="100%",cols="30%,70%",options="header",] |======================================================================= |Header |Value -|`CamelYqlHttpRequest` |http://query.yahooapis.com/v1/public/yql?format=json&diagnostics=false&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=yqlCallback&q=select+*+from+yahoo.finance.quotes+where+symbol+in+%28%27GOOG%27%29 +|`CamelYqlHttpRequest` |https://query.yahooapis.com/v1/public/yql?q=select+wind%2C+atmosphere+from+weather.forecast+where+woeid+in+%28select+woeid+from+geo.places%281%29+where+text%3D%22chicago%2C+il%22%29&format=json&callback=&diagnostics=false&debug=false +|`CamelYqlHttpStatus` |200 +|======================================================================= + +# Sample 2 + +In this example we query YQL to obtain the Google quote. + +[source,java] +-------------------------------------------------------- +from("direct:start") + .to("yql://select symbol, Ask, Bid, AverageDailyVolume from yahoo.finance.quotes where symbol in ('GOOG')?env=store://datatables.org/alltableswithkeys&https=false&callback=yqlCallback"); +-------------------------------------------------------- + +Which will setup the body as: + +[source,json] +-------------------------------------------------------- +/**/yqlCallback({ + "query":{ + "count":1, + "created":"2017-11-01T19:48:17Z", + "lang":"en-US", + "results":{ + "quote":{ + "symbol":"GOOG", + "Bid":"1025.57", + "Ask":"1025.92", + "AverageDailyVolume":"1350640"AverageDailyVolume + } + } + } +}); +-------------------------------------------------------- + +and the headers: + +[width="100%",cols="30%,70%",options="header",] +|======================================================================= +|Header |Value +|`CamelYqlHttpRequest` |http://query.yahooapis.com/v1/public/yql?q=select+symbol%2C+Ask%2C+Bid%2C+AverageDailyVolume+from+yahoo.finance.quotes+where+symbol+in+%28%27GOOG%27%29&format=json&callback=yqlCallback&diagnostics=false&debug=false&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys |`CamelYqlHttpStatus` |200 |======================================================================= + +# Sample 3 + +In this example we query YQL to obtain one book written by Barack Obama + +[source,java] +-------------------------------------------------------- +from("direct:start") + .to("yql://select * from google.books where q='barack obama' and maxResults=1?format=xml&crossProduct=optimized&env=store://datatables.org/alltableswithkeys"); +-------------------------------------------------------- + +Which will setup the body as: + +[source,xml] +-------------------------------------------------------- +<?xml version="1.0" encoding="UTF-8"?> +<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:count="1" yahoo:created="2017-11-01T20:32:22Z" yahoo:lang="en-US"> + <results> + <json> + <kind>books#volumes</kind> + <totalItems>1993</totalItems> + <items> + <kind>books#volume</kind> + <id>HRCHJp-V0QUC</id> + <etag>SeTJeSgFDzo</etag> + <selfLink>https://www.googleapis.com/books/v1/volumes/HRCHJp-V0QUC</selfLink> + <volumeInfo> + <title>Dreams from My Father</title> + <subtitle>A Story of Race and Inheritance</subtitle> + <authors>Barack Obama</authors> + <publisher>Broadway Books</publisher> + <publishedDate>2007-01-09</publishedDate> + ... + </volumeInfo> + </items> + </json> + </results> +</query> +<!-- total: 646 --> +-------------------------------------------------------- + +and the headers: + +[width="100%",cols="30%,70%",options="header",] +|======================================================================= +|Header |Value +|`CamelYqlHttpRequest` |https://query.yahooapis.com/v1/public/yql?q=select+*+from+google.books+where+q%3D%27barack+obama%27+and+maxResults%3D1&format=xml&callback=&crossProduct=optimized&diagnostics=false&debug=false&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys +|`CamelYqlHttpStatus` |200 +|======================================================================= + +### See Also + +* link:configuring-camel.html[Configuring Camel] +* link:component.html[Component] +* link:endpoint.html[Endpoint] +* link:getting-started.html[Getting Started] + +* https://developer.yahoo.com/yql/guide/[YQL Official Guide] \ No newline at end of file diff --git a/components/camel-yql/src/main/java/org/apache/camel/component/yql/YqlComponent.java b/components/camel-yql/src/main/java/org/apache/camel/component/yql/YqlComponent.java index fe02676..affc329 100644 --- a/components/camel-yql/src/main/java/org/apache/camel/component/yql/YqlComponent.java +++ b/components/camel-yql/src/main/java/org/apache/camel/component/yql/YqlComponent.java @@ -32,15 +32,12 @@ public class YqlComponent extends DefaultComponent { protected Endpoint createEndpoint(final String uri, final String remaining, final Map<String, Object> parameters) throws Exception { final YqlConfiguration configuration = new YqlConfiguration(); configuration.setQuery(remaining); + setProperties(configuration, parameters); + YqlConfigurationValidator.validateProperties(configuration); final HttpClientConnectionManager connectionManager = createConnectionManager(); - final Endpoint endpoint = new YqlEndpoint(uri, this, configuration, connectionManager); - - YqlConfigurationValidator.validateProperties(configuration); - - setProperties(configuration, parameters); - return endpoint; + return new YqlEndpoint(uri, this, configuration, connectionManager); } @Override diff --git a/components/camel-yql/src/main/java/org/apache/camel/component/yql/YqlProducer.java b/components/camel-yql/src/main/java/org/apache/camel/component/yql/YqlProducer.java index f32a7a7..62fe95e 100644 --- a/components/camel-yql/src/main/java/org/apache/camel/component/yql/YqlProducer.java +++ b/components/camel-yql/src/main/java/org/apache/camel/component/yql/YqlProducer.java @@ -44,15 +44,12 @@ public class YqlProducer extends DefaultProducer { @Override public void process(final Exchange exchange) throws Exception { final YqlConfiguration configuration = endpoint.getConfiguration(); - final YqlResponse yqlResponse = yqlClient.get( - configuration.getQuery(), - configuration.getFormat(), - configuration.isDiagnostics(), - configuration.getCallback() - ); + final YqlResponse yqlResponse = yqlClient.get(configuration); + if (configuration.isThrowExceptionOnFailure() && yqlResponse.getStatus() != HttpStatus.SC_OK) { throw YqlHttpException.failedWith(yqlResponse.getStatus(), yqlResponse.getBody(), yqlResponse.getHttpRequest()); } + exchange.getIn().setHeader(CAMEL_YQL_HTTP_STATUS, yqlResponse.getStatus()); exchange.getIn().setHeader(CAMEL_YQL_HTTP_REQUEST, yqlResponse.getHttpRequest()); exchange.getIn().setBody(yqlResponse.getBody()); diff --git a/components/camel-yql/src/main/java/org/apache/camel/component/yql/client/YqlClient.java b/components/camel-yql/src/main/java/org/apache/camel/component/yql/client/YqlClient.java index 650243c..fa10869 100644 --- a/components/camel-yql/src/main/java/org/apache/camel/component/yql/client/YqlClient.java +++ b/components/camel-yql/src/main/java/org/apache/camel/component/yql/client/YqlClient.java @@ -17,10 +17,15 @@ package org.apache.camel.component.yql.client; import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import org.apache.camel.component.yql.configuration.YqlConfiguration; +import org.apache.http.NameValuePair; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,21 +36,17 @@ public class YqlClient { private final CloseableHttpClient httpClient; - public YqlClient(final CloseableHttpClient httpClient){ + public YqlClient(final CloseableHttpClient httpClient) { this.httpClient = httpClient; } - public YqlResponse get(final String query, final String format, final boolean diagnostics, final String callback) throws Exception { + public YqlResponse get(final YqlConfiguration yqlConfiguration) throws Exception { final URI uri = new URIBuilder() - .setScheme("http") + .setScheme(yqlConfiguration.isHttps() ? "https" : "http") .setHost("query.yahooapis.com") .setPath("/v1/public/yql") - .setParameter("format", format) - .setParameter("diagnostics", Boolean.toString(diagnostics)) - .setParameter("env", "store://datatables.org/alltableswithkeys") - .setParameter("callback", callback) - .setParameter("q", query) + .setParameters(buildParameters(yqlConfiguration)) .build(); LOG.debug("YQL query: {}", uri); @@ -61,4 +62,23 @@ public class YqlClient { return yqlResponse; } } + + private List<NameValuePair> buildParameters(final YqlConfiguration yqlConfiguration) { + final List<NameValuePair> nameValuePairs = new ArrayList<>(); + nameValuePairs.add(new BasicNameValuePair("q", yqlConfiguration.getQuery())); + nameValuePairs.add(new BasicNameValuePair("format", yqlConfiguration.getFormat())); + nameValuePairs.add(new BasicNameValuePair("callback", yqlConfiguration.getCallback())); + if (yqlConfiguration.getCrossProduct() != null) { + nameValuePairs.add(new BasicNameValuePair("crossProduct", yqlConfiguration.getCrossProduct())); + } + nameValuePairs.add(new BasicNameValuePair("diagnostics", Boolean.toString(yqlConfiguration.isDiagnostics()))); + nameValuePairs.add(new BasicNameValuePair("debug", Boolean.toString(yqlConfiguration.isDebug()))); + if (yqlConfiguration.getEnv() != null) { + nameValuePairs.add(new BasicNameValuePair("env", yqlConfiguration.getEnv())); + } + if (yqlConfiguration.getJsonCompat() != null) { + nameValuePairs.add(new BasicNameValuePair("jsonCompat", yqlConfiguration.getJsonCompat())); + } + return nameValuePairs; + } } \ No newline at end of file diff --git a/components/camel-yql/src/main/java/org/apache/camel/component/yql/configuration/YqlConfiguration.java b/components/camel-yql/src/main/java/org/apache/camel/component/yql/configuration/YqlConfiguration.java index 73ff453..b26e347 100644 --- a/components/camel-yql/src/main/java/org/apache/camel/component/yql/configuration/YqlConfiguration.java +++ b/components/camel-yql/src/main/java/org/apache/camel/component/yql/configuration/YqlConfiguration.java @@ -21,33 +21,52 @@ import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriParams; import org.apache.camel.spi.UriPath; +/** + * YQL configuration that should reflect https://developer.yahoo.com/yql/guide/users-overview.html + */ @UriParams public class YqlConfiguration { - @UriPath(label="producer", description = "The YQL query to be sent.") + @UriPath(label = "producer", description = "The YQL statement to execute.") @Metadata(required = "true") private String query; - @UriParam(label="producer", enums = "json,xml", defaultValue = "json", description = "The expected format. Can only be json or xml.") + @UriParam(label = "producer", enums = "json,xml", defaultValue = "json", description = "The expected format. Allowed values: xml or json.") private String format = "json"; - @UriParam(label="producer", defaultValue = "false", description = "If true, the option will be included in the HTTP request to YQL and the response will contain some diagnostics data.") + @UriParam(label = "producer", description = "The name of the JavaScript callback function for JSONP format. If callback is set and if format=json, then the response format is JSON. For more " + + "information on using XML instead of JSON, see JSONP-X.") + private String callback = ""; + + @UriParam(label = "producer", description = "When given the value optimized, the projected fields in SELECT statements that may be returned in separate item elements in the response are " + + "optimized to be in a single item element instead. The only allowed value is optimized.") + private String crossProduct; + + @UriParam(label = "producer", defaultValue = "false", description = "If true, diagnostic information is returned with the response.") private boolean diagnostics = false; - @UriParam(label="producer", description = "If specified, the option will be included in the HTTP request to YQL. If the format is json, then the response will contain a JSONP callback method. " - + "If the format is xml, then the response will contain a JSONP-X callback method. More information: https://developer.yahoo.com/yql/guide/response.html") - private String callback = ""; + @UriParam(label = "producer", defaultValue = "false", description = "If true, and if diagnostic is set to true, debug data is returned with the response.") + private boolean debug = false; + + @UriParam(label = "producer", description = "Allows you to use multiple Open Data Tables through a YQL environment file.") + private String env; + + @UriParam(label = "producer", description = "Enables lossless JSON processing. The only allowed value is new.") + private String jsonCompat; @UriParam(label = "producer", defaultValue = "true", description = "Option to disable throwing the YqlHttpException in case of failed responses from the remote server. " + "This allows you to get all responses regardless of the HTTP status code.") private boolean throwExceptionOnFailure = true; + @UriParam(label = "producer", defaultValue = "true", description = "Option to use HTTPS to communicate with YQL.") + private boolean https = true; + public String getQuery() { return query; } /** - * The YQL query to be sent. + * The YQL statement to execute. */ public void setQuery(final String query) { this.query = query; @@ -58,33 +77,81 @@ public class YqlConfiguration { } /** - * The expected format. Can only be json or xml. + * The expected format. Allowed values: xml or json. */ public void setFormat(final String format) { this.format = format; } + public String getCallback() { + return callback; + } + + /** + * The name of the JavaScript callback function for JSONP format. If callback is set and if format=json, then the response format is JSON. For more + * information on using XML instead of JSON, see JSONP-X. https://developer.yahoo.com/yql/guide/response.html + */ + public void setCallback(final String callback) { + this.callback = callback; + } + + public String getCrossProduct() { + return crossProduct; + } + + /** + * When given the value optimized, the projected fields in SELECT statements that may be returned in separate item elements in the response are optimized to be in a single item element instead. + * The only allowed value is optimized. More information https://developer.yahoo.com/yql/guide/response.html#response-optimizing= + */ + public void setCrossProduct(final String crossProduct) { + this.crossProduct = crossProduct; + } + public boolean isDiagnostics() { return diagnostics; } /** - * If true, the option will be included in the HTTP request to YQL and the response will contain some diagnostics data. + * If true, diagnostic information is returned with the response. */ public void setDiagnostics(final boolean diagnostics) { this.diagnostics = diagnostics; } - public String getCallback() { - return callback; + public boolean isDebug() { + return debug; } /** - * If specified, the option will be included in the HTTP request to YQL. If the format is json, then the response will contain a JSONP callback method. - * If the format is xml, then the response will contain a JSONP-X callback method. More information: https://developer.yahoo.com/yql/guide/response.html + * If true, and if diagnostic is set to true, debug data is returned with the response. + * More information: https://developer.yahoo.com/yql/guide/dev-external_tables.html#odt-enable-logging= */ - public void setCallback(final String callback) { - this.callback = callback; + public void setDebug(final boolean debug) { + this.debug = debug; + } + + public String getEnv() { + return env; + } + + /** + * Allows you to use multiple Open Data Tables through a YQL environment file. + * More information https://developer.yahoo.com/yql/guide/yql_storage.html#using-records-env-files= + */ + public void setEnv(final String env) { + this.env = env; + } + + public String getJsonCompat() { + return jsonCompat; + } + + /** + * Enables lossless JSON processing. The only allowed value is new. + * More information https://developer.yahoo.com/yql/guide/response.html#json-to-json= + */ + public void setJsonCompat(final String jsonCompat) { + this.jsonCompat = jsonCompat; } public boolean isThrowExceptionOnFailure() { @@ -98,4 +165,15 @@ public class YqlConfiguration { public void setThrowExceptionOnFailure(final boolean throwExceptionOnFailure) { this.throwExceptionOnFailure = throwExceptionOnFailure; } + + public boolean isHttps() { + return https; + } + + /** + * Option to use HTTPS to communicate with YQL. + */ + public void setHttps(final boolean https) { + this.https = https; + } } diff --git a/components/camel-yql/src/main/java/org/apache/camel/component/yql/configuration/YqlConfigurationValidator.java b/components/camel-yql/src/main/java/org/apache/camel/component/yql/configuration/YqlConfigurationValidator.java index 0ab0ff7..124d8f7 100644 --- a/components/camel-yql/src/main/java/org/apache/camel/component/yql/configuration/YqlConfigurationValidator.java +++ b/components/camel-yql/src/main/java/org/apache/camel/component/yql/configuration/YqlConfigurationValidator.java @@ -32,5 +32,13 @@ public final class YqlConfigurationValidator { if (!StringUtils.equalsAny(configuration.getFormat(), "json", "xml")) { throw new YqlException("<format> is not valid!"); } + + if (configuration.getCrossProduct() != null && !configuration.getCrossProduct().equals("optimized")) { + throw new YqlException("<crossProduct> is not valid!"); + } + + if (configuration.getJsonCompat() != null && !configuration.getJsonCompat().equals("new")) { + throw new YqlException("<jsonCompat> is not valid!"); + } } } diff --git a/components/camel-yql/src/test/java/org/apache/camel/component/yql/YqlComponentIntegrationTest.java b/components/camel-yql/src/test/java/org/apache/camel/component/yql/YqlComponentIntegrationTest.java index 6bbf8ee..e8164e7 100644 --- a/components/camel-yql/src/test/java/org/apache/camel/component/yql/YqlComponentIntegrationTest.java +++ b/components/camel-yql/src/test/java/org/apache/camel/component/yql/YqlComponentIntegrationTest.java @@ -16,6 +16,13 @@ */ package org.apache.camel.component.yql; +import static org.apache.camel.component.yql.YqlProducer.CAMEL_YQL_HTTP_REQUEST; +import static org.apache.camel.component.yql.YqlProducer.CAMEL_YQL_HTTP_STATUS; +import static org.hamcrest.CoreMatchers.containsString; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import org.apache.camel.CamelExecutionException; import org.apache.camel.EndpointInject; import org.apache.camel.Exchange; import org.apache.camel.Produce; @@ -23,46 +30,133 @@ 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.apache.http.HttpStatus; +import org.junit.Rule; import org.junit.Test; - -import static org.apache.camel.component.yql.YqlProducer.CAMEL_YQL_HTTP_REQUEST; -import static org.apache.camel.component.yql.YqlProducer.CAMEL_YQL_HTTP_STATUS; -import static org.hamcrest.CoreMatchers.containsString; +import org.junit.rules.ExpectedException; public class YqlComponentIntegrationTest extends CamelTestSupport { - private static final String QUERY = "select * from yahoo.finance.quotes where symbol in ('GOOG')"; + private static final String FINANCE_QUERY = "select symbol, Ask, Bid, from yahoo.finance.quotes where symbol in ('GOOG')"; + private static final String WEATHER_QUERY = "select wind, atmosphere from weather.forecast where woeid in (select woeid from geo.places(1) where text='chicago, il')"; + private static final String BOOK_QUERY = "select * from google.books where q='barack obama' and maxResults=1"; private static final String CALLBACK = "yqlCallback"; + private static final String ENV = "store://datatables.org/alltableswithkeys"; + + @Rule + public final ExpectedException thrown = ExpectedException.none(); + + @Produce(uri = "direct:startFinance") + private ProducerTemplate templateFinance; - @Produce(uri = "direct:start") - private ProducerTemplate template; + @EndpointInject(uri = "mock:resultFinance") + private MockEndpoint endFinance; - @EndpointInject(uri = "mock:result") - private MockEndpoint end; + @Produce(uri = "direct:startWeather") + private ProducerTemplate templateWeather; + + @EndpointInject(uri = "mock:resultWeather") + private MockEndpoint endWeather; + + @Produce(uri = "direct:startBook") + private ProducerTemplate templateBook; + + @EndpointInject(uri = "mock:resultBook") + private MockEndpoint endBook; + + @Produce(uri = "direct:startFail") + private ProducerTemplate templateFail; @Override protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { - from("direct:start") - .to("yql://" + QUERY + "?format=json&callback=" + CALLBACK) - .to("mock:result"); + from("direct:startFinance") + .to("yql://" + FINANCE_QUERY + "?format=json&callback=" + CALLBACK + "&https=false&env=" + ENV) + .to("mock:resultFinance"); + + from("direct:startWeather") + .to("yql://" + WEATHER_QUERY) + .to("mock:resultWeather"); + + from("direct:startBook") + .to("yql://" + BOOK_QUERY + "?format=xml&crossProduct=optimized&env=" + ENV) + .to("mock:resultBook"); + + from("direct:startFail") + .to("yql://" + FINANCE_QUERY) + .to("mock:resultBook"); } }; } @Test - public void testFinanceQuote() { - template.sendBody(""); + public void testFinanceQuote() throws UnsupportedEncodingException { + // when + templateFinance.sendBody(""); - final Exchange exchange = end.getReceivedExchanges().get(0); + // then + final Exchange exchange = endFinance.getReceivedExchanges().get(0); final String body = exchange.getIn().getBody(String.class); final Integer status = exchange.getIn().getHeader(CAMEL_YQL_HTTP_STATUS, Integer.class); final String httpRequest = exchange.getIn().getHeader(CAMEL_YQL_HTTP_REQUEST, String.class); + assertThat(httpRequest, containsString("http")); + assertThat(httpRequest, containsString("q=" + URLEncoder.encode(FINANCE_QUERY, "UTF-8"))); + assertThat(httpRequest, containsString("format=json")); + assertThat(httpRequest, containsString("callback=" + CALLBACK)); + assertThat(httpRequest, containsString("diagnostics=false")); + assertThat(httpRequest, containsString("debug=false")); + assertThat(httpRequest, containsString("env=" + URLEncoder.encode(ENV, "UTF-8"))); assertNotNull(body); assertThat(body, containsString(CALLBACK + "(")); - assertNotNull(status); - assertEquals("http://query.yahooapis.com/v1/public/yql?format=json&diagnostics=false&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=yqlCallback&q=select+*+from+" - + "yahoo.finance.quotes+where+symbol+in+%28%27GOOG%27%29", httpRequest); + assertEquals(HttpStatus.SC_OK, status.intValue()); + } + + @Test + public void testWeather() throws UnsupportedEncodingException { + // when + templateWeather.sendBody(""); + + // then + final Exchange exchange = endWeather.getReceivedExchanges().get(0); + final String body = exchange.getIn().getBody(String.class); + final Integer status = exchange.getIn().getHeader(CAMEL_YQL_HTTP_STATUS, Integer.class); + final String httpRequest = exchange.getIn().getHeader(CAMEL_YQL_HTTP_REQUEST, String.class); + assertThat(httpRequest, containsString("https")); + assertThat(httpRequest, containsString("q=" + URLEncoder.encode(WEATHER_QUERY, "UTF-8"))); + assertThat(httpRequest, containsString("format=json")); + assertThat(httpRequest, containsString("diagnostics=false")); + assertThat(httpRequest, containsString("debug=false")); + assertNotNull(body); + assertEquals(HttpStatus.SC_OK, status.intValue()); + } + + @Test + public void testBook() throws UnsupportedEncodingException { + // when + templateBook.sendBody(""); + + // then + final Exchange exchange = endBook.getReceivedExchanges().get(0); + final String body = exchange.getIn().getBody(String.class); + final Integer status = exchange.getIn().getHeader(CAMEL_YQL_HTTP_STATUS, Integer.class); + final String httpRequest = exchange.getIn().getHeader(CAMEL_YQL_HTTP_REQUEST, String.class); + assertThat(httpRequest, containsString("https")); + assertThat(httpRequest, containsString("q=" + URLEncoder.encode(BOOK_QUERY, "UTF-8"))); + assertThat(httpRequest, containsString("format=xml")); + assertThat(httpRequest, containsString("diagnostics=false")); + assertThat(httpRequest, containsString("debug=false")); + assertThat(httpRequest, containsString("crossProduct=optimized")); + assertNotNull(body); + assertEquals(HttpStatus.SC_OK, status.intValue()); + } + + @Test + public void testFail() throws UnsupportedEncodingException { + // then + thrown.expect(CamelExecutionException.class); + + // when + templateFail.sendBody(""); } } diff --git a/components/camel-yql/src/test/java/org/apache/camel/component/yql/configuration/YqlConfigurationValidatorTest.java b/components/camel-yql/src/test/java/org/apache/camel/component/yql/configuration/YqlConfigurationValidatorTest.java index e7a6ce0..af7fa58 100644 --- a/components/camel-yql/src/test/java/org/apache/camel/component/yql/configuration/YqlConfigurationValidatorTest.java +++ b/components/camel-yql/src/test/java/org/apache/camel/component/yql/configuration/YqlConfigurationValidatorTest.java @@ -27,11 +27,13 @@ public class YqlConfigurationValidatorTest { public final ExpectedException thrown = ExpectedException.none(); @Test - public void testGoodQuery() { + public void testValidQuery() { // given final YqlConfiguration yqlConfiguration = new YqlConfiguration(); yqlConfiguration.setQuery("select * from ..."); yqlConfiguration.setFormat("json"); + yqlConfiguration.setCrossProduct("optimized"); + yqlConfiguration.setJsonCompat("new"); // when YqlConfigurationValidator.validateProperties(yqlConfiguration); @@ -95,4 +97,37 @@ public class YqlConfigurationValidatorTest { // when YqlConfigurationValidator.validateProperties(yqlConfiguration); } + + @Test + public void testWrongCrossProduct() { + // then + thrown.expect(YqlException.class); + thrown.expectMessage("<crossProduct> is not valid!"); + + // given + final YqlConfiguration yqlConfiguration = new YqlConfiguration(); + yqlConfiguration.setQuery("query"); + yqlConfiguration.setFormat("xml"); + yqlConfiguration.setCrossProduct("optimizedddd"); + + // when + YqlConfigurationValidator.validateProperties(yqlConfiguration); + } + + @Test + public void testWrongJsonCompat() { + // then + thrown.expect(YqlException.class); + thrown.expectMessage("<jsonCompat> is not valid!"); + + // given + final YqlConfiguration yqlConfiguration = new YqlConfiguration(); + yqlConfiguration.setQuery("query"); + yqlConfiguration.setFormat("xml"); + yqlConfiguration.setCrossProduct("optimized"); + yqlConfiguration.setJsonCompat("neww"); + + // when + YqlConfigurationValidator.validateProperties(yqlConfiguration); + } } diff --git a/components/readme.adoc b/components/readme.adoc index ca1a164..945fb13 100644 --- a/components/readme.adoc +++ b/components/readme.adoc @@ -1044,7 +1044,7 @@ Miscellaneous Components ^^^^^^^^^^^^^^^^^^^^^^^^ // others: START -Number of Miscellaneous Components: 38 in 38 JAR artifacts (14 deprecated) +Number of Miscellaneous Components: 37 in 37 JAR artifacts (13 deprecated) [width="100%",cols="4,1,5",options="header"] |=== @@ -1100,8 +1100,6 @@ Number of Miscellaneous Components: 38 in 38 JAR artifacts (14 deprecated) | link:camel-spring-cloud-netflix/src/main/docs/spring-cloud-netflix.adoc[Spring Cloud Netflix] (camel-spring-cloud-netflix) | 2.19 | Camel Cloud integration with Spring Cloud Netflix -| link:camel-spring-dm/src/main/docs/spring-dm.adoc[Spring DM] (camel-spring-dm) | 2.18 | *deprecated* Camel SpringDM (OSGi) XML DSL - | link:camel-spring-javaconfig/src/main/docs/spring-javaconfig.adoc[Spring Java Configuration] (camel-spring-javaconfig) | 2.0 | Using Camel with Spring Java Configuration | link:camel-spring-security/src/main/docs/spring-security.adoc[Spring Security] (camel-spring-security) | 2.3 | Security using Spring Security diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md index b55a6a5..b1dc1ca 100644 --- a/docs/user-manual/en/SUMMARY.md +++ b/docs/user-manual/en/SUMMARY.md @@ -417,7 +417,6 @@ * [Spring Boot](spring-boot.adoc) * [Spring Cloud](spring-cloud.adoc) * [Spring Cloud Netflix](spring-cloud-netflix.adoc) - * [Spring DM](spring-dm.adoc) * [Spring Java Configuration](spring-javaconfig.adoc) * [Spring Security](spring-security.adoc) * [Swagger](swagger.adoc) diff --git a/platforms/spring-boot/components-starter/camel-yql-starter/src/main/java/org/apache/camel/component/yql/springboot/YqlComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-yql-starter/src/main/java/org/apache/camel/component/yql/springboot/YqlComponentConfiguration.java index 9fccdf3..4b736b5 100644 --- a/platforms/spring-boot/components-starter/camel-yql-starter/src/main/java/org/apache/camel/component/yql/springboot/YqlComponentConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-yql-starter/src/main/java/org/apache/camel/component/yql/springboot/YqlComponentConfiguration.java @@ -18,7 +18,9 @@ package org.apache.camel.component.yql.springboot; import javax.annotation.Generated; import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon; +import org.apache.http.conn.HttpClientConnectionManager; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; /** * Camel Yahoo Query Language Component @@ -32,12 +34,26 @@ public class YqlComponentConfiguration ComponentConfigurationPropertiesCommon { /** + * Set the connection manager. + */ + @NestedConfigurationProperty + private HttpClientConnectionManager connectionManager; + /** * Whether the component should resolve property placeholders on itself when * starting. Only properties which are of String type can use property * placeholders. */ private Boolean resolvePropertyPlaceholders = true; + public HttpClientConnectionManager getConnectionManager() { + return connectionManager; + } + + public void setConnectionManager( + HttpClientConnectionManager connectionManager) { + this.connectionManager = connectionManager; + } + public Boolean getResolvePropertyPlaceholders() { return resolvePropertyPlaceholders; } -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
