diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java b/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java index bfc65566e6e..9b276fc053e 100644 --- a/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java +++ b/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java @@ -25,6 +25,7 @@ import org.opentripplanner.ext.ridehailing.service.oauth.UrlEncodedOAuthService; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.json.ObjectMappers; import org.opentripplanner.transit.model.basic.Money; import org.slf4j.Logger; @@ -79,7 +80,7 @@ public UberService(RideHailingServiceParameters config) { this.timeEstimateUri = timeEstimateUri; this.bannedTypes = bannedTypes; this.wheelchairAccessibleProductId = wheelchairAccessibleProductId; - this.otpHttpClient = new OtpHttpClient(); + this.otpHttpClient = new OtpHttpClientFactory().create(LOG); } @Override diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETGooglePubsubUpdater.java b/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETGooglePubsubUpdater.java index 4b5797f03de..9a1c5690c58 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETGooglePubsubUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETGooglePubsubUpdater.java @@ -28,7 +28,7 @@ import org.opentripplanner.ext.siri.SiriFuzzyTripMatcher; import org.opentripplanner.ext.siri.SiriTimetableSnapshotSource; import org.opentripplanner.framework.application.ApplicationShutdownSupport; -import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.retry.OtpRetry; import org.opentripplanner.framework.retry.OtpRetryBuilder; import org.opentripplanner.framework.text.FileSizeToTextConverter; @@ -312,7 +312,8 @@ private void initializeData() { } private ByteString fetchInitialData() { - try (OtpHttpClient otpHttpClient = new OtpHttpClient()) { + try (OtpHttpClientFactory otpHttpClientFactory = new OtpHttpClientFactory()) { + var otpHttpClient = otpHttpClientFactory.create(LOG); return otpHttpClient.getAndMap( dataInitializationUrl, initialGetDataTimeout, diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriHttpLoader.java b/src/ext/java/org/opentripplanner/ext/siri/updater/SiriHttpLoader.java index 7a094dc0863..daf3d0397cc 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriHttpLoader.java +++ b/src/ext/java/org/opentripplanner/ext/siri/updater/SiriHttpLoader.java @@ -4,6 +4,7 @@ import java.time.Duration; import java.util.Optional; import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.updater.spi.HttpHeaders; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +36,7 @@ public SiriHttpLoader( this.timeout = timeout; this.requestHeaders = requestHeaders; this.previewInterval = previewInterval; - this.otpHttpClient = new OtpHttpClient(timeout, timeout); + this.otpHttpClient = new OtpHttpClientFactory(timeout, timeout).create(LOG); } /** diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AbstractAzureSiriUpdater.java b/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AbstractAzureSiriUpdater.java index 1915105960e..f211468cc66 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AbstractAzureSiriUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AbstractAzureSiriUpdater.java @@ -25,7 +25,7 @@ import org.opentripplanner.ext.siri.EntityResolver; import org.opentripplanner.ext.siri.SiriFuzzyTripMatcher; import org.opentripplanner.framework.application.ApplicationShutdownSupport; -import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.TransitModel; import org.opentripplanner.transit.service.TransitService; @@ -206,7 +206,8 @@ public String getConfigRef() { protected Optional fetchInitialSiriData(URI uri) { var headers = HttpHeaders.of().acceptApplicationXML().build().asMap(); - try (OtpHttpClient otpHttpClient = new OtpHttpClient()) { + try (OtpHttpClientFactory otpHttpClientFactory = new OtpHttpClientFactory()) { + var otpHttpClient = otpHttpClientFactory.create(LOG); var t1 = System.currentTimeMillis(); var siriOptional = otpHttpClient.executeAndMapOptional( new HttpGet(uri), diff --git a/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSource.java b/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSource.java index abeaab42137..3876ff44651 100644 --- a/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSource.java +++ b/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSource.java @@ -4,6 +4,7 @@ import java.util.Map; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; @@ -23,7 +24,7 @@ public class SmooveBikeRentalDataSource extends GenericJsonDataSource implements VehicleRentalDatasource { - private static final Logger log = LoggerFactory.getLogger(SmooveBikeRentalDataSource.class); + private static final Logger LOG = LoggerFactory.getLogger(SmooveBikeRentalDataSource.class); public static final String DEFAULT_NETWORK_NAME = "smoove"; @@ -33,14 +34,14 @@ public class SmooveBikeRentalDataSource private final RentalVehicleType vehicleType; public SmooveBikeRentalDataSource(SmooveBikeRentalDataSourceParameters config) { - this(config, new OtpHttpClient()); + this(config, new OtpHttpClientFactory()); } public SmooveBikeRentalDataSource( SmooveBikeRentalDataSourceParameters config, - OtpHttpClient otpHttpClient + OtpHttpClientFactory otpHttpClientFactory ) { - super(config.url(), "result", config.httpHeaders(), otpHttpClient); + super(config.url(), "result", config.httpHeaders(), otpHttpClientFactory.create(LOG)); networkName = config.getNetwork(DEFAULT_NETWORK_NAME); vehicleType = RentalVehicleType.getDefaultType(networkName); overloadingAllowed = config.overloadingAllowed(); @@ -76,7 +77,7 @@ protected VehicleRentalStation parseElement(JsonNode node) { station.longitude = Double.parseDouble(coordinates[1].trim()); } catch (NumberFormatException e) { // E.g. coordinates is empty - log.warn("Error parsing bike rental station {}", station.id, e); + LOG.warn("Error parsing bike rental station {}", station.id, e); return null; } if (!node.path("style").asText().equals("Station on")) { diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java index 5758d5d99e1..2bed1121913 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java @@ -15,6 +15,7 @@ import org.opentripplanner.framework.i18n.LocalizedString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.json.ObjectMappers; import org.opentripplanner.routing.vehicle_parking.VehicleParking; import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; @@ -44,7 +45,7 @@ public class BikelyUpdater implements DataSource { .put("lonMax", 0) .put("latMin", 0) .put("latMax", 0); - private final OtpHttpClient httpClient = new OtpHttpClient(); + private final OtpHttpClient httpClient = new OtpHttpClientFactory().create(LOG); private final BikelyUpdaterParameters parameters; private List lots; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java index 31664170a04..dcf4ffe29d9 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java @@ -12,6 +12,7 @@ import java.util.function.BiFunction; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientException; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.routing.vehicle_parking.VehicleParking; import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -20,7 +21,7 @@ public class HslFacilitiesDownloader { - private static final Logger log = LoggerFactory.getLogger(HslFacilitiesDownloader.class); + private static final Logger LOG = LoggerFactory.getLogger(HslFacilitiesDownloader.class); private static final ObjectMapper mapper = new ObjectMapper(); private final String jsonParsePath; @@ -31,19 +32,20 @@ public class HslFacilitiesDownloader { public HslFacilitiesDownloader( String url, String jsonParsePath, - BiFunction, VehicleParking> facilitiesParser + BiFunction, VehicleParking> facilitiesParser, + OtpHttpClientFactory otpHttpClientFactory ) { this.url = url; this.jsonParsePath = jsonParsePath; this.facilitiesParser = facilitiesParser; - this.otpHttpClient = new OtpHttpClient(); + this.otpHttpClient = otpHttpClientFactory.create(LOG); } public List downloadFacilities( Map hubForPark ) { if (url == null) { - log.warn("Cannot download updates, because url is null!"); + LOG.warn("Cannot download updates, because url is null!"); return null; } @@ -55,17 +57,17 @@ public List downloadFacilities( try { return parseJSON(is, hubForPark); } catch (IllegalArgumentException e) { - log.warn("Error parsing facilities from {}", url, e); + LOG.warn("Error parsing facilities from {}", url, e); } catch (JsonProcessingException e) { - log.warn("Error parsing facilities from {} (bad JSON of some sort)", url, e); + LOG.warn("Error parsing facilities from {} (bad JSON of some sort)", url, e); } catch (IOException e) { - log.warn("Error reading facilities from {}", url, e); + LOG.warn("Error reading facilities from {}", url, e); } return null; } ); } catch (OtpHttpClientException e) { - log.warn("Failed to get data from url {}", url); + LOG.warn("Failed to get data from url {}", url); return null; } } diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java index c5712e2067e..f1f98b6139c 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java @@ -11,6 +11,7 @@ import java.util.function.Function; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientException; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.slf4j.Logger; @@ -18,7 +19,7 @@ public class HslHubsDownloader { - private static final Logger log = LoggerFactory.getLogger(HslHubsDownloader.class); + private static final Logger LOG = LoggerFactory.getLogger(HslHubsDownloader.class); private static final ObjectMapper mapper = new ObjectMapper(); private final String jsonParsePath; @@ -29,17 +30,18 @@ public class HslHubsDownloader { public HslHubsDownloader( String url, String jsonParsePath, - Function> hubsParser + Function> hubsParser, + OtpHttpClientFactory otpHttpClientFactory ) { this.url = url; this.jsonParsePath = jsonParsePath; this.hubsParser = hubsParser; - otpHttpClient = new OtpHttpClient(); + otpHttpClient = otpHttpClientFactory.create(LOG); } public Map downloadHubs() { if (url == null) { - log.warn("Cannot download updates, because url is null!"); + LOG.warn("Cannot download updates, because url is null!"); return null; } try { @@ -50,17 +52,17 @@ public Map downloadHubs() { try { return parseJSON(is); } catch (IllegalArgumentException e) { - log.warn("Error parsing hubs from {}", url, e); + LOG.warn("Error parsing hubs from {}", url, e); } catch (JsonProcessingException e) { - log.warn("Error parsing hubs from {} (bad JSON of some sort)", url, e); + LOG.warn("Error parsing hubs from {} (bad JSON of some sort)", url, e); } catch (IOException e) { - log.warn("Error reading hubs from {}", url, e); + LOG.warn("Error reading hubs from {}", url, e); } return null; } ); } catch (OtpHttpClientException e) { - log.warn("Failed to get data from url {}", url); + LOG.warn("Failed to get data from url {}", url); return null; } } diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java index e5086630941..f5c5b33ef29 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java @@ -4,6 +4,7 @@ import java.util.Map; import java.util.stream.Collectors; import org.opentripplanner.framework.io.JsonDataListDownloader; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; import org.opentripplanner.routing.vehicle_parking.VehicleParking; import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; @@ -11,6 +12,8 @@ import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces.VehicleParkingSpacesBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.updater.spi.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Vehicle parking updater class for https://github.com/HSLdevcom/parkandrideAPI format APIs. There @@ -19,6 +22,8 @@ */ public class HslParkUpdater implements DataSource { + private static final Logger LOG = LoggerFactory.getLogger(HslParkUpdater.class); + private static final String JSON_PARSE_PATH = "results"; private final HslFacilitiesDownloader facilitiesDownloader; @@ -43,24 +48,28 @@ public HslParkUpdater( new HslParkToVehicleParkingMapper(feedId, openingHoursCalendarService, parameters.timeZone()); vehicleParkingGroupMapper = new HslHubToVehicleParkingGroupMapper(feedId); parkPatchMapper = new HslParkUtilizationToPatchMapper(feedId); + var otpHttpClientFactory = new OtpHttpClientFactory(); facilitiesDownloader = new HslFacilitiesDownloader( parameters.facilitiesUrl(), JSON_PARSE_PATH, - vehicleParkingMapper::parsePark + vehicleParkingMapper::parsePark, + otpHttpClientFactory ); hubsDownloader = new HslHubsDownloader( parameters.hubsUrl(), JSON_PARSE_PATH, - vehicleParkingGroupMapper::parseHub + vehicleParkingGroupMapper::parseHub, + otpHttpClientFactory ); utilizationsDownloader = new JsonDataListDownloader<>( parameters.utilizationsUrl(), "", parkPatchMapper::parseUtilization, - Map.of() + Map.of(), + otpHttpClientFactory.create(LOG) ); this.facilitiesFrequencySec = parameters.facilitiesFrequencySec(); } diff --git a/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java b/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java index d51d0d70b6c..9b350dec345 100644 --- a/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java +++ b/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java @@ -10,8 +10,8 @@ import java.util.Map; import java.util.Optional; import org.opentripplanner.ext.vehiclerentalservicedirectory.api.VehicleRentalServiceDirectoryFetcherParameters; -import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientException; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.json.JsonUtils; import org.opentripplanner.routing.linking.VertexLinker; import org.opentripplanner.service.vehiclerental.VehicleRentalRepository; @@ -35,16 +35,16 @@ public class VehicleRentalServiceDirectoryFetcher { private final VertexLinker vertexLinker; private final VehicleRentalRepository repository; - private final OtpHttpClient otpHttpClient; + private final OtpHttpClientFactory otpHttpClientFactory; public VehicleRentalServiceDirectoryFetcher( VertexLinker vertexLinker, VehicleRentalRepository repository, - OtpHttpClient otpHttpClient + OtpHttpClientFactory otpHttpClientFactory ) { this.vertexLinker = vertexLinker; this.repository = repository; - this.otpHttpClient = otpHttpClient; + this.otpHttpClientFactory = otpHttpClientFactory; } public static List createUpdatersFromEndpoint( @@ -61,12 +61,12 @@ public static List createUpdatersFromEndpoint( } int maxHttpConnections = sources.size(); - var otpHttpClient = new OtpHttpClient(maxHttpConnections); + var otpHttpClientFactory = new OtpHttpClientFactory(maxHttpConnections); var serviceDirectory = new VehicleRentalServiceDirectoryFetcher( vertexLinker, repository, - otpHttpClient + otpHttpClientFactory ); return serviceDirectory.createUpdatersFromEndpoint(parameters, sources); } @@ -146,7 +146,7 @@ private VehicleRentalUpdater fetchAndCreateUpdater( var dataSource = VehicleRentalDataSourceFactory.create( vehicleRentalParameters.sourceParameters(), - otpHttpClient + otpHttpClientFactory ); return new VehicleRentalUpdater(vehicleRentalParameters, dataSource, vertexLinker, repository); } @@ -154,7 +154,8 @@ private VehicleRentalUpdater fetchAndCreateUpdater( private static JsonNode listSources(VehicleRentalServiceDirectoryFetcherParameters parameters) { JsonNode node; URI url = parameters.getUrl(); - try (OtpHttpClient otpHttpClient = new OtpHttpClient()) { + try { + var otpHttpClient = new OtpHttpClientFactory().create(LOG); node = otpHttpClient.getAndMapAsJsonNode(url, Map.of(), new ObjectMapper()); } catch (OtpHttpClientException e) { LOG.warn("Error fetching list of vehicle rental endpoints from {}", url, e); diff --git a/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java b/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java index bf087d0c0ad..56afc888c73 100644 --- a/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java +++ b/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java @@ -11,13 +11,17 @@ import org.opentripplanner.datastore.api.FileType; import org.opentripplanner.datastore.base.DataSourceRepository; import org.opentripplanner.datastore.file.ZipStreamDataSourceDecorator; -import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This data store accesses files in read-only mode over HTTPS. */ public class HttpsDataSourceRepository implements DataSourceRepository { + private static final Logger LOG = LoggerFactory.getLogger(HttpsFileDataSource.class); + private static final Duration HTTP_HEAD_REQUEST_TIMEOUT = Duration.ofSeconds(20); @Override @@ -75,7 +79,8 @@ private CompositeDataSource createCompositeSource(URI uri, FileType type) { } protected List
getHttpHeaders(URI uri) { - try (OtpHttpClient otpHttpClient = new OtpHttpClient()) { + try (OtpHttpClientFactory otpHttpClientFactory = new OtpHttpClientFactory()) { + var otpHttpClient = otpHttpClientFactory.create(LOG); return otpHttpClient.getHeaders(uri, HTTP_HEAD_REQUEST_TIMEOUT, Map.of()); } } diff --git a/src/main/java/org/opentripplanner/datastore/https/HttpsFileDataSource.java b/src/main/java/org/opentripplanner/datastore/https/HttpsFileDataSource.java index 14b770036b8..f81f42f9c77 100644 --- a/src/main/java/org/opentripplanner/datastore/https/HttpsFileDataSource.java +++ b/src/main/java/org/opentripplanner/datastore/https/HttpsFileDataSource.java @@ -13,6 +13,9 @@ import org.opentripplanner.datastore.file.DirectoryDataSource; import org.opentripplanner.datastore.file.ZipFileDataSource; import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This class is a wrapper around an HTTPS resource. @@ -22,6 +25,8 @@ */ final class HttpsFileDataSource implements DataSource { + private static final Logger LOG = LoggerFactory.getLogger(HttpsFileDataSource.class); + private static final Duration HTTP_GET_REQUEST_TIMEOUT = Duration.ofSeconds(20); private final URI uri; private final FileType type; @@ -35,7 +40,7 @@ final class HttpsFileDataSource implements DataSource { this.uri = uri; this.type = type; this.httpsDataSourceMetadata = httpsDataSourceMetadata; - otpHttpClient = new OtpHttpClient(); + otpHttpClient = new OtpHttpClientFactory().create(LOG); } /** diff --git a/src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java b/src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java index bb602adb472..3affa734605 100644 --- a/src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java +++ b/src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java @@ -17,7 +17,7 @@ public class JsonDataListDownloader { - private static final Logger log = LoggerFactory.getLogger(JsonDataListDownloader.class); + private static final Logger LOG = LoggerFactory.getLogger(JsonDataListDownloader.class); private final String jsonParsePath; private final Map headers; private final Function elementParser; @@ -30,7 +30,7 @@ public JsonDataListDownloader( @Nonnull Function elementParser, @Nonnull Map headers ) { - this(url, jsonParsePath, elementParser, headers, new OtpHttpClient()); + this(url, jsonParsePath, elementParser, headers, new OtpHttpClientFactory().create(LOG)); } public JsonDataListDownloader( @@ -49,7 +49,7 @@ public JsonDataListDownloader( public List download() { if (url == null) { - log.warn("Cannot download updates, because url is null!"); + LOG.warn("Cannot download updates, because url is null!"); return null; } try { @@ -60,17 +60,17 @@ public List download() { try { return parseJSON(is); } catch (IllegalArgumentException e) { - log.warn("Error parsing bike rental feed from {}", url, e); + LOG.warn("Error parsing feed from {}", url, e); } catch (JsonProcessingException e) { - log.warn("Error parsing bike rental feed from {} (bad JSON of some sort)", url, e); + LOG.warn("Error parsing feed from {} (bad JSON of some sort)", url, e); } catch (IOException e) { - log.warn("Error reading bike rental feed from {}", url, e); + LOG.warn("Error reading feed from {}", url, e); } return null; } ); } catch (OtpHttpClientException e) { - log.warn("Failed to get data from url {}", url); + LOG.warn("Failed to get data from url {}", url); return null; } } @@ -111,7 +111,7 @@ private List parseJSON(InputStream dataStream) throws IllegalArgumentExceptio out.add(parsedElement); } } catch (Exception e) { - log.error("Could not process element in JSON list downloaded from {}", url, e); + LOG.error("Could not process element in JSON list downloaded from {}", url, e); } } return out; diff --git a/src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java b/src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java index 1ac8891553c..678eb4754bd 100644 --- a/src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java +++ b/src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; @@ -14,17 +16,13 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; -import org.apache.hc.client5.http.config.ConnectionConfig; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; -import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; -import org.apache.hc.client5.http.impl.classic.HttpClients; -import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; -import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.Header; @@ -32,14 +30,9 @@ import org.apache.hc.core5.http.HttpHeaders; import org.apache.hc.core5.http.HttpResponse; import org.apache.hc.core5.http.io.HttpClientResponseHandler; -import org.apache.hc.core5.http.io.SocketConfig; import org.apache.hc.core5.http.io.entity.StringEntity; -import org.apache.hc.core5.pool.PoolConcurrencyPolicy; -import org.apache.hc.core5.pool.PoolReusePolicy; -import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * HTTP client providing convenience methods to send HTTP requests and map HTTP responses to Java @@ -50,101 +43,27 @@ *

Exception management

* Exceptions thrown during network operations or response mapping are wrapped in * {@link OtpHttpClientException} - *

Timeout configuration

- * The same timeout value is applied to the following parameters: - *
    - *
  • Connection request timeout: the maximum waiting time for leasing a connection in the - * connection pool. - *
  • Connect timeout: the maximum waiting time for the first packet received from the server. - *
  • Socket timeout: the maximum waiting time between two packets received from the server. - *
- * The default timeout is set to 5 seconds. - *

Connection time-to-live

- * Maximum time an HTTP connection can stay in the connection pool before being closed. - * Note that HTTP 1.1 and HTTP/2 rely on persistent connections and the HTTP server is allowed to - * close idle connections at any time. - * The default connection time-to-live is set to 1 minute. *

Resource management

- * It is recommended to use the getAndMapXXX and postAndMapXXX methods - * in this class since they - * ensure that the underlying network resources are properly released. - * The method {@link #getAsInputStream} gives access to an input stream on the body response but - * requires the caller to close this stream. For most use cases, this method is not recommended . - *

Connection Pooling

- * The connection pool holds by default a maximum of 25 connections, with maximum 5 connections - * per host. + * It is recommended to use the getAndMapXXX and postAndMapXXX methods in + * this class since they ensure that the underlying network resources are properly released. The + * method {@link #getAsInputStream} gives access to an input stream on the body response but + * requires the caller to close this stream. For most use cases, this method is not recommended. * *

Thread-safety

* Instances of this class are thread-safe. */ -public class OtpHttpClient implements AutoCloseable { - - private static final Logger LOG = LoggerFactory.getLogger(OtpHttpClient.class); - private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(5); - - private static final Duration DEFAULT_TTL = Duration.ofMinutes(1); - - /** - * see {@link PoolingHttpClientConnectionManager#DEFAULT_MAX_TOTAL_CONNECTIONS} - */ - public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 25; +public class OtpHttpClient { private final CloseableHttpClient httpClient; - /** - * Creates an HTTP client with default timeout, default connection time-to-live and default max - * number of connections. - */ - public OtpHttpClient() { - this(DEFAULT_TIMEOUT, DEFAULT_TTL); - } - - /** - * Creates an HTTP client with default timeout, default connection time-to-live and the given max - * number of connections. - */ - public OtpHttpClient(int maxConnections) { - this(DEFAULT_TIMEOUT, DEFAULT_TTL, maxConnections); - } - - /** - * Creates an HTTP client the given timeout and connection time-to-live and the default max - * number of connections. - */ - public OtpHttpClient(Duration timeout, Duration connectionTtl) { - this(timeout, connectionTtl, DEFAULT_MAX_TOTAL_CONNECTIONS); - } + private final Logger log; /** * Creates an HTTP client with custom configuration. */ - private OtpHttpClient(Duration timeout, Duration connectionTtl, int maxConnections) { - Objects.requireNonNull(timeout); - Objects.requireNonNull(connectionTtl); - - PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder - .create() - .setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(Timeout.of(timeout)).build()) - .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT) - .setConnPoolPolicy(PoolReusePolicy.LIFO) - .setMaxConnTotal(maxConnections) - .setDefaultConnectionConfig( - ConnectionConfig - .custom() - .setSocketTimeout(Timeout.of(timeout)) - .setConnectTimeout(Timeout.of(timeout)) - .setTimeToLive(TimeValue.of(connectionTtl)) - .build() - ) - .build(); - - HttpClientBuilder httpClientBuilder = HttpClients - .custom() - .setUserAgent("OpenTripPlanner") - .setConnectionManager(connectionManager) - .setDefaultRequestConfig(requestConfig(timeout)); - - httpClient = httpClientBuilder.build(); + OtpHttpClient(CloseableHttpClient httpClient, Logger logger) { + this.httpClient = httpClient; + log = logger; } /** @@ -162,7 +81,8 @@ public List
getHeaders( requestHeaderValues, response -> { if (isFailedRequest(response)) { - LOG.warn( + logResponse(response); + log.warn( "Headers of resource {} unavailable. HTTP error code {}", sanitizeUri(uri), response.getCode() @@ -347,15 +267,6 @@ public Optional executeAndMapOptional( ); } - @Override - public void close() { - try { - httpClient.close(); - } catch (IOException e) { - throw new OtpHttpClientException(e); - } - } - /** * Executes an HTTP GET request and returns an input stream on the response body. The caller must * close the stream in order to release resources. Use preferably the provided getAndMapXXX @@ -416,6 +327,7 @@ protected T executeAndMapWithResponseHandler( private T mapResponse(ClassicHttpResponse response, ResponseMapper contentMapper) { if (isFailedRequest(response)) { + logResponse(response); throw new OtpHttpClientException( "HTTP request failed with status code " + response.getCode() ); @@ -485,6 +397,24 @@ private static String sanitizeUri(URI uri) { return uri.toString().replace('?' + uri.getQuery(), ""); } + private void logResponse(ClassicHttpResponse response) { + try { + if ( + log.isTraceEnabled() && + response.getEntity() != null && + response.getEntity().getContent() != null + ) { + var entity = response.getEntity(); + String content = new BufferedReader(new InputStreamReader(entity.getContent())) + .lines() + .collect(Collectors.joining("\n")); + log.trace("HTTP request failed with status code {}: \n{}", response.getCode(), content); + } + } catch (Exception e) { + log.debug(e.getMessage()); + } + } + @FunctionalInterface public interface ResponseMapper { /** diff --git a/src/main/java/org/opentripplanner/framework/io/OtpHttpClientFactory.java b/src/main/java/org/opentripplanner/framework/io/OtpHttpClientFactory.java new file mode 100644 index 00000000000..a6436168541 --- /dev/null +++ b/src/main/java/org/opentripplanner/framework/io/OtpHttpClientFactory.java @@ -0,0 +1,137 @@ +package org.opentripplanner.framework.io; + +import java.io.IOException; +import java.time.Duration; +import java.util.Objects; +import org.apache.hc.client5.http.config.ConnectionConfig; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.core5.http.io.SocketConfig; +import org.apache.hc.core5.pool.PoolConcurrencyPolicy; +import org.apache.hc.core5.pool.PoolReusePolicy; +import org.apache.hc.core5.util.TimeValue; +import org.apache.hc.core5.util.Timeout; +import org.slf4j.Logger; + +/** + * Factory for creating {@link OtpHttpClient} instances. These instances will share the same + * {@link CloseableHttpClient} instance. + * + *

Timeout configuration

+ * The same timeout value is applied to the following parameters: + *
    + *
  • Connection request timeout: the maximum waiting time for leasing a connection in the + * connection pool. + *
  • Connect timeout: the maximum waiting time for the first packet received from the server. + *
  • Socket timeout: the maximum waiting time between two packets received from the server. + *
+ * The default timeout is set to 5 seconds. + *

Connection time-to-live

+ * Maximum time an HTTP connection can stay in the connection pool before being closed. + * Note that HTTP 1.1 and HTTP/2 rely on persistent connections and the HTTP server is allowed to + * close idle connections at any time. + * The default connection time-to-live is set to 1 minute. + *

Connection Pooling

+ * The connection pool holds by default a maximum of 25 connections, with maximum 5 connections + * per host. + * + *

Thread-safety

+ * Instances of this class are thread-safe. + */ +public class OtpHttpClientFactory implements AutoCloseable { + + private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(5); + + private static final Duration DEFAULT_TTL = Duration.ofMinutes(1); + + /** + * see {@link PoolingHttpClientConnectionManager#DEFAULT_MAX_TOTAL_CONNECTIONS} + */ + public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 25; + + private final CloseableHttpClient httpClient; + + /** + * Creates an HTTP client with default timeout, default connection time-to-live and default max + * number of connections. + */ + public OtpHttpClientFactory() { + this(DEFAULT_TIMEOUT, DEFAULT_TTL); + } + + /** + * Creates an HTTP client with default timeout, default connection time-to-live and the given max + * number of connections. + */ + public OtpHttpClientFactory(int maxConnections) { + this(DEFAULT_TIMEOUT, DEFAULT_TTL, maxConnections); + } + + /** + * Creates an HTTP client the given timeout and connection time-to-live and the default max + * number of connections. + */ + public OtpHttpClientFactory(Duration timeout, Duration connectionTtl) { + this(timeout, connectionTtl, DEFAULT_MAX_TOTAL_CONNECTIONS); + } + + /** + * Creates an HTTP client with custom configuration. + */ + private OtpHttpClientFactory(Duration timeout, Duration connectionTtl, int maxConnections) { + Objects.requireNonNull(timeout); + Objects.requireNonNull(connectionTtl); + + PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder + .create() + .setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(Timeout.of(timeout)).build()) + .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT) + .setConnPoolPolicy(PoolReusePolicy.LIFO) + .setMaxConnTotal(maxConnections) + .setDefaultConnectionConfig( + ConnectionConfig + .custom() + .setSocketTimeout(Timeout.of(timeout)) + .setConnectTimeout(Timeout.of(timeout)) + .setTimeToLive(TimeValue.of(connectionTtl)) + .build() + ) + .build(); + + HttpClientBuilder httpClientBuilder = HttpClients + .custom() + .setUserAgent("OpenTripPlanner") + .setConnectionManager(connectionManager) + .setDefaultRequestConfig(requestConfig(timeout)); + + httpClient = httpClientBuilder.build(); + } + + public OtpHttpClient create(Logger logger) { + return new OtpHttpClient(httpClient, logger); + } + + @Override + public void close() { + try { + httpClient.close(); + } catch (IOException e) { + throw new OtpHttpClientException(e); + } + } + + /** + * Configures the request with a custom timeout. + */ + private static RequestConfig requestConfig(Duration timeout) { + return RequestConfig + .custom() + .setResponseTimeout(Timeout.of(timeout)) + .setConnectionRequestTimeout(Timeout.of(timeout)) + .build(); + } +} diff --git a/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java b/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java index 21f6c81bc67..364972531c2 100644 --- a/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java +++ b/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java @@ -3,6 +3,7 @@ import com.google.transit.realtime.GtfsRealtime.FeedMessage; import java.net.URI; import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.routing.services.TransitAlertService; @@ -50,7 +51,7 @@ public GtfsRealtimeAlertsUpdater( this.updateHandler.setFeedId(config.feedId()); this.updateHandler.setTransitAlertService(transitAlertService); this.updateHandler.setFuzzyTripMatcher(fuzzyTripMatcher); - this.otpHttpClient = new OtpHttpClient(); + this.otpHttpClient = new OtpHttpClientFactory().create(LOG); LOG.info("Creating real-time alert updater running every {}: {}", pollingPeriod(), url); } diff --git a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java index c755578da41..3b6f7f52279 100644 --- a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java +++ b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java @@ -10,7 +10,7 @@ import org.opentripplanner.ext.siri.updater.azure.SiriAzureSXUpdater; import org.opentripplanner.ext.vehiclerentalservicedirectory.VehicleRentalServiceDirectoryFetcher; import org.opentripplanner.ext.vehiclerentalservicedirectory.api.VehicleRentalServiceDirectoryFetcherParameters; -import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository; @@ -28,6 +28,8 @@ import org.opentripplanner.updater.vehicle_position.PollingVehiclePositionUpdater; import org.opentripplanner.updater.vehicle_rental.VehicleRentalUpdater; import org.opentripplanner.updater.vehicle_rental.datasources.VehicleRentalDataSourceFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Sets up and starts all the graph updaters. @@ -38,6 +40,8 @@ */ public class UpdaterConfigurator { + private static final Logger LOG = LoggerFactory.getLogger(UpdaterConfigurator.class); + private final Graph graph; private final TransitModel transitModel; private final UpdatersParameters updatersParameters; @@ -137,11 +141,11 @@ private List createUpdatersFromConfig() { if (!updatersParameters.getVehicleRentalParameters().isEmpty()) { int maxHttpConnections = updatersParameters.getVehicleRentalParameters().size(); - OtpHttpClient otpHttpClient = new OtpHttpClient(maxHttpConnections); + var otpHttpClientFactory = new OtpHttpClientFactory(maxHttpConnections); for (var configItem : updatersParameters.getVehicleRentalParameters()) { var source = VehicleRentalDataSourceFactory.create( configItem.sourceParameters(), - otpHttpClient + otpHttpClientFactory ); updaters.add( new VehicleRentalUpdater(configItem, source, graph.getLinker(), vehicleRentalRepository) diff --git a/src/main/java/org/opentripplanner/updater/spi/GenericJsonDataSource.java b/src/main/java/org/opentripplanner/updater/spi/GenericJsonDataSource.java index df275073f72..894c0a0466f 100644 --- a/src/main/java/org/opentripplanner/updater/spi/GenericJsonDataSource.java +++ b/src/main/java/org/opentripplanner/updater/spi/GenericJsonDataSource.java @@ -4,6 +4,7 @@ import java.util.List; import org.opentripplanner.framework.io.JsonDataListDownloader; import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,7 +16,7 @@ public abstract class GenericJsonDataSource implements DataSource { protected List updates = List.of(); protected GenericJsonDataSource(String url, String jsonParsePath, HttpHeaders headers) { - this(url, jsonParsePath, headers, new OtpHttpClient()); + this(url, jsonParsePath, headers, new OtpHttpClientFactory().create(LOG)); } protected GenericJsonDataSource( diff --git a/src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java b/src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java index 765f6d11845..12a044424ca 100644 --- a/src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java +++ b/src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.List; import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.updater.spi.HttpHeaders; import org.slf4j.Logger; @@ -33,7 +34,7 @@ public GtfsRealtimeTripUpdateSource(PollingTripUpdaterParameters config) { this.url = config.url(); this.headers = HttpHeaders.of().acceptProtobuf().add(config.headers()).build(); MfdzRealtimeExtensions.registerAllExtensions(registry); - otpHttpClient = new OtpHttpClient(); + otpHttpClient = new OtpHttpClientFactory().create(LOG); } public List getUpdates() { diff --git a/src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java b/src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java index 5983eef7c40..ec0be6822e7 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java @@ -9,6 +9,7 @@ import java.util.List; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientException; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.updater.spi.HttpHeaders; import org.slf4j.Logger; @@ -33,7 +34,7 @@ public class GtfsRealtimeHttpVehiclePositionSource { public GtfsRealtimeHttpVehiclePositionSource(URI url, HttpHeaders headers) { this.url = url; this.headers = HttpHeaders.of().acceptProtobuf().add(headers).build(); - this.otpHttpClient = new OtpHttpClient(); + this.otpHttpClient = new OtpHttpClientFactory().create(LOG); } /** diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoader.java b/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoader.java index 58a625192f9..d4e5cbd4952 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoader.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoader.java @@ -13,6 +13,7 @@ import org.entur.gbfs.v2_3.gbfs.GBFSFeeds; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientException; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.spi.UpdaterConstructionException; import org.slf4j.Logger; @@ -98,7 +99,7 @@ public GbfsFeedLoader( } GbfsFeedLoader(String url, HttpHeaders httpHeaders, String languageCode) { - this(url, httpHeaders, languageCode, new OtpHttpClient()); + this(url, httpHeaders, languageCode, new OtpHttpClientFactory().create(LOG)); } /** diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java b/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java index 8cc8897f0de..aed214102ff 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java @@ -16,6 +16,7 @@ import org.entur.gbfs.v2_3.vehicle_types.GBFSVehicleTypes; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.service.vehiclerental.model.GeofencingZone; import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; @@ -46,10 +47,10 @@ class GbfsVehicleRentalDataSource implements VehicleRentalDatasource { public GbfsVehicleRentalDataSource( GbfsVehicleRentalDataSourceParameters parameters, - OtpHttpClient otpHttpClient + OtpHttpClientFactory otpHttpClientFactory ) { this.params = parameters; - this.otpHttpClient = otpHttpClient; + this.otpHttpClient = otpHttpClientFactory.create(LOG); } @Override diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDataSourceFactory.java b/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDataSourceFactory.java index 50e26d82459..bd921a70edb 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDataSourceFactory.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDataSourceFactory.java @@ -2,7 +2,7 @@ import org.opentripplanner.ext.smoovebikerental.SmooveBikeRentalDataSource; import org.opentripplanner.ext.smoovebikerental.SmooveBikeRentalDataSourceParameters; -import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters; import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters; @@ -10,7 +10,7 @@ public class VehicleRentalDataSourceFactory { public static VehicleRentalDatasource create( VehicleRentalDataSourceParameters source, - OtpHttpClient otpHttpClient + OtpHttpClientFactory otpHttpClientFactory ) { return switch (source.sourceType()) { // There used to be a lot more updaters and corresponding config variables here, but since @@ -20,11 +20,11 @@ public static VehicleRentalDatasource create( // and become the point of contact for the community. case GBFS -> new GbfsVehicleRentalDataSource( (GbfsVehicleRentalDataSourceParameters) source, - otpHttpClient + otpHttpClientFactory ); case SMOOVE -> new SmooveBikeRentalDataSource( (SmooveBikeRentalDataSourceParameters) source, - otpHttpClient + otpHttpClientFactory ); }; } diff --git a/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoaderTest.java b/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoaderTest.java index 5bb9a3a750c..9a0dbcdfe87 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoaderTest.java +++ b/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoaderTest.java @@ -28,8 +28,9 @@ import org.entur.gbfs.v2_3.vehicle_types.GBFSVehicleTypes; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.updater.spi.HttpHeaders; +import org.slf4j.LoggerFactory; /** * This tests that {@link GbfsFeedLoader} handles loading of different versions of GBFS correctly, @@ -90,7 +91,10 @@ void getV10FeedWithExplicitLanguage() { @Test @Disabled void fetchAllPublicFeeds() { - try (OtpHttpClient otpHttpClient = new OtpHttpClient()) { + try (OtpHttpClientFactory otpHttpClientFactory = new OtpHttpClientFactory()) { + var otpHttpClient = otpHttpClientFactory.create( + LoggerFactory.getLogger(GbfsFeedLoaderTest.class) + ); List exceptions = otpHttpClient.getAndMap( URI.create("https://raw.githubusercontent.com/NABSA/gbfs/master/systems.csv"), Map.of(), diff --git a/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java b/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java index dba2e10510b..018a3d06e5b 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java +++ b/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java @@ -10,7 +10,7 @@ import java.util.Map; import org.entur.gbfs.v2_3.vehicle_types.GBFSVehicleType; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.service.vehiclerental.model.GeofencingZone; import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; @@ -34,7 +34,7 @@ void makeStationFromV22() { false, false ), - new OtpHttpClient() + new OtpHttpClientFactory() ); dataSource.setup(); @@ -125,7 +125,7 @@ void geofencing() { true, false ), - new OtpHttpClient() + new OtpHttpClientFactory() ); dataSource.setup(); @@ -167,7 +167,7 @@ void makeStationFromV10() { false, true ), - new OtpHttpClient() + new OtpHttpClientFactory() ); dataSource.setup();