From 7d7ead3baf11a2a893bd7b221c9d66c74b359bfd Mon Sep 17 00:00:00 2001 From: Michael Reichert Date: Mon, 7 May 2018 17:27:59 +0200 Subject: [PATCH 1/2] Allow cookies to be sent with HTTP replication requests --- .../replication/common/ReplicationCookie.java | 77 +++++++++++++++++++ .../replication/common/ServerStateReader.java | 45 ++++++++++- .../v0_6/BaseReplicationDownloader.java | 34 ++++---- .../v0_6/ReplicationFileMerger.java | 5 +- .../v0_6/ReplicationLagReader.java | 9 ++- .../ReplicationDownloaderConfiguration.java | 10 +++ 6 files changed, 158 insertions(+), 22 deletions(-) create mode 100644 osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ReplicationCookie.java diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ReplicationCookie.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ReplicationCookie.java new file mode 100644 index 000000000..8d8d169cc --- /dev/null +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ReplicationCookie.java @@ -0,0 +1,77 @@ +// This software is released into the Public Domain. See copying.txt for details. +package org.openstreetmap.osmosis.replication.common; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import org.openstreetmap.osmosis.core.OsmosisRuntimeException; + +/** + * Cookie to be sent with all HTTP requests. The cookie is read from a file. + * + * @author Michael Reichert + */ +public class ReplicationCookie { + private static final String COOKIE_FILE_NAME = "cookie.txt"; + + private Path directory; + private String data; + + /** + * Create an invalid dummy cookie. + */ + public ReplicationCookie() { + directory = null; + data = null; + } + + /** + * Creates an empty cookie. + * + * @param cookieDirectory directory to read the cookie.txt from + */ + public ReplicationCookie(Path cookieDirectory) { + directory = cookieDirectory; + data = ""; + } + + /** + * Check if this cookie is not empty and used. + * + * @return False if it has not been set. + */ + public boolean valid() { + return data != null && !data.isEmpty(); + } + + /** + * Get the string representation of the cookie to be set as HTTP header. + * + * @return string representation + */ + public String toString() { + return data; + } + + /** + * Read the cookie from a file name cookie.txt in the working directory. + */ + public void read() { + Path cookieFilePath = directory.resolve(Paths.get(COOKIE_FILE_NAME)); + try { + List lines = Files.readAllLines(cookieFilePath, Charset.forName("US-ASCII")); + if (lines.size() == 1) { + data = lines.get(0); + } else { + throw new OsmosisRuntimeException("The cookie file " + cookieFilePath.toString() + + " must contain exactly one line."); + } + } catch (IOException e) { + throw new OsmosisRuntimeException("Failed to read the cookie file " + cookieFilePath.toString()); + } + } +} diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ServerStateReader.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ServerStateReader.java index 175ebe57a..0b151cf27 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ServerStateReader.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ServerStateReader.java @@ -38,18 +38,36 @@ public ServerStateReader() { /** * Retrieves the latest state from the server. * + * No cookie will be sent with the HTTP request. + * * @param baseUrl * The url of the directory containing change files. * @return The state. */ public ReplicationState getServerState(URL baseUrl) { - return getServerState(baseUrl, SERVER_STATE_FILE); + return getServerState(baseUrl, SERVER_STATE_FILE, new ReplicationCookie()); + } + + + /** + * Retrieves the latest state from the server. + * + * @param baseUrl + * The url of the directory containing change files. + * @param cookie + * Cookie to send with each HTTP request. + * @return The state. + */ + public ReplicationState getServerState(URL baseUrl, ReplicationCookie cookie) { + return getServerState(baseUrl, SERVER_STATE_FILE, cookie); } /** * Retrieves the specified state from the server. * + * No cookie will be sent with the HTTP request. + * * @param baseUrl * The url of the directory containing change files. * @param sequenceNumber @@ -57,7 +75,23 @@ public ReplicationState getServerState(URL baseUrl) { * @return The state. */ public ReplicationState getServerState(URL baseUrl, long sequenceNumber) { - return getServerState(baseUrl, sequenceFormatter.getFormattedName(sequenceNumber, SEQUENCE_STATE_FILE_SUFFIX)); + return getServerState(baseUrl, sequenceNumber, new ReplicationCookie()); + } + + + /** + * Retrieves the specified state from the server. + * + * @param baseUrl + * The url of the directory containing change files. + * @param sequenceNumber + * The sequence number of the state to be retrieved from the server. + * @param cookie + * Cookie to send with each HTTP request. + * @return The state. + */ + public ReplicationState getServerState(URL baseUrl, long sequenceNumber, ReplicationCookie cookie) { + return getServerState(baseUrl, sequenceFormatter.getFormattedName(sequenceNumber, SEQUENCE_STATE_FILE_SUFFIX), cookie); } @@ -68,9 +102,11 @@ public ReplicationState getServerState(URL baseUrl, long sequenceNumber) { * The url of the directory containing change files. * @param stateFile * The state file to be retrieved. + * @param cookie + * Cookie to send with each HTTP request. * @return The state. */ - private ReplicationState getServerState(URL baseUrl, String stateFile) { + private ReplicationState getServerState(URL baseUrl, String stateFile, ReplicationCookie cookie) { URL stateUrl; try { @@ -88,6 +124,9 @@ private ReplicationState getServerState(URL baseUrl, String stateFile) { connection.setReadTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setConnectTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setRequestProperty("User-Agent", "Osmosis/" + OsmosisConstants.VERSION); + if (cookie.valid()) { + connection.setRequestProperty("Cookie", cookie.toString()); + } try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { stateProperties = new Properties(); stateProperties.load(reader); diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/BaseReplicationDownloader.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/BaseReplicationDownloader.java index 6f46093a8..0ba9317d6 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/BaseReplicationDownloader.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/BaseReplicationDownloader.java @@ -19,6 +19,7 @@ import org.openstreetmap.osmosis.core.task.common.RunnableTask; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.core.util.PropertiesPersister; +import org.openstreetmap.osmosis.replication.common.ReplicationCookie; import org.openstreetmap.osmosis.replication.common.ReplicationSequenceFormatter; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.replication.common.ServerStateReader; @@ -45,6 +46,8 @@ public abstract class BaseReplicationDownloader implements RunnableTask { private File workingDirectory; private ReplicationSequenceFormatter sequenceFormatter; private ServerStateReader serverStateReader; + protected ReplicationDownloaderConfiguration configuration; + private ReplicationCookie cookie; /** @@ -58,6 +61,12 @@ public BaseReplicationDownloader(File workingDirectory) { sequenceFormatter = new ReplicationSequenceFormatter(9, 3); serverStateReader = new ServerStateReader(); + + configuration = new ReplicationDownloaderConfiguration(new File(workingDirectory, CONFIG_FILE)); + cookie = new ReplicationCookie(workingDirectory.toPath()); + if (configuration.getAttachCookie()) { + cookie.read(); + } } @@ -98,7 +107,10 @@ private File downloadReplicationFile(String fileName, URL baseUrl) { connection.setReadTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setConnectTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setRequestProperty("User-Agent", "Osmosis/" + OsmosisConstants.VERSION); - + if (cookie.valid()) { + connection.setRequestProperty("Cookie", cookie.toString()); + } + try (BufferedInputStream source = new BufferedInputStream(connection.getInputStream(), 65536)) { // Create a temporary file to write the data to. outputFile = File.createTempFile("change", null); @@ -146,16 +158,13 @@ private void processReplicationFile(File replicationFile, ReplicationState repli * limit the maximum timestamp further if needed. A sub-class may never increase the maximum * timestamp beyond that calculated by this method. * - * @param configuration - * The configuration. * @param serverTimestamp * The timestamp of the latest data on the server. * @param localTimestamp * The timestamp of the most recently downloaded data. * @return The maximum timestamp for this invocation. */ - protected Date calculateMaximumTimestamp(ReplicationDownloaderConfiguration configuration, Date serverTimestamp, - Date localTimestamp) { + protected Date calculateMaximumTimestamp(Date serverTimestamp, Date localTimestamp) { Date maximumTimestamp; maximumTimestamp = serverTimestamp; @@ -174,8 +183,7 @@ protected Date calculateMaximumTimestamp(ReplicationDownloaderConfiguration conf } - private ReplicationState download(ReplicationDownloaderConfiguration configuration, ReplicationState serverState, - ReplicationState initialLocalState) { + private ReplicationState download(ReplicationState serverState, ReplicationState initialLocalState) { URL baseUrl; ReplicationState localState; Date maximumDownloadTimestamp; @@ -187,7 +195,7 @@ private ReplicationState download(ReplicationDownloaderConfiguration configurati // Determine the maximum timestamp that can be downloaded. maximumDownloadTimestamp = - calculateMaximumTimestamp(configuration, serverState.getTimestamp(), localState.getTimestamp()); + calculateMaximumTimestamp(serverState.getTimestamp(), localState.getTimestamp()); LOG.fine("The maximum timestamp to be downloaded is " + maximumDownloadTimestamp + "."); // Download all files and send their contents to the sink. @@ -210,7 +218,7 @@ private ReplicationState download(ReplicationDownloaderConfiguration configurati LOG.finer("Processing replication sequence " + sequenceNumber + "."); // Get the state associated with the next file. - fileReplicationState = serverStateReader.getServerState(baseUrl, sequenceNumber); + fileReplicationState = serverStateReader.getServerState(baseUrl, sequenceNumber, cookie); // Ensure that the next state is within the allowable timestamp // range. We must stop if the next data takes us beyond the maximum @@ -244,17 +252,13 @@ private ReplicationState download(ReplicationDownloaderConfiguration configurati private void runImpl() { try { - ReplicationDownloaderConfiguration configuration; ReplicationState serverState; ReplicationState localState; PropertiesPersister localStatePersistor; - // Instantiate utility objects. - configuration = new ReplicationDownloaderConfiguration(new File(workingDirectory, CONFIG_FILE)); - // Obtain the server state. LOG.fine("Reading current server state."); - serverState = serverStateReader.getServerState(configuration.getBaseUrl()); + serverState = serverStateReader.getServerState(configuration.getBaseUrl(), cookie); // Build the local state persister which is used for both loading and storing local state. localStatePersistor = new PropertiesPersister(new File(workingDirectory, LOCAL_STATE_FILE)); @@ -268,7 +272,7 @@ private void runImpl() { localState = new ReplicationState(localStatePersistor.loadMap()); // Download and process the replication files. - localState = download(configuration, serverState, localState); + localState = download(serverState, localState); } else { localState = serverState; diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationFileMerger.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationFileMerger.java index f4f03eedd..cc95a299b 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationFileMerger.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationFileMerger.java @@ -69,8 +69,7 @@ private Date alignDateToIntervalBoundary(Date requestedDate, long intervalLength * {@inheritDoc} */ @Override - protected Date calculateMaximumTimestamp(ReplicationDownloaderConfiguration configuration, Date serverTimestamp, - Date localTimestamp) { + protected Date calculateMaximumTimestamp(Date serverTimestamp, Date localTimestamp) { Date maximumTimestamp; long intervalLength; @@ -78,7 +77,7 @@ protected Date calculateMaximumTimestamp(ReplicationDownloaderConfiguration conf currentDataState = replicationStore.getCurrentState(); // Get the default maximum timestamp according to base calculations. - maximumTimestamp = super.calculateMaximumTimestamp(configuration, serverTimestamp, localTimestamp); + maximumTimestamp = super.calculateMaximumTimestamp(serverTimestamp, localTimestamp); // Align the maximum timestamp to an interval boundary. intervalLength = getConfiguration().getIntervalLength(); diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationLagReader.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationLagReader.java index 0e6f81a50..53fcc1126 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationLagReader.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationLagReader.java @@ -9,6 +9,7 @@ import org.openstreetmap.osmosis.core.task.common.RunnableTask; import org.openstreetmap.osmosis.core.util.FileBasedLock; import org.openstreetmap.osmosis.core.util.PropertiesPersister; +import org.openstreetmap.osmosis.replication.common.ReplicationCookie; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.replication.common.ServerStateReader; import org.openstreetmap.osmosis.replication.v0_6.impl.ReplicationDownloaderConfiguration; @@ -59,10 +60,16 @@ private void getLag() { // Instantiate utility objects. configuration = new ReplicationDownloaderConfiguration(new File(workingDirectory, CONFIG_FILE)); + + // read cookie if necessary + ReplicationCookie cookie = new ReplicationCookie(workingDirectory.toPath()); + if (configuration.getAttachCookie()) { + cookie.read(); + } // Obtain the server state. LOG.fine("Reading current server state."); - serverState = serverStateReader.getServerState(configuration.getBaseUrl()); + serverState = serverStateReader.getServerState(configuration.getBaseUrl(), cookie); // Build the local state persister which is used for both loading and storing local state. localStatePersistor = new PropertiesPersister(new File(workingDirectory, LOCAL_STATE_FILE)); diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl/ReplicationDownloaderConfiguration.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl/ReplicationDownloaderConfiguration.java index 19465f070..6f6f08923 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl/ReplicationDownloaderConfiguration.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl/ReplicationDownloaderConfiguration.java @@ -18,6 +18,7 @@ public class ReplicationDownloaderConfiguration { private static final String KEY_BASE_URL = "baseUrl"; private static final String KEY_MAX_INTERVAL = "maxInterval"; + private static final String ATTACH_COOKIE = "attachCookie"; private Properties properties; @@ -65,4 +66,13 @@ public URL getBaseUrl() { public int getMaxInterval() { return Integer.parseInt(properties.getProperty(KEY_MAX_INTERVAL)) * 1000; } + + /** + * Returns whether a cookie stored in cookie.txt should be sent with each request. + * + * @return If a cookie should be send. + */ + public boolean getAttachCookie() { + return Boolean.parseBoolean(properties.getProperty(ATTACH_COOKIE)); + } } From aa20a23d9f61fcc61154e877b1f594650fa7b329 Mon Sep 17 00:00:00 2001 From: Michael Reichert Date: Tue, 8 May 2018 17:04:40 +0200 Subject: [PATCH 2/2] check the cookie before using it and throw an exception if that fails --- .../replication/common/ReplicationCookie.java | 49 ++++++++++++++++++- .../replication/common/ServerStateReader.java | 3 +- .../v0_6/BaseReplicationDownloader.java | 7 ++- .../v0_6/ReplicationFileMerger.java | 1 - .../v0_6/ReplicationLagReader.java | 6 ++- .../ReplicationDownloaderConfiguration.java | 22 ++++++++- 6 files changed, 81 insertions(+), 7 deletions(-) diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ReplicationCookie.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ReplicationCookie.java index 8d8d169cc..21bf03f9a 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ReplicationCookie.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ReplicationCookie.java @@ -2,12 +2,15 @@ package org.openstreetmap.osmosis.replication.common; import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; +import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** @@ -19,6 +22,7 @@ public class ReplicationCookie { private static final String COOKIE_FILE_NAME = "cookie.txt"; private Path directory; + private URL cookieStatusAPI; private String data; /** @@ -26,6 +30,7 @@ public class ReplicationCookie { */ public ReplicationCookie() { directory = null; + cookieStatusAPI = null; data = null; } @@ -34,8 +39,9 @@ public ReplicationCookie() { * * @param cookieDirectory directory to read the cookie.txt from */ - public ReplicationCookie(Path cookieDirectory) { + public ReplicationCookie(Path cookieDirectory, URL cookieStatusApiUrl) { directory = cookieDirectory; + cookieStatusAPI = cookieStatusApiUrl; data = ""; } @@ -74,4 +80,45 @@ public void read() { throw new OsmosisRuntimeException("Failed to read the cookie file " + cookieFilePath.toString()); } } + + /** + * Throw a OsmosisRuntimeException if the cookie isn't accepted by the server any more. + * + * @throws OsmosisRuntimeException + */ + public void throw_if_expired() { + if (!accepted()) { + throw new OsmosisRuntimeException("Your cookie is not valid anymore."); + } + } + + /** + * Check if the cookie is still accepted by the server + * + * @return acceptance + * + * @throws OsmosisRuntimeException for empty cookies and IOExceptions + */ + public boolean accepted() { + if (!valid()) { + throw new OsmosisRuntimeException("Cannot check if the cookie is expired because it is empty."); + } + if (cookieStatusAPI == null) { + return false; + } + HttpURLConnection connection; + try { + connection = (HttpURLConnection) cookieStatusAPI.openConnection(); + connection.setReadTimeout(15 * 60 * 1000); // timeout 15 minutes + connection.setConnectTimeout(15 * 60 * 1000); // timeout 15 minutes + connection.setRequestProperty("User-Agent", "Osmosis/" + OsmosisConstants.VERSION); + connection.setRequestProperty("Cookie", data); + // A HTTP HEAD request is sufficient, we don't have to parse the JSON. + connection.setRequestMethod("HEAD"); + connection.connect(); + return connection.getResponseCode() == HttpURLConnection.HTTP_OK; + } catch (IOException e) { + throw new OsmosisRuntimeException("Failed to check if the cookie is still valid."); + } + } } diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ServerStateReader.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ServerStateReader.java index 0b151cf27..7c24da264 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ServerStateReader.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/common/ServerStateReader.java @@ -91,7 +91,8 @@ public ReplicationState getServerState(URL baseUrl, long sequenceNumber) { * @return The state. */ public ReplicationState getServerState(URL baseUrl, long sequenceNumber, ReplicationCookie cookie) { - return getServerState(baseUrl, sequenceFormatter.getFormattedName(sequenceNumber, SEQUENCE_STATE_FILE_SUFFIX), cookie); + return getServerState(baseUrl, sequenceFormatter.getFormattedName(sequenceNumber, SEQUENCE_STATE_FILE_SUFFIX), + cookie); } diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/BaseReplicationDownloader.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/BaseReplicationDownloader.java index 0ba9317d6..9f05699d0 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/BaseReplicationDownloader.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/BaseReplicationDownloader.java @@ -46,7 +46,12 @@ public abstract class BaseReplicationDownloader implements RunnableTask { private File workingDirectory; private ReplicationSequenceFormatter sequenceFormatter; private ServerStateReader serverStateReader; + + /** + * configuration of the downloader + */ protected ReplicationDownloaderConfiguration configuration; + private ReplicationCookie cookie; @@ -63,7 +68,7 @@ public BaseReplicationDownloader(File workingDirectory) { serverStateReader = new ServerStateReader(); configuration = new ReplicationDownloaderConfiguration(new File(workingDirectory, CONFIG_FILE)); - cookie = new ReplicationCookie(workingDirectory.toPath()); + cookie = new ReplicationCookie(workingDirectory.toPath(), configuration.getCookieStatusAPI()); if (configuration.getAttachCookie()) { cookie.read(); } diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationFileMerger.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationFileMerger.java index cc95a299b..f882c9a70 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationFileMerger.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationFileMerger.java @@ -13,7 +13,6 @@ import org.openstreetmap.osmosis.replication.common.FileReplicationStore; import org.openstreetmap.osmosis.replication.common.ReplicationState; import org.openstreetmap.osmosis.replication.common.ReplicationStore; -import org.openstreetmap.osmosis.replication.v0_6.impl.ReplicationDownloaderConfiguration; import org.openstreetmap.osmosis.replication.v0_6.impl.ReplicationFileMergerConfiguration; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeReader; import org.openstreetmap.osmosis.xml.v0_6.XmlChangeWriter; diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationLagReader.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationLagReader.java index 53fcc1126..3d42090f5 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationLagReader.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/ReplicationLagReader.java @@ -62,9 +62,13 @@ private void getLag() { configuration = new ReplicationDownloaderConfiguration(new File(workingDirectory, CONFIG_FILE)); // read cookie if necessary - ReplicationCookie cookie = new ReplicationCookie(workingDirectory.toPath()); + ReplicationCookie cookie = new ReplicationCookie(workingDirectory.toPath(), + configuration.getCookieStatusAPI()); if (configuration.getAttachCookie()) { cookie.read(); + // Throw an exception if the cookie is expired. Fail with a understandable error now because further + // requests will fail. + cookie.throw_if_expired(); } // Obtain the server state. diff --git a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl/ReplicationDownloaderConfiguration.java b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl/ReplicationDownloaderConfiguration.java index 6f6f08923..60f33b98e 100644 --- a/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl/ReplicationDownloaderConfiguration.java +++ b/osmosis-replication/src/main/java/org/openstreetmap/osmosis/replication/v0_6/impl/ReplicationDownloaderConfiguration.java @@ -19,8 +19,9 @@ public class ReplicationDownloaderConfiguration { private static final String KEY_BASE_URL = "baseUrl"; private static final String KEY_MAX_INTERVAL = "maxInterval"; private static final String ATTACH_COOKIE = "attachCookie"; - - + private static final String COOKIE_STATUS_API = "cookieStatusAPI"; + + private Properties properties; @@ -75,4 +76,21 @@ public int getMaxInterval() { public boolean getAttachCookie() { return Boolean.parseBoolean(properties.getProperty(ATTACH_COOKIE)); } + + /** + * Returns the API endpoint to use to check if the cookie is expired. + * + * @return The URL or null if not set. + */ + public URL getCookieStatusAPI() { + String url = properties.getProperty(COOKIE_STATUS_API, null); + if (url == null) { + return null; + } + try { + return new URL(url); + } catch (MalformedURLException e) { + throw new OsmosisRuntimeException("Cookie status API URL is malformed."); + } + } }