From ac1f043f51639be16817b4cfc06b79492d664000 Mon Sep 17 00:00:00 2001 From: Dave Badia Date: Sat, 4 Nov 2023 12:32:16 -0400 Subject: [PATCH] add onecall 3 API --- pom.xml | 2 +- .../api/OpenWeatherMapClient.java | 12 ++ .../mapper/OneCallWeatherResponseMapper.java | 9 ++ .../api/model/onecall/current/Daily.java | 20 +++ .../api/request/RequestSettings.java | 9 ++ .../api/utils/RequestUtils.java | 4 + ...rentWeatherOneCallApi3IntegrationTest.java | 136 ++++++++++++++++++ 7 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/github/prominence/openweathermap/api/request/onecall/current/CurrentWeatherOneCallApi3IntegrationTest.java diff --git a/pom.xml b/pom.xml index 6f23922..74e60d4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.prominence openweathermap-api - 2.3.0 + 2.4.0 jar Java OpenWeatherMap API diff --git a/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapClient.java b/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapClient.java index c29d1eb..30c6e89 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapClient.java +++ b/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapClient.java @@ -84,6 +84,18 @@ public class OpenWeatherMapClient { return new OneCallWeatherRequester(new RequestSettings(apiKey, timeoutSettings)); } + /** + * One Call 3 API API. + * Includes a weather summary statement in addition to the information provided by {@link #oneCall()} + * @return requester for retrieving one call weather information for the OneCall 3 API. + */ + @SubscriptionAvailability(plans = ALL) + public OneCallWeatherRequester oneCall3() { + RequestSettings requestSettings = new RequestSettings(apiKey, timeoutSettings); + requestSettings.setUseApi3(); + return new OneCallWeatherRequester(requestSettings); + } + /** * Air Pollution API. * Air Pollution API provides current, forecast and historical air pollution data for any coordinates on the globe. diff --git a/src/main/java/com/github/prominence/openweathermap/api/mapper/OneCallWeatherResponseMapper.java b/src/main/java/com/github/prominence/openweathermap/api/mapper/OneCallWeatherResponseMapper.java index d3477b4..e3ad567 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/mapper/OneCallWeatherResponseMapper.java +++ b/src/main/java/com/github/prominence/openweathermap/api/mapper/OneCallWeatherResponseMapper.java @@ -213,6 +213,7 @@ public class OneCallWeatherResponseMapper { daily.setMoonPhase(new MoonPhase(moonPhaseNode.asDouble())); } + daily.setSummary(parseSummary(dailyNode)); daily.setWeatherState(parseWeatherState(dailyNode.get("weather").get(0))); daily.setTemperature(parseDailyTemperature(dailyNode)); daily.setAtmosphericPressure(parsePressure(dailyNode)); @@ -439,4 +440,12 @@ public class OneCallWeatherResponseMapper { return null; } + + private String parseSummary(JsonNode dailyNode) { + final JsonNode summaryNode = dailyNode.get("summary"); + if(summaryNode != null) { + return summaryNode.asText(); + } + return null; + } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/Daily.java b/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/Daily.java index e2f8b45..baeb87d 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/Daily.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/Daily.java @@ -43,6 +43,7 @@ public class Daily { private LocalDateTime moonsetTime; private MoonPhase moonPhase; + private String summary; private WeatherState weatherState; private DailyTemperature temperature; private AtmosphericPressure atmosphericPressure; @@ -162,6 +163,24 @@ public class Daily { this.moonPhase = moonPhase; } + /** + * Gets summary. + * + * @return the summary + */ + public String getSummary() { + return summary; + } + + /** + * Sets summary. + * + * @param summary the summary + */ + public void setSummary(String summary) { + this.summary = summary; + } + /** * Gets weather state. * @@ -435,4 +454,5 @@ public class Daily { } return stringBuilder.toString(); } + } diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/RequestSettings.java b/src/main/java/com/github/prominence/openweathermap/api/request/RequestSettings.java index db0b103..5e3a0a7 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/request/RequestSettings.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/RequestSettings.java @@ -45,6 +45,7 @@ public class RequestSettings { private Language language = Language.ENGLISH; private UnitSystem unitSystem = UnitSystem.STANDARD; + private boolean useApi3 = false; public RequestSettings(String apiKey, TimeoutSettings timeoutSettings) { this.putRequestParameter(API_KEY_PARAM_NAME, apiKey); @@ -94,6 +95,14 @@ public class RequestSettings { urlAppenderBuilder.append(appendix); } + public void setUseApi3() { + this.useApi3 = true; + } + + public boolean getUseApi3() { + return this.useApi3; + } + public StringBuilder getUrlAppender() { return urlAppenderBuilder; } diff --git a/src/main/java/com/github/prominence/openweathermap/api/utils/RequestUtils.java b/src/main/java/com/github/prominence/openweathermap/api/utils/RequestUtils.java index c20ec6d..419af2a 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/utils/RequestUtils.java +++ b/src/main/java/com/github/prominence/openweathermap/api/utils/RequestUtils.java @@ -45,6 +45,7 @@ import java.util.stream.Collectors; public final class RequestUtils { private static final String OWM_URL_BASE = "http://api.openweathermap.org/data/2.5/"; + private static final String OWM_URL_BASE_3_0 = "http://api.openweathermap.org/data/3.0/"; private static final Logger logger = LoggerFactory.getLogger(RequestUtils.class); @@ -53,6 +54,9 @@ public final class RequestUtils { public static String getResponse(RequestSettings requestSettings) { StringBuilder requestUrlBuilder = new StringBuilder(OWM_URL_BASE); + if(requestSettings.getUseApi3()) { + requestUrlBuilder = new StringBuilder(OWM_URL_BASE_3_0); + } requestUrlBuilder.append(requestSettings.getUrlAppender()); requestUrlBuilder.append('?'); String parameters = requestSettings.getRequestParameters().entrySet().stream() diff --git a/src/test/java/com/github/prominence/openweathermap/api/request/onecall/current/CurrentWeatherOneCallApi3IntegrationTest.java b/src/test/java/com/github/prominence/openweathermap/api/request/onecall/current/CurrentWeatherOneCallApi3IntegrationTest.java new file mode 100644 index 0000000..bc4ff50 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/request/onecall/current/CurrentWeatherOneCallApi3IntegrationTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2021 Alexey Zinchenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.prominence.openweathermap.api.request.onecall.current; + +import com.github.prominence.openweathermap.api.ApiTest; +import com.github.prominence.openweathermap.api.OpenWeatherMapClient; +import com.github.prominence.openweathermap.api.enums.Language; +import com.github.prominence.openweathermap.api.enums.OneCallResultOptions; +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.exception.InvalidAuthTokenException; +import com.github.prominence.openweathermap.api.exception.NoDataFoundException; +import com.github.prominence.openweathermap.api.model.Coordinate; +import com.github.prominence.openweathermap.api.model.onecall.current.CurrentWeatherData; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import static org.junit.jupiter.api.Assertions.*; + +public class CurrentWeatherOneCallApi3IntegrationTest extends ApiTest { + @Test + public void whenRetrieveCurrentOneCallResponseAsJava_thenOk() { + final CurrentWeatherData currentWeatherData = getClient() + .oneCall3() + .current() + .byCoordinate(Coordinate.of(53.54, 27.34)) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJava(); + + assertNotNull(currentWeatherData); + assertNotNull(currentWeatherData.getDailyList().get(0).getSummary()); + } + + @Test + public void whenRetrieveCurrentOneCallResponseAsJSON_thenOk() { + final String responseJson = getClient() + .oneCall3() + .current() + .byCoordinate(Coordinate.of(53.54, 27.34)) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJSON(); + + assertNotNull(responseJson); + assertNotEquals("", responseJson); + } + + @Test + public void whenRetrieveCurrentOneCallResponseWithExclusionAsJava_thenOk() { + final CurrentWeatherData currentWeatherData = getClient() + .oneCall3() + .current() + .byCoordinate(Coordinate.of(53.54, 27.34)) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .exclude(OneCallResultOptions.CURRENT, OneCallResultOptions.MINUTELY) + .retrieve() + .asJava(); + + assertNotNull(currentWeatherData); + assertNull(currentWeatherData.getCurrent()); + assertNull(currentWeatherData.getMinutelyList()); + assertNotNull(currentWeatherData.getDailyList().get(0).getSummary()); + } + + @Test + public void whenRetrieveCurrentOneCallAsyncResponseAsJava_thenOk() throws ExecutionException, InterruptedException { + final CompletableFuture currentWeatherDataFuture = getClient() + .oneCall3() + .current() + .byCoordinate(Coordinate.of(53.54, 27.34)) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieveAsync() + .asJava(); + + assertNotNull(currentWeatherDataFuture); + assertNotNull(currentWeatherDataFuture.get()); + assertNotNull(currentWeatherDataFuture.get().getDailyList().get(0).getSummary()); + } + + @Test + public void whenRetrieveCurrentOneCallAsyncResponseAsJSON_thenOk() throws ExecutionException, InterruptedException { + final CompletableFuture responseJsonFuture = getClient() + .oneCall3() + .current() + .byCoordinate(Coordinate.of(53.54, 27.34)) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieveAsync() + .asJSON(); + + assertNotNull(responseJsonFuture); + final String responseJson = responseJsonFuture.get(); + assertNotNull(responseJson); + } + + @Test + public void whenRequestOnecallWithInvalidApiKey_thenThrowAnException() { + OpenWeatherMapClient client = new OpenWeatherMapClient("invalidKey"); + assertThrows(InvalidAuthTokenException.class, () -> + client + .oneCall3() + .current() + .byCoordinate(Coordinate.of(53.54, 27.34)) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJSON() + ); + } +}