Skip to content

Commit

Permalink
- Improving performance
Browse files Browse the repository at this point in the history
  • Loading branch information
FarukBraimo committed Jun 20, 2024
1 parent 2a1533f commit 5956ef8
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutionException;

@RestController
@CrossOrigin(value = "*")
@RequiredArgsConstructor
Expand All @@ -37,7 +39,7 @@ public class InsightController {
@ApiResponse(responseCode = "404", content = {@Content(schema = @Schema(implementation = String.class), mediaType = "application/json")}, description = "When the city is not valid or found"),
@ApiResponse(responseCode = "500", content = {@Content(schema = @Schema(implementation = String.class), mediaType = "application/json")}, description = "When unknown error happens")
})
public ResponseEntity<InsightResponse> getInsight(@RequestParam("city") String city) throws ResourceNotFoundException {
public ResponseEntity<InsightResponse> getInsight(@RequestParam("city") String city) throws ResourceNotFoundException, ExecutionException, InterruptedException {
InsightResponse response = falconInsightService.getInsight(city);
return new ResponseEntity<>(response, HttpStatus.OK);
}
Expand Down
58 changes: 51 additions & 7 deletions src/main/java/com/vodacom/falcon/service/InsightService.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.MethodArgumentNotValidException;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import static com.vodacom.falcon.util.FalconDefaults.WB_FILTER_DATE;
import static com.vodacom.falcon.util.FalconDefaults.WB_RANGE_FILTER_DATE;
Expand All @@ -34,20 +35,41 @@ public class InsightService {
private final ExchangeRateService exchangeRateService;
private final CountryMetadataService countryMetadataService;

public InsightResponse getInsight(String city) throws ResourceNotFoundException {
public InsightResponse getInsight(String city) throws ResourceNotFoundException, ExecutionException, InterruptedException {
log.info("Getting insights for {}", city);
ValidationFactory.validateSearch("City", city);

MetadataResponse metadata = new MetadataResponse();

String encodedCity = URLEncoder.encode(city, StandardCharsets.UTF_8);

String countryCode = countryMetadataService.getCountryCode(encodedCity);
String countryCode = null;

CompletableFuture<String> countryTaskResponse = CompletableFuture
.supplyAsync(() -> countryMetadataService.getCountryCode(encodedCity))
.exceptionally(
(e) -> {
log.error("Error getting country data ");
throw new RuntimeException(e.getMessage());
});

CompletableFuture<WeatherForecastResponse> weatherForecastTaskResponse = CompletableFuture
.supplyAsync(() -> weatherForecastService.getWeatherForecast(encodedCity))
.exceptionally(
(e) -> {
log.error("Error getting weather ");
throw new RuntimeException(e.getMessage());
});

CompletableFuture<Void> combinedCountryFuture = CompletableFuture.allOf(countryTaskResponse, weatherForecastTaskResponse);

combinedCountryFuture.join();

WeatherForecastResponse weatherForecast = new WeatherForecastResponse();
metadata.setCountry(true);

if (Objects.isNull(countryCode)) {
weatherForecast = weatherForecastService.getWeatherForecast(encodedCity);
if (Objects.isNull(countryTaskResponse.get())) {
weatherForecast = weatherForecastTaskResponse.get();
countryCode = weatherForecast
.getForecast()
.getLocation()
Expand All @@ -60,11 +82,33 @@ public InsightResponse getInsight(String city) throws ResourceNotFoundException
throw new ResourceNotFoundException(String.format("City: %s Not found", city));
}

String finalCountryCode = countryCode;
CompletableFuture<EconomyInsightResponse> economyTaskResponse = CompletableFuture
.supplyAsync(() -> economyInsightService.getEconomyInsight(finalCountryCode, WB_FILTER_DATE))
.exceptionally(
(e) -> {
log.error("Error getting economy data ");
throw new RuntimeException(e.getMessage());
});

CompletableFuture<ExchangeRateResponse> exchangeRateTaskResponse = CompletableFuture
.supplyAsync(() -> exchangeRateService.getExchangeRates(finalCountryCode))
.exceptionally(
(e) -> {
log.error("Error getting exchanges ");
throw new RuntimeException(e.getMessage());
}
);

CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(economyTaskResponse, exchangeRateTaskResponse);

combinedFuture.join();

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
metadata.setAuthenticatedUser(true);
metadata.setMessage("Enjoy your destination %s! ");

ExchangeRateResponse exchangeRateResponse = exchangeRateService.getExchangeRates(countryCode);
ExchangeRateResponse exchangeRateResponse = exchangeRateTaskResponse.get();

if (authentication instanceof AnonymousAuthenticationToken) {
metadata.setAuthenticatedUser(false);
Expand All @@ -73,7 +117,7 @@ public InsightResponse getInsight(String city) throws ResourceNotFoundException
exchangeRateResponse = null;
}

EconomyInsightResponse economyInsight = economyInsightService.getEconomyInsight(countryCode, WB_FILTER_DATE);
EconomyInsightResponse economyInsight = economyTaskResponse.get();

return InsightResponse
.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ public class WeatherForecastService {

private final String OPEN_WEATHER_API_VERSION = "3.0"; // TODO: Add feature flag Or row controller, to determine the version to use. (2.5 0r 3.0)

public WeatherForecastResponse getWeatherForecast(String city) throws ResourceNotFoundException {
public WeatherForecastResponse getWeatherForecast(String city) {
return WeatherForecastResponse
.builder()
.forecast(buildWeatherForecast(city))
.build();
}

private OpenWeatherForecastResponse buildWeatherForecast(String city) throws ResourceNotFoundException {
private OpenWeatherForecastResponse buildWeatherForecast(String city) {
OpenLocationResponse location = this.getLocation(city);

if (location == null) {
log.info("Couldn't find location for {}", city);
throw new ResourceNotFoundException(String.format("City: %s Not found", city));
return null;
}

String url = String.format("%s/data/%s/onecall?units=metric&cnt=4&exclude=hourly,minutely,alerts&lat=%s&lon=%s&appid=%s", FalconDefaults.OPEN_WEATHER_API_BASE_URL, OPEN_WEATHER_API_VERSION, location.getLat(), location.getLon(), openWeatherApiKeyV3);
Expand Down

0 comments on commit 5956ef8

Please sign in to comment.