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 2016/05/06 10:05:32 UTC
camel git commit: CAMEL-9273: More options to weather. Thanks to Arno
Noordover for the patch.
Repository: camel
Updated Branches:
refs/heads/master 31e2df5e7 -> 426922a26
CAMEL-9273: More options to weather. 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/426922a2
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/426922a2
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/426922a2
Branch: refs/heads/master
Commit: 426922a2607420ba0175da27145d520e80120291
Parents: 31e2df5
Author: Claus Ibsen <da...@apache.org>
Authored: Fri May 6 12:05:04 2016 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri May 6 12:05:04 2016 +0200
----------------------------------------------------------------------
components/camel-weather/readme.MD | 27 ++++
.../component/weather/WeatherConfiguration.java | 98 ++++++++-------
.../component/weather/WeatherLanguage.java | 46 +++++++
.../camel/component/weather/WeatherQuery.java | 125 +++++++++++++++++++
.../weather/CurrentWeatherConsumerTest.java | 11 +-
.../src/test/resources/log4j.properties | 2 +-
6 files changed, 262 insertions(+), 47 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/426922a2/components/camel-weather/readme.MD
----------------------------------------------------------------------
diff --git a/components/camel-weather/readme.MD b/components/camel-weather/readme.MD
new file mode 100644
index 0000000..0c680f6
--- /dev/null
+++ b/components/camel-weather/readme.MD
@@ -0,0 +1,27 @@
+#Description of Weather API
+
+##Types of queries
+
+There are five type of queries:
+
+1. current weather (contexts weather, group, find and box/city);
+2. forecast (5 days per 3 hours, context forecast)
+3. forecast/daily (context forecast/daily); you must provide cnt parameter
+4. history (context history/city and maybe also history/station)
+5. station (contexts station, box/station and station/find)
+
+##Locations
+
+1. by name of the city and the country code (q={city name},{country code})
+2. by id of the city (id={city ID}); The current weather can also be
+asked for a group of id's using the context group
+3. by latitude and longtitude (lat={lat}&lon={lon})
+4. by box (bbox=12,32,15,37,10), you must also provide cluster=yes/no; context
+must be box/city or box/station
+5. find cities/station around location defined by lat/lon; context
+must be find or station/find. You must provide a cnt parameter.
+
+
+##Note
+The history by station isn't documented at the OpenWeather website but
+is mentioned in the issue
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/426922a2/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 4dc2dba..f4da1b9 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
@@ -16,19 +16,16 @@
*/
package org.apache.camel.component.weather;
-import java.net.URL;
import java.util.Scanner;
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.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.map.ObjectMapper;
+import static org.apache.camel.component.weather.WeatherLanguage.en;
import static org.apache.camel.component.weather.WeatherMode.JSON;
import static org.apache.camel.component.weather.WeatherUnits.METRIC;
-import static org.apache.camel.util.ObjectHelper.isEmpty;
import static org.apache.camel.util.ObjectHelper.notNull;
@UriParams
@@ -47,11 +44,19 @@ public class WeatherConfiguration {
@UriParam
private String lon;
@UriParam
+ private String rightLon;
+ @UriParam
+ private String topLat;
+ @UriParam
+ private Integer zoom;
+ @UriParam
private String period = "";
@UriParam(defaultValue = "JSON")
private WeatherMode mode = JSON;
@UriParam(defaultValue = "METRIC")
private WeatherUnits units = METRIC;
+ @UriParam(defaultValue = "en")
+ private WeatherLanguage language = en;
@UriParam
private String headerName;
@@ -142,6 +147,7 @@ public class WeatherConfiguration {
/**
* Latitude of location. You can use lat and lon options instead of location.
+ * For boxed queries this is the bottom latitude.
*/
public void setLat(String lat) {
this.lat = lat;
@@ -153,6 +159,7 @@ public class WeatherConfiguration {
/**
* Longitude of location. You can use lat and lon options instead of location.
+ * For boxed queries this is the left longtitude.
*/
public void setLon(String lon) {
this.lon = lon;
@@ -169,57 +176,58 @@ public class WeatherConfiguration {
return appid;
}
+ String getQuery() throws Exception {
+ return new WeatherQuery(this.component, this).getQuery();
+ }
- public String getQuery() throws Exception {
- return getQuery(getLocation());
+ String getQuery(String location) throws Exception {
+ return new WeatherQuery(this.component, this).getQuery(location);
}
- public String getQuery(String location) throws Exception {
- String answer = "http://api.openweathermap.org/data/2.5/";
+ public WeatherLanguage getLanguage() {
+ return language;
+ }
- if (lat != null && lon != null) {
- location = "lat=" + lat + "&lon=" + lon;
- } else if (isEmpty(location) || "current".equals(location)) {
- location = getCurrentGeoLocation();
- } else {
- // assuming the location is a town or country
- location = "q=" + location;
- }
-
- if (isEmpty(getPeriod())) {
- answer += "weather?" + location;
- } else {
- answer += "forecast/daily?" + location + "&cnt=" + getPeriod();
- }
+ /**
+ * Language of the response.
+ */
+ public void setLanguage(WeatherLanguage language) {
+ this.language = language;
+ }
- // append the desired measurement unit if not the default (which is metric)
- if (getUnits() != METRIC) {
- answer += "&units=" + getUnits().name().toLowerCase();
- }
+ public String getRightLon() {
+ return rightLon;
+ }
- // append the desired output mode if not the default (which is json)
- if (getMode() != JSON) {
- answer += "&mode=" + getMode().name().toLowerCase();
- }
+ /**
+ * For boxed queries this is the right longtitude. Needs to be used
+ * in combination with topLat and zoom.
+ */
+ public void setRightLon(String rightLon) {
+ this.rightLon = rightLon;
+ }
- if (getAppid() != null) {
- answer += "&APPID=" + getAppid();
- }
-
- return answer;
+ public String getTopLat() {
+ return topLat;
}
- private String getCurrentGeoLocation() throws Exception {
- String geoLocation = component.getCamelContext().getTypeConverter().mandatoryConvertTo(String.class, new URL("http://freegeoip.io/json/"));
- if (isEmpty(geoLocation)) {
- throw new IllegalStateException("Got the unexpected value '" + geoLocation + "' for the geolocation");
- }
+ /**
+ * For boxed queries this is the top latitude. Needs to be used
+ * in combination with rightLon and zoom.
+ */
+ public void setTopLat(String topLat) {
+ this.topLat = topLat;
+ }
- ObjectMapper mapper = new ObjectMapper();
- JsonNode node = mapper.readValue(geoLocation, JsonNode.class);
- JsonNode latitudeNode = notNull(node.get("latitude"), "latitude");
- JsonNode longitudeNode = notNull(node.get("longitude"), "longitude");
+ public Integer getZoom() {
+ return zoom;
+ }
- return "lat=" + latitudeNode + "&lon=" + longitudeNode;
+ /**
+ * For boxed queries this is the zoom. Needs to be used
+ * in combination with rightLon and topLat.
+ */
+ public void setZoom(Integer zoom) {
+ this.zoom = zoom;
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/426922a2/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherLanguage.java
----------------------------------------------------------------------
diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherLanguage.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherLanguage.java
new file mode 100644
index 0000000..ec4f35f
--- /dev/null
+++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherLanguage.java
@@ -0,0 +1,46 @@
+/**
+ * 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;
+
+/**
+ * All available languages for the weather API.
+ */
+public enum WeatherLanguage {
+ en,
+ ru,
+ it,
+ es,
+ sp,
+ uk,
+ ua,
+ de,
+ pt,
+ ro,
+ pl,
+ fi,
+ nl,
+ fr,
+ bg,
+ sv,
+ se,
+ zh_tw,
+ zh,
+ zh_cn,
+ tr,
+ hr,
+ ca;
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/426922a2/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherQuery.java
----------------------------------------------------------------------
diff --git a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherQuery.java b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherQuery.java
new file mode 100644
index 0000000..bf6edb4
--- /dev/null
+++ b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherQuery.java
@@ -0,0 +1,125 @@
+/**
+ * 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;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+
+import static org.apache.camel.component.weather.WeatherMode.JSON;
+import static org.apache.camel.component.weather.WeatherUnits.METRIC;
+import static org.apache.camel.util.ObjectHelper.isEmpty;
+import static org.apache.camel.util.ObjectHelper.notNull;
+
+/**
+ * Logic for determining the query based on the provided
+ * configuration.
+ */
+public class WeatherQuery {
+ private final WeatherConfiguration weatherConfiguration;
+ private final WeatherComponent component;
+
+ public WeatherQuery(WeatherComponent component, WeatherConfiguration weatherConfiguration) {
+ this.component = component;
+ this.weatherConfiguration = weatherConfiguration;
+ }
+
+ public String getQuery() throws Exception {
+ return getQuery(weatherConfiguration.getLocation());
+ }
+
+ public String getQuery(String location) throws Exception {
+ String answer = "http://api.openweathermap.org/data/2.5/";
+
+ if (weatherConfiguration.getLat() != null && weatherConfiguration.getLon() != null
+ && weatherConfiguration.getRightLon() == null && weatherConfiguration.getTopLat() == null) {
+ location = "lat=" + weatherConfiguration.getLat() + "&lon=" + weatherConfiguration.getLon();
+ } else if (weatherConfiguration.getLat() != null && weatherConfiguration.getLon() != null
+ && weatherConfiguration.getRightLon() != null && weatherConfiguration.getTopLat() != null) {
+ location = "bbox=" + weatherConfiguration.getLon() + ","
+ + weatherConfiguration.getLat() + ","
+ + weatherConfiguration.getRightLon() + ","
+ + weatherConfiguration.getTopLat() + ","
+ + weatherConfiguration.getZoom() + "&cluster=yes";
+ } else if (isEmpty(location) || "current".equals(location)) {
+ location = getCurrentGeoLocation();
+ } else {
+ // assuming the location is a town or country
+ location = "q=" + location;
+ }
+
+ location = location + "&lang=" + weatherConfiguration.getLanguage();
+
+ if (weatherConfiguration.getTopLat() != null && weatherConfiguration.getRightLon() != null) {
+ answer += "box?" + location;
+ } else if (isEmpty(weatherConfiguration.getPeriod())) {
+ answer += "weather?" + location;
+ } else {
+ answer += "forecast/daily?" + location + "&cnt=" + weatherConfiguration.getPeriod();
+ }
+
+ // append the desired measurement unit if not the default (which is metric)
+ if (weatherConfiguration.getUnits() != METRIC) {
+ answer += "&units=" + weatherConfiguration.getUnits().name().toLowerCase();
+ }
+
+ // append the desired output mode if not the default (which is json)
+ if (weatherConfiguration.getMode() != JSON) {
+ answer += "&mode=" + weatherConfiguration.getMode().name().toLowerCase();
+ }
+
+ if (weatherConfiguration.getAppid() != null) {
+ answer += "&APPID=" + weatherConfiguration.getAppid();
+ }
+
+ return answer;
+
+ }
+
+ /**
+ * TODO: shouldn't this method be moved to a class of its own perhaps with an interface
+ * that gets injected. For testing purposes you can inject your own version when testing this
+ * class.
+ */
+
+ String getCurrentGeoLocation() throws Exception {
+ HttpClient httpClient = new HttpClient();
+ 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 = component.getCamelContext().getTypeConverter().mandatoryConvertTo(String.class, getMethod.getResponseBodyAsStream());
+ if (isEmpty(geoLocation)) {
+ throw new IllegalStateException("Got the unexpected value '" + geoLocation + "' for the geolocation");
+ }
+
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode node = mapper.readValue(geoLocation, JsonNode.class);
+ JsonNode latitudeNode = notNull(node.get("latitude"), "latitude");
+ JsonNode longitudeNode = notNull(node.get("longitude"), "longitude");
+
+ return "lat=" + latitudeNode + "&lon=" + longitudeNode;
+ } finally {
+ getMethod.releaseConnection();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/426922a2/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 eceed0b..b1436ec 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
@@ -21,11 +21,20 @@ import org.apache.camel.builder.RouteBuilder;
public class CurrentWeatherConsumerTest extends BaseWeatherConsumerTest {
@Override
+ protected void checkWeatherContent(String weather) {
+ log.debug("The weather in {} format is {}{}", new Object[] {WeatherMode.XML, LS, weather});
+
+ //assertStringContains(weather, "<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+ assertStringContains(weather, "<coord");
+ assertStringContains(weather, "<temperature");
+ }
+
+ @Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
- from("weather:foo?appid=9162755b2efa555823cfe0451d7fff38").to("mock:result");
+ from("weather:foo?appid=9162755b2efa555823cfe0451d7fff38&lon=4&lat=52&rightLon=6&topLat=54").to("mock:result");
}
};
}
http://git-wip-us.apache.org/repos/asf/camel/blob/426922a2/components/camel-weather/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/components/camel-weather/src/test/resources/log4j.properties b/components/camel-weather/src/test/resources/log4j.properties
index 33efa4c..fb0280d 100644
--- a/components/camel-weather/src/test/resources/log4j.properties
+++ b/components/camel-weather/src/test/resources/log4j.properties
@@ -18,7 +18,7 @@
#
# The logging properties used for testing.
#
-log4j.rootLogger=INFO, file
+log4j.rootLogger=DEBUG, file
#log4j.logger.org.apache.camel=DEBUG
#log4j.logger.org.apache.camel.component.weather=DEBUG