package org.learning.by.example.reactive.microservices.services;
import org.learning.by.example.reactive.microservices.exceptions.GetSunriseSunsetException;
import org.learning.by.example.reactive.microservices.model.GeographicCoordinates;
import org.learning.by.example.reactive.microservices.model.SunriseSunset;
import org.learning.by.example.reactive.microservices.model.GeoTimesResponse;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
public class SunriseSunsetServiceImpl implements SunriseSunsetService {
private static final String BEGIN_PARAMETERS = "?";
private static final String NEXT_PARAMETER = "&";
private static final String EQUALS = "=";
private static final String LATITUDE_PARAMETER = "lat" + EQUALS;
private static final String LONGITUDE_PARAMETER = "lng" + EQUALS;
private static final String DATE_PARAMETER = "date" + EQUALS;
private static final String TODAY_DATE = "today";
private static final String FORMATTED_PARAMETER = "formatted" + EQUALS;
private static final String NOT_FORMATTED = "0";
private static final String ERROR_GETTING_DATA = "error getting sunrise and sunset";
private static final String SUNRISE_RESULT_NOT_OK = "sunrise result was not OK";
private static final String STATUS_OK = "OK";
WebClient webClient;
private final String endPoint;
public SunriseSunsetServiceImpl(final String endPoint) {
this.endPoint = endPoint;
this.webClient = WebClient.create();
}
@Override
public Mono<SunriseSunset> fromGeographicCoordinates(Mono<GeographicCoordinates> location) {
return location
.transform(this::buildUrl)
.transform(this::get)
.onErrorResume(throwable -> Mono.error(new GetSunriseSunsetException(ERROR_GETTING_DATA, throwable)))
.transform(this::createResult);
}
Mono<String> buildUrl(final Mono<GeographicCoordinates> geographicCoordinatesMono) {
return geographicCoordinatesMono.flatMap(geographicCoordinates -> Mono.just(endPoint
.concat(BEGIN_PARAMETERS)
.concat(LATITUDE_PARAMETER).concat(Double.toString(geographicCoordinates.getLatitude()))
.concat(NEXT_PARAMETER)
.concat(LONGITUDE_PARAMETER).concat(Double.toString(geographicCoordinates.getLongitude()))
.concat(NEXT_PARAMETER)
.concat(DATE_PARAMETER).concat(TODAY_DATE)
.concat(NEXT_PARAMETER)
.concat(FORMATTED_PARAMETER).concat(NOT_FORMATTED)
));
}
Mono<GeoTimesResponse> get(final Mono<String> monoUrl) {
return monoUrl.flatMap(url -> webClient
.get()
.uri(url)
.accept(MediaType.APPLICATION_JSON)
.exchange()
.flatMap(clientResponse -> clientResponse.bodyToMono(GeoTimesResponse.class)));
}
Mono<SunriseSunset> createResult(final Mono<GeoTimesResponse> geoTimesResponseMono) {
return geoTimesResponseMono.flatMap(geoTimesResponse -> {
if ((geoTimesResponse.getStatus() != null) && (geoTimesResponse.getStatus().equals(STATUS_OK))) {
return Mono.just(new SunriseSunset(geoTimesResponse.getResults().getSunrise(),
geoTimesResponse.getResults().getSunset()));
} else {
return Mono.error(new GetSunriseSunsetException(SUNRISE_RESULT_NOT_OK));
}
});
}
}