Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public final class OurAirportsAirportProvider implements AirportProvider {
private final Map<String, Country> countries;
/** Map of airports. */
private final Map<String, Airport> airports;
/** HTTP client used to retrieve airport data. */
private final HttpClient httpClient;
/** Common CSV format. */
private final CSVFormat csvFormat;

Expand All @@ -46,8 +48,25 @@ public final class OurAirportsAirportProvider implements AirportProvider {
* @throws URISyntaxException when the URI is invalid
*/
public OurAirportsAirportProvider() throws IOException, URISyntaxException, InterruptedException {
this(HttpClient.newBuilder().build());
}

/**
* Creates a provider with the supplied HTTP client.
*
* <p>This constructor is package-private to support deterministic tests without changing
* the public HTTP-based provider API.
*
* @param client HTTP client used to retrieve OurAirports data
* @throws IOException when network error
* @throws URISyntaxException when a URI is invalid
* @throws InterruptedException when the request is interrupted
*/
OurAirportsAirportProvider(final HttpClient client)
throws IOException, URISyntaxException, InterruptedException {
countries = new HashMap<>();
airports = new HashMap<>();
httpClient = client;
csvFormat = CSVFormat.RFC4180;
buildCountries();
buildAirport();
Expand All @@ -67,10 +86,18 @@ public void buildCountries() throws URISyntaxException, IOException, Interrupted
.timeout(Duration.ofSeconds(5))
.build();

HttpResponse<InputStream> response = HttpClient.newBuilder()
.build()
.send(request, HttpResponse.BodyHandlers.ofInputStream());
try (CSVParser parser = csvFormat.parse(new InputStreamReader(response.body(), StandardCharsets.UTF_8))) {
HttpResponse<InputStream> response = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
parseCountries(response.body());
}

/**
* Parses countries CSV data and adds the records to the country map.
*
* @param countriesStream stream containing countries.csv data
* @throws IOException when the stream cannot be parsed
*/
private void parseCountries(final InputStream countriesStream) throws IOException {
try (CSVParser parser = csvFormat.parse(new InputStreamReader(countriesStream, StandardCharsets.UTF_8))) {
for (CSVRecord line: parser) {
Country c = new Country();
c.setName(line.get(2));
Expand All @@ -93,10 +120,18 @@ public void buildAirport() throws URISyntaxException, IOException, InterruptedEx
.timeout(Duration.ofSeconds(5))
.build();

HttpResponse<InputStream> response = HttpClient.newBuilder()
.build()
.send(request, HttpResponse.BodyHandlers.ofInputStream());
try (CSVParser parser = csvFormat.parse(new InputStreamReader(response.body(), StandardCharsets.UTF_8))) {
HttpResponse<InputStream> response = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
parseAirports(response.body());
}

/**
* Parses airports CSV data and adds the records to the airport map.
*
* @param airportsStream stream containing airports.csv data
* @throws IOException when the stream cannot be parsed
*/
private void parseAirports(final InputStream airportsStream) throws IOException {
try (CSVParser parser = csvFormat.parse(new InputStreamReader(airportsStream, StandardCharsets.UTF_8))) {
for (CSVRecord line : parser) {
Airport airport = new Airport();
airport.setIcao(line.get(1));
Expand All @@ -117,4 +152,3 @@ public Map<String, Airport> getAirports() {
return Collections.unmodifiableMap(airports);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;

import io.github.mivek.model.Airport;
import io.github.mivek.provider.airport.AirportProvider;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;
import java.util.Objects;
import org.junit.jupiter.api.Test;

/**
Expand All @@ -19,13 +27,25 @@
class OurAirportsAirportProviderTest {

@Test
void testGetAirport() throws IOException, URISyntaxException, InterruptedException {
AirportProvider provider = new OurAirportsAirportProvider();
void testGetAirport() throws IOException, InterruptedException, URISyntaxException {
HttpClient client = mock(HttpClient.class);
HttpResponse<InputStream> countriesResponse = mock(HttpResponse.class);
HttpResponse<InputStream> airportsResponse = mock(HttpResponse.class);
doReturn(fixture("countries.csv")).when(countriesResponse).body();
doReturn(fixture("airports.csv")).when(airportsResponse).body();
doReturn(countriesResponse, airportsResponse).when(client).send(any(HttpRequest.class), any());

AirportProvider provider = new OurAirportsAirportProvider(client);

Map<String, Airport> airports = provider.getAirports();

assertThat(airports, not(anEmptyMap()));
assertThat(airports, hasKey("LFPG"));
assertNotNull(airports.get("LFPG"));
}

private static InputStream fixture(final String name) {
return Objects.requireNonNull(
OurAirportsAirportProviderTest.class.getResourceAsStream("/ourairports/" + name));
}
}
2 changes: 2 additions & 0 deletions metarParser-spi/src/test/resources/ourairports/airports.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id,ident,type,name,latitude_deg,longitude_deg,elevation_ft,continent,iso_country,iso_region,municipality,scheduled_service,gps_code,iata_code,local_code,home_link,wikipedia_link,keywords
6523,LFPG,large_airport,Paris Charles de Gaulle Airport,49.01279830932617,2.55,392,EU,FR,FR-IDF,Paris,yes,LFPG,CDG,LFPG,,,
2 changes: 2 additions & 0 deletions metarParser-spi/src/test/resources/ourairports/countries.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id,code,name
83,FR,France
Loading