// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.common; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.OsmosisConstants; /** * Retrieves replication state files from the server hosting replication data. */ public class ServerStateReader { private static final String SERVER_STATE_FILE = "state.txt"; private static final String SEQUENCE_STATE_FILE_SUFFIX = ".state.txt"; private ReplicationSequenceFormatter sequenceFormatter; /** * Creates a new instance. */ public ServerStateReader() { sequenceFormatter = new ReplicationSequenceFormatter(9, 3); } /** * Retrieves the latest state from the server. * * @param baseUrl * The url of the directory containing change files. * @return The state. */ public ReplicationState getServerState(URL baseUrl) { return getServerState(baseUrl, SERVER_STATE_FILE); } /** * 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. * @return The state. */ public ReplicationState getServerState(URL baseUrl, long sequenceNumber) { return getServerState(baseUrl, sequenceFormatter.getFormattedName(sequenceNumber, SEQUENCE_STATE_FILE_SUFFIX)); } /** * Retrieves the specified state from the server. * * @param baseUrl * The url of the directory containing change files. * @param stateFile * The state file to be retrieved. * @return The state. */ private ReplicationState getServerState(URL baseUrl, String stateFile) { URL stateUrl; try { stateUrl = new URL(baseUrl, stateFile); } catch (MalformedURLException e) { throw new OsmosisRuntimeException("The server timestamp URL could not be created.", e); } try { Properties stateProperties; Map<String, String> stateMap; ReplicationState state; URLConnection connection = stateUrl.openConnection(); connection.setReadTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setConnectTimeout(15 * 60 * 1000); // timeout 15 minutes connection.setRequestProperty("User-Agent", "Osmosis/" + OsmosisConstants.VERSION); try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { stateProperties = new Properties(); stateProperties.load(reader); } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read the state from the server.", e); } stateMap = new HashMap<String, String>(); for (Entry<Object, Object> property : stateProperties.entrySet()) { stateMap.put((String) property.getKey(), (String) property.getValue()); } state = new ReplicationState(stateMap); return state; } catch (IOException e) { throw new OsmosisRuntimeException("Unable to read the state from the server.", e); } } }