diff --git a/README.md b/README.md
index a90c113..b23ea83 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ Paid:
* Daily Forecast 16 days
* Climatic 30 days
* Solar Radiation API
+* Road Risk API
Other:
* Request timeout settings
diff --git a/docs/SNAPSHOT.md b/docs/SNAPSHOT.md
index 10314a8..bb55362 100644
--- a/docs/SNAPSHOT.md
+++ b/docs/SNAPSHOT.md
@@ -5,6 +5,7 @@
* Daily forecast
* Solar Radiation API
* 5 day / 3-hour forecast
+* Road Risk API
* Air Pollution
* Geocoding 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 15c2649..78e050b 100644
--- a/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapClient.java
+++ b/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapClient.java
@@ -33,6 +33,7 @@ import com.github.prominence.openweathermap.api.request.forecast.hourly.FourDays
import com.github.prominence.openweathermap.api.request.geocoding.GeocodingRequester;
import com.github.prominence.openweathermap.api.request.onecall.OneCallWeatherRequester;
import com.github.prominence.openweathermap.api.request.radiation.SolarRadiationRequester;
+import com.github.prominence.openweathermap.api.request.roadrisk.RoadRiskRequester;
import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherRequester;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.*;
@@ -125,6 +126,15 @@ public class OpenWeatherMapClient {
return new FiveDayThreeHourStepForecastRequester(new RequestSettings(apiKey, timeoutSettings));
}
+ /**
+ * Road Risk API.
+ * @return requester for retrieving road risk information.
+ */
+ @SubscriptionAvailability(plans = SPECIAL)
+ public RoadRiskRequester roadRisk() {
+ return new RoadRiskRequester(new RequestSettings(apiKey, timeoutSettings));
+ }
+
/**
* 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/deserializer/roadrisk/RoadRiskAlertDeserializer.java b/src/main/java/com/github/prominence/openweathermap/api/deserializer/roadrisk/RoadRiskAlertDeserializer.java
new file mode 100644
index 0000000..eb37528
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/deserializer/roadrisk/RoadRiskAlertDeserializer.java
@@ -0,0 +1,23 @@
+package com.github.prominence.openweathermap.api.deserializer.roadrisk;
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.github.prominence.openweathermap.api.enums.EventLevel;
+import com.github.prominence.openweathermap.api.model.roadrisk.Alert;
+
+import java.io.IOException;
+
+public class RoadRiskAlertDeserializer extends JsonDeserializer {
+ @Override
+ public Alert deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
+ final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
+ final Alert alert = new Alert();
+ alert.setEvent(rootNode.get("event").asText());
+ alert.setSenderName(rootNode.get("sender_name").asText());
+ alert.setEventLevel(EventLevel.findByValue(rootNode.get("event_level").asInt()));
+ return alert;
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/deserializer/roadrisk/RoadRiskRoadDetailsDeserializer.java b/src/main/java/com/github/prominence/openweathermap/api/deserializer/roadrisk/RoadRiskRoadDetailsDeserializer.java
new file mode 100644
index 0000000..943fcf6
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/deserializer/roadrisk/RoadRiskRoadDetailsDeserializer.java
@@ -0,0 +1,23 @@
+package com.github.prominence.openweathermap.api.deserializer.roadrisk;
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.github.prominence.openweathermap.api.enums.RoadState;
+import com.github.prominence.openweathermap.api.model.roadrisk.RoadDetails;
+
+import java.io.IOException;
+
+public class RoadRiskRoadDetailsDeserializer extends JsonDeserializer {
+ @Override
+ public RoadDetails deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
+ final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
+ final RoadDetails roadDetails = new RoadDetails();
+ roadDetails.setSurfaceTemperature(rootNode.get("temp").asDouble());
+ roadDetails.setRoadState(RoadState.findByValue(rootNode.get("state").asInt()));
+
+ return roadDetails;
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/deserializer/roadrisk/RoadRiskWeatherDeserializer.java b/src/main/java/com/github/prominence/openweathermap/api/deserializer/roadrisk/RoadRiskWeatherDeserializer.java
new file mode 100644
index 0000000..8627a96
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/deserializer/roadrisk/RoadRiskWeatherDeserializer.java
@@ -0,0 +1,31 @@
+package com.github.prominence.openweathermap.api.deserializer.roadrisk;
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.github.prominence.openweathermap.api.model.roadrisk.Weather;
+
+import java.io.IOException;
+
+public class RoadRiskWeatherDeserializer extends JsonDeserializer {
+ @Override
+ public Weather deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
+ final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
+
+ final Weather weather = new Weather();
+ weather.setTemperature(rootNode.get("temp").asDouble());
+ weather.setDewPoint(rootNode.get("dew_point").asDouble());
+ weather.setWindSpeed(rootNode.get("wind_speed").asDouble());
+ weather.setWindDegrees(rootNode.get("wind_deg").asDouble());
+ if (rootNode.has("precipitation_intensity")) {
+ weather.setPrecipitationIntensity(rootNode.get("precipitation_intensity").asDouble());
+ }
+ if (rootNode.has("visibility")) {
+ weather.setVisibilityInMetres(rootNode.get("visibility").asDouble());
+ }
+
+ return weather;
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/enums/EventLevel.java b/src/main/java/com/github/prominence/openweathermap/api/enums/EventLevel.java
new file mode 100644
index 0000000..7133a2c
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/enums/EventLevel.java
@@ -0,0 +1,25 @@
+package com.github.prominence.openweathermap.api.enums;
+
+import java.util.Arrays;
+
+public enum EventLevel {
+ UNKNOWN(0),
+ GREEN(1),
+ YELLOW(2),
+ ORANGE(3),
+ RED(4);
+
+ private final int value;
+
+ EventLevel(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static EventLevel findByValue(int value) {
+ return Arrays.stream(values()).filter(eventLevel -> eventLevel.getValue() == value).findFirst().orElse(null);
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/enums/RoadState.java b/src/main/java/com/github/prominence/openweathermap/api/enums/RoadState.java
new file mode 100644
index 0000000..fe2f2f2
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/enums/RoadState.java
@@ -0,0 +1,39 @@
+package com.github.prominence.openweathermap.api.enums;
+
+import java.util.Arrays;
+
+public enum RoadState {
+ NO_REPORT(0),
+ DRY(1),
+ MOIST(2),
+ MOIST_AND_CHEMICALLY_TREATED(3),
+ WET(4),
+ WET_AND_CHEMICALLY_TREATED(5),
+ ICE(6),
+ FROST(7),
+ SNOW(8),
+ SNOW_OR_ICE_WATCH(9),
+ SNOW_OR_ICE_WARNING(10),
+ WET_ABOVE_FREEZING(11),
+ WET_BELOW_FREEZING(12),
+ ABSORPTION(13),
+ ABSORPTION_AT_DEWPOINT(14),
+ DEW(15),
+ BLACK_ICE_WARNING(16),
+ OTHER(17),
+ SLUSH(18);
+
+ private final int value;
+
+ RoadState(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static RoadState findByValue(int value) {
+ return Arrays.stream(values()).filter(roadState -> roadState.getValue() == value).findFirst().orElse(null);
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/mapper/RoadRiskResponseMapper.java b/src/main/java/com/github/prominence/openweathermap/api/mapper/RoadRiskResponseMapper.java
new file mode 100644
index 0000000..cd62814
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/mapper/RoadRiskResponseMapper.java
@@ -0,0 +1,72 @@
+package com.github.prominence.openweathermap.api.mapper;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.github.prominence.openweathermap.api.deserializer.roadrisk.RoadRiskAlertDeserializer;
+import com.github.prominence.openweathermap.api.deserializer.roadrisk.RoadRiskRoadDetailsDeserializer;
+import com.github.prominence.openweathermap.api.deserializer.roadrisk.RoadRiskWeatherDeserializer;
+import com.github.prominence.openweathermap.api.model.Coordinates;
+import com.github.prominence.openweathermap.api.model.roadrisk.Alert;
+import com.github.prominence.openweathermap.api.model.roadrisk.RoadDetails;
+import com.github.prominence.openweathermap.api.model.roadrisk.RoadRiskRecord;
+import com.github.prominence.openweathermap.api.model.roadrisk.Weather;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class RoadRiskResponseMapper extends AbstractMapper {
+
+ public RoadRiskResponseMapper() {
+ final SimpleModule module = new SimpleModule();
+ module.addDeserializer(Weather.class, new RoadRiskWeatherDeserializer());
+ module.addDeserializer(RoadDetails.class, new RoadRiskRoadDetailsDeserializer());
+ module.addDeserializer(Alert.class, new RoadRiskAlertDeserializer());
+ objectMapper.registerModule(module);
+ }
+
+ public List mapToObjects(String jsonResponse) {
+ List roadRiskRecords;
+ try {
+ final JsonNode root = objectMapper.readTree(jsonResponse);
+ roadRiskRecords = mapToObjects(root);
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot parse SolarRadiation response", e);
+ }
+
+ return roadRiskRecords;
+ }
+
+ private List mapToObjects(JsonNode rootNode) throws IOException {
+ List roadRiskRecords = new ArrayList<>();
+
+ if (rootNode.isArray()) {
+ for (JsonNode recordNode : rootNode) {
+ RoadRiskRecord roadRiskRecord = new RoadRiskRecord();
+ roadRiskRecord.setForecastTime(parseDateTime(recordNode.get("dt")));
+
+ final JsonNode coordNode = recordNode.get("coord");
+ roadRiskRecord.setCoordinates(Coordinates.of(coordNode.get(0).asDouble(), coordNode.get(1).asDouble()));
+
+ roadRiskRecord.setWeather(objectMapper.readValue(objectMapper.treeAsTokens(recordNode.get("weather")), Weather.class));
+ if (recordNode.has("road")) {
+ roadRiskRecord.setRoadDetails(objectMapper.readValue(objectMapper.treeAsTokens(recordNode.get("road")), RoadDetails.class));
+ }
+
+ final JsonNode alertsNode = recordNode.get("alerts");
+ if (alertsNode != null && alertsNode.isArray()) {
+ List alerts = new ArrayList<>();
+ for (JsonNode alertNode : alertsNode) {
+ alerts.add(objectMapper.readValue(objectMapper.treeAsTokens(alertNode), Alert.class));
+ }
+
+ roadRiskRecord.setAlerts(alerts);
+ }
+
+ roadRiskRecords.add(roadRiskRecord);
+ }
+ }
+
+ return roadRiskRecords;
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/Alert.java b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/Alert.java
new file mode 100644
index 0000000..056fd37
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/Alert.java
@@ -0,0 +1,57 @@
+package com.github.prominence.openweathermap.api.model.roadrisk;
+
+import com.github.prominence.openweathermap.api.enums.EventLevel;
+
+import java.util.Objects;
+
+public class Alert {
+ private String senderName;
+ private String event;
+ private EventLevel eventLevel;
+
+ public String getSenderName() {
+ return senderName;
+ }
+
+ public void setSenderName(String senderName) {
+ this.senderName = senderName;
+ }
+
+ public String getEvent() {
+ return event;
+ }
+
+ public void setEvent(String event) {
+ this.event = event;
+ }
+
+ public EventLevel getEventLevel() {
+ return eventLevel;
+ }
+
+ public void setEventLevel(EventLevel eventLevel) {
+ this.eventLevel = eventLevel;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Alert alert = (Alert) o;
+ return Objects.equals(senderName, alert.senderName) && Objects.equals(event, alert.event) && eventLevel == alert.eventLevel;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(senderName, event, eventLevel);
+ }
+
+ @Override
+ public String toString() {
+ return "Alert{" +
+ "senderName='" + senderName + '\'' +
+ ", event='" + event + '\'' +
+ ", eventLevel=" + eventLevel +
+ '}';
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/RoadDetails.java b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/RoadDetails.java
new file mode 100644
index 0000000..8b6618b
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/RoadDetails.java
@@ -0,0 +1,47 @@
+package com.github.prominence.openweathermap.api.model.roadrisk;
+
+import com.github.prominence.openweathermap.api.enums.RoadState;
+
+import java.util.Objects;
+
+public class RoadDetails {
+ private RoadState roadState;
+ private Double surfaceTemperature;
+
+ public RoadState getRoadState() {
+ return roadState;
+ }
+
+ public void setRoadState(RoadState roadState) {
+ this.roadState = roadState;
+ }
+
+ public Double getSurfaceTemperature() {
+ return surfaceTemperature;
+ }
+
+ public void setSurfaceTemperature(Double surfaceTemperature) {
+ this.surfaceTemperature = surfaceTemperature;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ RoadDetails that = (RoadDetails) o;
+ return roadState == that.roadState && Objects.equals(surfaceTemperature, that.surfaceTemperature);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(roadState, surfaceTemperature);
+ }
+
+ @Override
+ public String toString() {
+ return "RoadDetails{" +
+ "roadState=" + roadState +
+ ", surfaceTemperature=" + surfaceTemperature +
+ '}';
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/RoadRiskRecord.java b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/RoadRiskRecord.java
new file mode 100644
index 0000000..c94a11b
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/RoadRiskRecord.java
@@ -0,0 +1,81 @@
+package com.github.prominence.openweathermap.api.model.roadrisk;
+
+import com.github.prominence.openweathermap.api.model.Coordinates;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Objects;
+
+public class RoadRiskRecord {
+ private LocalDateTime forecastTime;
+ private Coordinates coordinates;
+
+ private Weather weather;
+ private RoadDetails roadDetails;
+
+ private List alerts;
+
+ public LocalDateTime getForecastTime() {
+ return forecastTime;
+ }
+
+ public void setForecastTime(LocalDateTime forecastTime) {
+ this.forecastTime = forecastTime;
+ }
+
+ public Coordinates getCoordinates() {
+ return coordinates;
+ }
+
+ public void setCoordinates(Coordinates coordinates) {
+ this.coordinates = coordinates;
+ }
+
+ public Weather getWeather() {
+ return weather;
+ }
+
+ public void setWeather(Weather weather) {
+ this.weather = weather;
+ }
+
+ public RoadDetails getRoadDetails() {
+ return roadDetails;
+ }
+
+ public void setRoadDetails(RoadDetails roadDetails) {
+ this.roadDetails = roadDetails;
+ }
+
+ public List getAlerts() {
+ return alerts;
+ }
+
+ public void setAlerts(List alerts) {
+ this.alerts = alerts;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ RoadRiskRecord record = (RoadRiskRecord) o;
+ return Objects.equals(forecastTime, record.forecastTime) && Objects.equals(coordinates, record.coordinates) && Objects.equals(weather, record.weather) && Objects.equals(roadDetails, record.roadDetails) && Objects.equals(alerts, record.alerts);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(forecastTime, coordinates, weather, roadDetails, alerts);
+ }
+
+ @Override
+ public String toString() {
+ return "RoadRiskRecord{" +
+ "forecastTime=" + forecastTime +
+ ", coordinates=" + coordinates +
+ ", weather=" + weather +
+ ", roadDetails=" + roadDetails +
+ ", alerts=" + alerts +
+ '}';
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/TrackPoint.java b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/TrackPoint.java
new file mode 100644
index 0000000..22de4dd
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/TrackPoint.java
@@ -0,0 +1,48 @@
+package com.github.prominence.openweathermap.api.model.roadrisk;
+
+import com.github.prominence.openweathermap.api.model.Coordinates;
+
+import java.time.LocalDateTime;
+import java.util.Objects;
+
+public class TrackPoint {
+ private Coordinates coordinates;
+ private LocalDateTime requestedTime;
+
+ public Coordinates getCoordinates() {
+ return coordinates;
+ }
+
+ public void setCoordinates(Coordinates coordinates) {
+ this.coordinates = coordinates;
+ }
+
+ public LocalDateTime getRequestedTime() {
+ return requestedTime;
+ }
+
+ public void setRequestedTime(LocalDateTime requestedTime) {
+ this.requestedTime = requestedTime;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TrackPoint that = (TrackPoint) o;
+ return Objects.equals(coordinates, that.coordinates) && Objects.equals(requestedTime, that.requestedTime);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(coordinates, requestedTime);
+ }
+
+ @Override
+ public String toString() {
+ return "TrackPoint{" +
+ "coordinates=" + coordinates +
+ ", requestedTime=" + requestedTime +
+ '}';
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/Weather.java b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/Weather.java
new file mode 100644
index 0000000..5d3d4db
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/model/roadrisk/Weather.java
@@ -0,0 +1,86 @@
+package com.github.prominence.openweathermap.api.model.roadrisk;
+
+import java.util.Objects;
+
+public class Weather {
+
+ private Double temperature;
+ private Double windSpeed;
+ private Double windDegrees;
+ private Double precipitationIntensity;
+ private Double visibilityInMetres;
+ private Double dewPoint;
+
+ public Double getTemperature() {
+ return temperature;
+ }
+
+ public void setTemperature(Double temperature) {
+ this.temperature = temperature;
+ }
+
+ public Double getWindSpeed() {
+ return windSpeed;
+ }
+
+ public void setWindSpeed(Double windSpeed) {
+ this.windSpeed = windSpeed;
+ }
+
+ public Double getWindDegrees() {
+ return windDegrees;
+ }
+
+ public void setWindDegrees(Double windDegrees) {
+ this.windDegrees = windDegrees;
+ }
+
+ public Double getPrecipitationIntensity() {
+ return precipitationIntensity;
+ }
+
+ public void setPrecipitationIntensity(Double precipitationIntensity) {
+ this.precipitationIntensity = precipitationIntensity;
+ }
+
+ public Double getVisibilityInMetres() {
+ return visibilityInMetres;
+ }
+
+ public void setVisibilityInMetres(Double visibilityInMetres) {
+ this.visibilityInMetres = visibilityInMetres;
+ }
+
+ public Double getDewPoint() {
+ return dewPoint;
+ }
+
+ public void setDewPoint(Double dewPoint) {
+ this.dewPoint = dewPoint;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Weather weather = (Weather) o;
+ return Objects.equals(temperature, weather.temperature) && Objects.equals(windSpeed, weather.windSpeed) && Objects.equals(windDegrees, weather.windDegrees) && Objects.equals(precipitationIntensity, weather.precipitationIntensity) && Objects.equals(visibilityInMetres, weather.visibilityInMetres) && Objects.equals(dewPoint, weather.dewPoint);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(temperature, windSpeed, windDegrees, precipitationIntensity, visibilityInMetres, dewPoint);
+ }
+
+ @Override
+ public String toString() {
+ return "Weather{" +
+ "temperature=" + temperature +
+ ", windSpeed=" + windSpeed +
+ ", windDegrees=" + windDegrees +
+ ", precipitationIntensity=" + precipitationIntensity +
+ ", visibilityInMetres=" + visibilityInMetres +
+ ", dewPoint=" + dewPoint +
+ '}';
+ }
+}
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 56218d6..f4599e8 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
@@ -26,8 +26,10 @@ import com.github.prominence.openweathermap.api.conf.TimeoutSettings;
import com.github.prominence.openweathermap.api.enums.Language;
import com.github.prominence.openweathermap.api.enums.ResponseType;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
+import com.github.prominence.openweathermap.api.model.roadrisk.TrackPoint;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
public class RequestSettings {
@@ -41,6 +43,8 @@ public class RequestSettings {
private final Map requestParameters = new HashMap<>(8);
+ private final Map requestBody = new HashMap<>();
+
private final StringBuilder urlAppenderBuilder = new StringBuilder();
private String subdomain = "api";
@@ -107,4 +111,8 @@ public class RequestSettings {
public StringBuilder getUrlAppender() {
return urlAppenderBuilder;
}
+
+ public void addToRequestBody(String key, Object object) {
+ requestBody.put(key, object);
+ }
}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskAsyncRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskAsyncRequestTerminator.java
new file mode 100644
index 0000000..7ff68b7
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskAsyncRequestTerminator.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2022 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.roadrisk;
+
+import com.github.prominence.openweathermap.api.enums.ResponseType;
+import com.github.prominence.openweathermap.api.mapper.RoadRiskResponseMapper;
+import com.github.prominence.openweathermap.api.model.roadrisk.RoadRiskRecord;
+import com.github.prominence.openweathermap.api.request.RequestSettings;
+import com.github.prominence.openweathermap.api.utils.RequestUtils;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * The type Single result current weather async request terminator.
+ */
+public class RoadRiskAsyncRequestTerminator {
+ private final RequestSettings requestSettings;
+
+ /**
+ * Instantiates a new Single result current weather async request terminator.
+ *
+ * @param requestSettings request settings object.
+ */
+ RoadRiskAsyncRequestTerminator(RequestSettings requestSettings) {
+ this.requestSettings = requestSettings;
+ }
+
+ public CompletableFuture> asJava() {
+ return CompletableFuture.supplyAsync(() -> new RoadRiskResponseMapper().mapToObjects(getRawResponse()));
+ }
+
+ public CompletableFuture asJSON() {
+ return CompletableFuture.supplyAsync(this::getRawResponse);
+ }
+
+ public CompletableFuture asXML() {
+ requestSettings.setResponseType(ResponseType.XML);
+ return CompletableFuture.supplyAsync(this::getRawResponse);
+ }
+
+ public CompletableFuture asHTML() {
+ requestSettings.setResponseType(ResponseType.HTML);
+ return CompletableFuture.supplyAsync(this::getRawResponse);
+ }
+
+ private String getRawResponse() {
+ return RequestUtils.getResponse(requestSettings);
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskRequestCustomizer.java b/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskRequestCustomizer.java
new file mode 100644
index 0000000..8bfca40
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskRequestCustomizer.java
@@ -0,0 +1,19 @@
+package com.github.prominence.openweathermap.api.request.roadrisk;
+
+import com.github.prominence.openweathermap.api.request.RequestSettings;
+
+public class RoadRiskRequestCustomizer {
+ private final RequestSettings requestSettings;
+
+ public RoadRiskRequestCustomizer(RequestSettings requestSettings) {
+ this.requestSettings = requestSettings;
+ }
+
+ public RoadRiskRequestTerminator retrieve() {
+ return new RoadRiskRequestTerminator(requestSettings);
+ }
+
+ public RoadRiskAsyncRequestTerminator retrieveAsync() {
+ return new RoadRiskAsyncRequestTerminator(requestSettings);
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskRequestTerminator.java
new file mode 100644
index 0000000..1cc869a
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskRequestTerminator.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022 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.roadrisk;
+
+import com.github.prominence.openweathermap.api.enums.ResponseType;
+import com.github.prominence.openweathermap.api.mapper.RoadRiskResponseMapper;
+import com.github.prominence.openweathermap.api.model.roadrisk.RoadRiskRecord;
+import com.github.prominence.openweathermap.api.request.RequestSettings;
+import com.github.prominence.openweathermap.api.utils.RequestUtils;
+
+import java.util.List;
+
+public class RoadRiskRequestTerminator {
+ private final RequestSettings requestSettings;
+
+ RoadRiskRequestTerminator(RequestSettings requestSettings) {
+ this.requestSettings = requestSettings;
+ }
+
+ public List asJava() {
+ return new RoadRiskResponseMapper().mapToObjects(asJSON());
+ }
+
+ public String asJSON() {
+ return getRawResponse();
+ }
+
+ public String asXML() {
+ requestSettings.setResponseType(ResponseType.XML);
+ return getRawResponse();
+ }
+
+ public String asHTML() {
+ requestSettings.setResponseType(ResponseType.HTML);
+ return getRawResponse();
+ }
+
+ private String getRawResponse() {
+ return RequestUtils.getResponse(requestSettings);
+ }
+}
diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskRequester.java b/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskRequester.java
new file mode 100644
index 0000000..0789c17
--- /dev/null
+++ b/src/main/java/com/github/prominence/openweathermap/api/request/roadrisk/RoadRiskRequester.java
@@ -0,0 +1,20 @@
+package com.github.prominence.openweathermap.api.request.roadrisk;
+
+import com.github.prominence.openweathermap.api.model.roadrisk.TrackPoint;
+import com.github.prominence.openweathermap.api.request.RequestSettings;
+
+import java.util.List;
+
+public class RoadRiskRequester {
+ private final RequestSettings requestSettings;
+
+ public RoadRiskRequester(RequestSettings requestSettings) {
+ this.requestSettings = requestSettings;
+ this.requestSettings.appendToURL("data/2.5/roadrisk");
+ }
+
+ public RoadRiskRequestCustomizer byTrackPoints(List trackPoints) {
+ requestSettings.addToRequestBody("track", trackPoints);
+ return new RoadRiskRequestCustomizer(requestSettings);
+ }
+}
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 1ef190d..8563403 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
@@ -70,6 +70,7 @@ public final class RequestUtils {
* @return response from the request in String representation.
* @throws IllegalArgumentException in case if provided parameter isn't a valid url for {@link URL} instance.
*/
+ @Deprecated
public static String getResponse(String url) {
return getResponse(url, new TimeoutSettings());
}
diff --git a/src/test/java/com/github/prominence/openweathermap/api/mapper/RoadRiskResponseMapperTest.java b/src/test/java/com/github/prominence/openweathermap/api/mapper/RoadRiskResponseMapperTest.java
new file mode 100644
index 0000000..0ff37c0
--- /dev/null
+++ b/src/test/java/com/github/prominence/openweathermap/api/mapper/RoadRiskResponseMapperTest.java
@@ -0,0 +1,67 @@
+package com.github.prominence.openweathermap.api.mapper;
+
+import com.github.prominence.openweathermap.api.model.roadrisk.RoadRiskRecord;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class RoadRiskResponseMapperTest {
+
+ @Test
+ void mapToObjects() {
+ final String jsonResponse = """
+ [
+ {
+ "dt": 1602702000,
+ "coord": [
+ 7.27,
+ 44.04
+ ],
+ "weather": {
+ "temp": 278.44,
+ "wind_speed": 2.27,
+ "wind_deg": 7,
+ "precipitation_intensity": 0.38,
+ "dew_point": 276.13
+ },
+ "road": {
+ "state": 2,
+ "temp": 293.85
+ },
+ "alerts": [
+ {
+ "sender_name": "METEO-FRANCE",
+ "event": "Moderate thunderstorm warning",
+ "event_level": 2
+ }
+ ]
+ },
+ {
+ "dt": 1602702400,
+ "coord": [
+ 7.37,
+ 45.04
+ ],
+ "weather": {
+ "temp": 282.44,
+ "wind_speed": 1.84,
+ "wind_deg": 316,
+ "dew_point": 275.99
+ },
+ "road": {
+ "state": 1,
+ "temp": 293.85
+ },
+ "alerts": [
+ ]
+ }
+ ]
+ """;
+
+ final List roadRiskRecords = new RoadRiskResponseMapper().mapToObjects(jsonResponse);
+ assertNotNull(roadRiskRecords);
+
+ }
+}
\ No newline at end of file