CAMEL-9273: camel-weather not support configuring a http proxy. Thanks to Arno Noordover for the patch.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/10c04b7b Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/10c04b7b Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/10c04b7b Branch: refs/heads/kube-lb Commit: 10c04b7bdb8468fdeb84270df931840202558bfd Parents: eaab788 Author: Claus Ibsen <davscl...@apache.org> Authored: Sun May 15 10:27:10 2016 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Mon May 16 09:59:33 2016 +0200 ---------------------------------------------------------------------- .../component/weather/WeatherComponent.java | 82 ++++++++++++++ .../component/weather/WeatherConfiguration.java | 110 ++++++++++++++++++- .../component/weather/WeatherConsumer.java | 3 +- .../component/weather/WeatherProducer.java | 2 +- .../FreeGeoIpGeoLocationProvider.java | 14 ++- .../AuthenticationHttpClientConfigurer.java | 54 +++++++++ .../weather/http/AuthenticationMethod.java | 27 +++++ .../weather/http/CompositeHttpConfigurer.java | 50 +++++++++ .../weather/http/HttpClientConfigurer.java | 36 ++++++ .../weather/CurrentWeatherConsumerTest.java | 3 +- 10 files changed, 370 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherComponent.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherComponent.java index 3ddae29..557af0f 100644 --- a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherComponent.java +++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherComponent.java @@ -20,7 +20,15 @@ import java.util.Map; import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; +import org.apache.camel.component.weather.http.AuthenticationHttpClientConfigurer; +import org.apache.camel.component.weather.http.AuthenticationMethod; +import org.apache.camel.component.weather.http.CompositeHttpConfigurer; +import org.apache.camel.component.weather.http.HttpClientConfigurer; import org.apache.camel.impl.UriEndpointComponent; +import org.apache.camel.util.ObjectHelper; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpConnectionManager; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; /** * A <a href="http://camel.apache.org/weather.html">Weather Component</a>. @@ -29,6 +37,8 @@ import org.apache.camel.impl.UriEndpointComponent; */ public class WeatherComponent extends UriEndpointComponent { + private HttpClient httpClient; + public WeatherComponent() { super(WeatherEndpoint.class); } @@ -44,7 +54,79 @@ public class WeatherComponent extends UriEndpointComponent { // and then override from parameters setProperties(configuration, parameters); + httpClient = createHttpClient(configuration); WeatherEndpoint endpoint = new WeatherEndpoint(uri, this, configuration); return endpoint; } + + private HttpClient createHttpClient(WeatherConfiguration configuration) { + HttpConnectionManager connectionManager = configuration.getHttpConnectionManager(); + if (connectionManager == null) { + connectionManager = new MultiThreadedHttpConnectionManager(); + } + HttpClient httpClient = new HttpClient(connectionManager); + + if (configuration.getProxyHost() != null && configuration.getProxyPort() != null) { + httpClient.getHostConfiguration().setProxy(configuration.getProxyHost(), + configuration.getProxyPort()); + } + + if (configuration.getProxyAuthUsername() != null && configuration.getProxyAuthMethod() == null) { + throw new IllegalArgumentException("Option proxyAuthMethod must be provided to use proxy authentication"); + } + + CompositeHttpConfigurer configurer = new CompositeHttpConfigurer(); + if (configuration.getProxyAuthMethod() != null) { + configureProxyAuth(configurer, + configuration.getProxyAuthMethod(), + configuration.getProxyAuthUsername(), + configuration.getProxyAuthPassword(), + configuration.getProxyAuthDomain(), + configuration.getProxyAuthHost()); + } + + configurer.configureHttpClient(httpClient); + + return httpClient; + } + + private HttpClientConfigurer configureProxyAuth(CompositeHttpConfigurer configurer, + String authMethod, + String username, + String password, + String domain, + String host) { + // no proxy auth is in use + if (username == null && authMethod == null) { + return configurer; + } + + // validate mandatory options given + if (username != null && authMethod == null) { + throw new IllegalArgumentException("Option proxyAuthMethod must be provided to use proxy authentication"); + } + + ObjectHelper.notNull(authMethod, "proxyAuthMethod"); + ObjectHelper.notNull(username, "proxyAuthUsername"); + ObjectHelper.notNull(password, "proxyAuthPassword"); + + AuthenticationMethod auth = getCamelContext().getTypeConverter().convertTo(AuthenticationMethod.class, authMethod); + + if (auth == AuthenticationMethod.Basic || auth == AuthenticationMethod.Digest) { + configurer.addConfigurer(AuthenticationHttpClientConfigurer.basicAutenticationConfigurer(true, username, password)); + return configurer; + } else if (auth == AuthenticationMethod.NTLM) { + // domain is mandatory for NTML + ObjectHelper.notNull(domain, "proxyAuthDomain"); + configurer.addConfigurer(AuthenticationHttpClientConfigurer.ntlmAutenticationConfigurer(true, username, password, domain, host)); + return configurer; + } + + throw new IllegalArgumentException("Unknown proxyAuthMethod " + authMethod); + + } + + public HttpClient getHttpClient() { + return httpClient; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConfiguration.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConfiguration.java index fefc223..c569ef3 100644 --- a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConfiguration.java +++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConfiguration.java @@ -23,6 +23,7 @@ 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.commons.httpclient.HttpConnectionManager; import static org.apache.camel.component.weather.WeatherLanguage.en; import static org.apache.camel.component.weather.WeatherMode.JSON; @@ -62,11 +63,28 @@ public class WeatherConfiguration { @UriParam private String headerName; + @UriParam(label = "proxy") + private String proxyHost; + @UriParam(label = "proxy") + private Integer proxyPort; + @UriParam(label = "proxy") + private String proxyAuthMethod; + @UriParam(label = "proxy") + private String proxyAuthUsername; + @UriParam(label = "proxy") + private String proxyAuthPassword; + @UriParam(label = "proxy") + private String proxyAuthDomain; + @UriParam(label = "proxy") + private String proxyAuthHost; + @UriParam(label = "advanced") + private HttpConnectionManager httpConnectionManager; + + public WeatherConfiguration(WeatherComponent component) { this.component = notNull(component, "component"); weatherQuery = new WeatherQuery(this); - FreeGeoIpGeoLocationProvider geoLocationProvider = new FreeGeoIpGeoLocationProvider(); - geoLocationProvider.setCamelContext(component.getCamelContext()); + FreeGeoIpGeoLocationProvider geoLocationProvider = new FreeGeoIpGeoLocationProvider(component); weatherQuery.setGeoLocationProvider(geoLocationProvider); } @@ -236,4 +254,92 @@ public class WeatherConfiguration { public void setZoom(Integer zoom) { this.zoom = zoom; } + + public HttpConnectionManager getHttpConnectionManager() { + return httpConnectionManager; + } + + /** + * To use a custom HttpConnectionManager to manage connections + */ + public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) { + this.httpConnectionManager = httpConnectionManager; + } + + public String getProxyHost() { + return proxyHost; + } + + /** + * The proxy host name + */ + public void setProxyHost(String proxyHost) { + this.proxyHost = proxyHost; + } + + public Integer getProxyPort() { + return proxyPort; + } + + /** + * The proxy port number + */ + public void setProxyPort(Integer proxyPort) { + this.proxyPort = proxyPort; + } + + public String getProxyAuthMethod() { + return proxyAuthMethod; + } + + /** + * Authentication method for proxy, either as Basic, Digest or NTLM. + */ + public void setProxyAuthMethod(String proxyAuthMethod) { + this.proxyAuthMethod = proxyAuthMethod; + } + + public String getProxyAuthUsername() { + return proxyAuthUsername; + } + + /** + * Username for proxy authentication + */ + public void setProxyAuthUsername(String proxyAuthUsername) { + this.proxyAuthUsername = proxyAuthUsername; + } + + public String getProxyAuthPassword() { + return proxyAuthPassword; + } + + /** + * Password for proxy authentication + */ + public void setProxyAuthPassword(String proxyAuthPassword) { + this.proxyAuthPassword = proxyAuthPassword; + } + + public String getProxyAuthDomain() { + return proxyAuthDomain; + } + + /** + * Domain for proxy NTLM authentication + */ + public void setProxyAuthDomain(String proxyAuthDomain) { + this.proxyAuthDomain = proxyAuthDomain; + } + + public String getProxyAuthHost() { + return proxyAuthHost; + } + + /** + * Optional host for proxy NTLM authentication + */ + public void setProxyAuthHost(String proxyAuthHost) { + this.proxyAuthHost = proxyAuthHost; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConsumer.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConsumer.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConsumer.java index 591f86d..4255720 100644 --- a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConsumer.java +++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherConsumer.java @@ -44,7 +44,7 @@ public class WeatherConsumer extends ScheduledPollConsumer { @Override protected int poll() throws Exception { LOG.debug("Going to execute the Weather query {}", query); - HttpClient httpClient = new HttpClient(); + HttpClient httpClient = ((WeatherComponent) getEndpoint().getComponent()).getHttpClient(); GetMethod getMethod = new GetMethod(query); try { int status = httpClient.executeMethod(getMethod); @@ -75,4 +75,5 @@ public class WeatherConsumer extends ScheduledPollConsumer { getMethod.releaseConnection(); } } + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherProducer.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherProducer.java index 65f9706..e506f4c 100644 --- a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherProducer.java +++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherProducer.java @@ -45,7 +45,7 @@ public class WeatherProducer extends DefaultProducer { q = getEndpoint().getConfiguration().getQuery(location); } - HttpClient httpClient = new HttpClient(); + HttpClient httpClient = ((WeatherComponent) getEndpoint().getComponent()).getHttpClient(); GetMethod method = new GetMethod(q); try { log.debug("Going to execute the Weather query {}", q); http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/main/java/org/apache/camel/component/weather/geolocation/FreeGeoIpGeoLocationProvider.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/geolocation/FreeGeoIpGeoLocationProvider.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/geolocation/FreeGeoIpGeoLocationProvider.java index 2d68a1f..0842194 100644 --- a/components/camel-weather/src/main/java/org/apache/camel/component/weather/geolocation/FreeGeoIpGeoLocationProvider.java +++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/geolocation/FreeGeoIpGeoLocationProvider.java @@ -17,6 +17,7 @@ package org.apache.camel.component.weather.geolocation; import org.apache.camel.CamelContext; +import org.apache.camel.component.weather.WeatherComponent; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; @@ -28,18 +29,22 @@ import static org.apache.camel.util.ObjectHelper.notNull; public class FreeGeoIpGeoLocationProvider implements GeoLocationProvider { - private CamelContext camelContext; + private final WeatherComponent component; + + public FreeGeoIpGeoLocationProvider(WeatherComponent component) { + this.component = component; + } @Override public GeoLocation getCurrentGeoLocation() throws Exception { - HttpClient httpClient = new HttpClient(); + HttpClient httpClient = component.getHttpClient(); GetMethod getMethod = new GetMethod("http://freegeoip.io/json/"); try { int statusCode = httpClient.executeMethod(getMethod); if (statusCode != HttpStatus.SC_OK) { throw new IllegalStateException("Got the unexpected http-status '" + getMethod.getStatusLine() + "' for the geolocation"); } - String geoLocation = camelContext.getTypeConverter().mandatoryConvertTo(String.class, getMethod.getResponseBodyAsStream()); + String geoLocation = component.getCamelContext().getTypeConverter().mandatoryConvertTo(String.class, getMethod.getResponseBodyAsStream()); if (isEmpty(geoLocation)) { throw new IllegalStateException("Got the unexpected value '" + geoLocation + "' for the geolocation"); } @@ -56,7 +61,4 @@ public class FreeGeoIpGeoLocationProvider implements GeoLocationProvider { } - public void setCamelContext(CamelContext camelContext) { - this.camelContext = camelContext; - } } http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/AuthenticationHttpClientConfigurer.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/AuthenticationHttpClientConfigurer.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/AuthenticationHttpClientConfigurer.java new file mode 100644 index 0000000..daf93bb --- /dev/null +++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/AuthenticationHttpClientConfigurer.java @@ -0,0 +1,54 @@ +/** + * 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.weather.http; + +import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.NTCredentials; +import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; + + +public final class AuthenticationHttpClientConfigurer implements HttpClientConfigurer { + + private final boolean proxy; + private final Credentials credentials; + + private AuthenticationHttpClientConfigurer(boolean proxy, Credentials credentials) { + this.proxy = proxy; + this.credentials = credentials; + } + + @Override + public HttpClient configureHttpClient(HttpClient client) { + if (proxy) { + client.getState().setProxyCredentials(AuthScope.ANY, this.credentials); + } else { + client.getState().setCredentials(AuthScope.ANY, this.credentials); + } + + return client; + } + + public static HttpClientConfigurer basicAutenticationConfigurer(boolean proxy, String user, String pwd) { + return new AuthenticationHttpClientConfigurer(proxy, new UsernamePasswordCredentials(user, pwd)); + } + + public static HttpClientConfigurer ntlmAutenticationConfigurer(boolean proxy, String user, String pwd, String domain, String host) { + return new AuthenticationHttpClientConfigurer(proxy, new NTCredentials(user, pwd, host, domain)); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/AuthenticationMethod.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/AuthenticationMethod.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/AuthenticationMethod.java new file mode 100644 index 0000000..4627512 --- /dev/null +++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/AuthenticationMethod.java @@ -0,0 +1,27 @@ +/** + * 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.weather.http; + +/** + * Authentication policy + * + * @version + */ +public enum AuthenticationMethod { + + Basic, Digest, NTLM +} http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/CompositeHttpConfigurer.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/CompositeHttpConfigurer.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/CompositeHttpConfigurer.java new file mode 100644 index 0000000..97f2816 --- /dev/null +++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/CompositeHttpConfigurer.java @@ -0,0 +1,50 @@ +/** + * 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.weather.http; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.httpclient.HttpClient; + +public class CompositeHttpConfigurer implements HttpClientConfigurer { + + private final List<HttpClientConfigurer> configurers = new ArrayList<>(); + + public void addConfigurer(HttpClientConfigurer configurer) { + if (configurer != null) { + configurers.add(configurer); + } + } + + public void removeConfigurer(HttpClientConfigurer configurer) { + configurers.remove(configurer); + } + + public HttpClient configureHttpClient(HttpClient client) { + for (HttpClientConfigurer configurer : configurers) { + configurer.configureHttpClient(client); + } + + return client; + } + + public List<HttpClientConfigurer> getConfigurers() { + return Collections.unmodifiableList(configurers); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/HttpClientConfigurer.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/HttpClientConfigurer.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/HttpClientConfigurer.java new file mode 100644 index 0000000..0aa5b95 --- /dev/null +++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/http/HttpClientConfigurer.java @@ -0,0 +1,36 @@ +/** + * 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.weather.http; + + +import org.apache.commons.httpclient.HttpClient; + +/** + * A pluggable strategy for configuring the HttpClient used by this component + * + * @version + */ +public interface HttpClientConfigurer { + + /** + * Configure the HttpClient such as setting the authentication or proxying details + * + * @param client the client + * @return the client + */ + HttpClient configureHttpClient(HttpClient client); +} http://git-wip-us.apache.org/repos/asf/camel/blob/10c04b7b/components/camel-weather/src/test/java/org/apache/camel/component/weather/CurrentWeatherConsumerTest.java ---------------------------------------------------------------------- diff --git a/components/camel-weather/src/test/java/org/apache/camel/component/weather/CurrentWeatherConsumerTest.java b/components/camel-weather/src/test/java/org/apache/camel/component/weather/CurrentWeatherConsumerTest.java index d50bf85..44791b7 100644 --- a/components/camel-weather/src/test/java/org/apache/camel/component/weather/CurrentWeatherConsumerTest.java +++ b/components/camel-weather/src/test/java/org/apache/camel/component/weather/CurrentWeatherConsumerTest.java @@ -34,7 +34,8 @@ public class CurrentWeatherConsumerTest extends BaseWeatherConsumerTest { return new RouteBuilder() { @Override public void configure() throws Exception { - from("weather:foo?appid=9162755b2efa555823cfe0451d7fff38&lon=4&lat=52&rightLon=6&topLat=54").to("mock:result"); + from("weather:foo?appid=9162755b2efa555823cfe0451d7fff38&lon=4&lat=52&mode=xml"). + to("mock:result"); } }; }