Java tutorial
/* Copyright (c) 2015 University of Massachusetts * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * Initial developer(s): V. Arun */ package edu.umass.cs.gigapaxos; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import org.junit.Assert; import org.json.JSONArray; import org.json.JSONException; import edu.umass.cs.gigapaxos.examples.noop.NoopPaxosApp; import edu.umass.cs.gigapaxos.paxosutil.E2ELatencyAwareRedirector; import edu.umass.cs.nio.NIOTransport; import edu.umass.cs.nio.SSLDataProcessingWorker; import edu.umass.cs.nio.SSLDataProcessingWorker.SSL_MODES; import edu.umass.cs.nio.interfaces.NodeConfig; import edu.umass.cs.reconfiguration.interfaces.ReconfigurableNodeConfig; import edu.umass.cs.reconfiguration.interfaces.ReplicableRequest; import edu.umass.cs.utils.Config; import edu.umass.cs.utils.DiskMap; import edu.umass.cs.utils.MultiArrayMap; import edu.umass.cs.utils.Util; /** * @author arun * * A container class for storing gigapaxos config parameters as an enum. */ public class PaxosConfig { /** * Default file name for gigapaxos config parameters. */ public static final String DEFAULT_GIGAPAXOS_CONFIG_FILE = "gigapaxos.properties"; /** * Gigapaxos config file information can be specified using * -DgigapaxosConfig=<filename> as a JVM argument. */ public static final String GIGAPAXOS_CONFIG_FILE_KEY = "gigapaxosConfig"; /** * */ public static final String DEFAULT_SERVER_PREFIX = "active."; static { load(); } /** * Loads from a default file or file name specified as a system property. We * take a type argument so that ReconfigurationConfig.RC can also mooch off * the same properties file. * * @param type */ public static void load(Class<?> type) { try { Config.register(type, GIGAPAXOS_CONFIG_FILE_KEY, DEFAULT_GIGAPAXOS_CONFIG_FILE).setSystemProperties(); } catch (IOException e) { // ignore as default will still be used } } /** * By default, PaxosConfig.PC will be registered. */ public static void load() { load(PC.class); } /** * @return Properties in gigapaxos properties file. */ public static Properties getAsProperties() { Properties config = null; try { // need to preserve case here config = Config.getProperties(PC.class, GIGAPAXOS_CONFIG_FILE_KEY, DEFAULT_GIGAPAXOS_CONFIG_FILE); } catch (IOException e) { e.printStackTrace(); } if (config == null) config = Config.getConfig(PC.class); return config; } /** * @return True if all parameters are sane. */ public static boolean sanityCheck() { Assert.assertTrue(PC.GIGAPAXOS_DATA_DIR + " must be an absolute path", Config.getGlobalString(PC.GIGAPAXOS_DATA_DIR).startsWith("/") // only for backwards compatibility || Config.getGlobalString(PC.GIGAPAXOS_DATA_DIR).trim().equals(".")); if (Config.getGlobalString(PC.GIGAPAXOS_DATA_DIR).trim().equals(".")) PaxosManager.getLogger().warning(PC.GIGAPAXOS_DATA_DIR + " must be an absolute path;" + " specifying \".\" is deprecated and discouraged."); return true; } /** * @return A map of names and socket addresses corresponding to servers * hosting paxos replicas. */ public static Map<String, InetSocketAddress> getActives() { Map<String, InetSocketAddress> map = new HashMap<String, InetSocketAddress>(); Properties config = getAsProperties(); Set<String> keys = config.stringPropertyNames(); for (String key : keys) { if (key.trim().startsWith(DEFAULT_SERVER_PREFIX)) { map.put(key.replaceFirst(DEFAULT_SERVER_PREFIX, ""), Util.getInetSocketAddressFromString(config.getProperty(key))); } } return map; } private static Class<?> getClassSuppressExceptions(String className) { Class<?> clazz = null; try { if (className != null && !"null".equals(className)) { clazz = Class.forName(className); } } catch (ClassNotFoundException e) { e.printStackTrace(); } return clazz; } /** * Paxos controlled application. */ public static final Class<?> application = getClassSuppressExceptions(Config.getGlobalString(PC.APPLICATION)); /** * All gigapaxos config parameters that can be specified via a configuration * file. */ public static enum PC implements Config.ConfigurableEnum, Config.Disableable { /** * Default application managed by gigapaxos. */ APPLICATION(NoopPaxosApp.class.getName()), /** * Default offset for the client facing port. */ CLIENT_PORT_OFFSET(100), /** * Default offset for the client facing ssl port. */ CLIENT_PORT_SSL_OFFSET(200), /** * Verbose debugging and request instrumentation */ DEBUG(false), /** * True means no persistent logging */ DISABLE_LOGGING(false), /** * FIXME: Journaling based log for efficiency. Needs periodic compaction * that is not yet implemented, so this log exists only for performance * instrumentation. */ ENABLE_JOURNALING(true), /** * True means no checkpointing. If logging is enabled (as is the * default), the logs will grow unbounded. So either both should be true * or both should be false. */ DISABLE_CHECKPOINTING(false), /** * */ ENABLE_COMPRESSION(true), /** * */ COMPRESSION_THRESHOLD(4 * 1024 * 1024), /** * The default size of the {@link MultiArrayMap} used to store paxos * instances. */ PINSTANCES_CAPACITY(2000000), // 2M /** * The waiting period for paxos instance corpses in order to prevent * inadvertant rebirths because of the missed birthing paxos instance * creation mechanism. */ MORGUE_DELAY(30000), /** * Whether the hibernate option is enabled. */ HIBERNATE_OPTION(false), /** * Whether the pause option is enabled. */ PAUSE_OPTION(true), /** * Fraction of capacity to be reached in order for pausing to get * enabled. */ PAUSE_SIZE_THRESHOLD(0), /** * The time after which the deactivation thread will attempt to pause * idle paxos instances by making a pass over all currently unpaused * instances. This is also the period for which a paxos instance must be * idle in order to be paused. */ DEACTIVATION_PERIOD(60000), // 30s default /** * Limits the rate of pausing to not interfere with request processing. * But it has the downside of increasing the total pause time as well as * limiting the paxos instance creation rate. For example, pausing a * million instances will take 1000s with the default rate limit of * 1000/s. */ PAUSE_RATE_LIMIT(1000), // /s /** * Refer to documentation in {@link SQLPaxosLogger}. */ MAX_FINAL_STATE_AGE(3600 * 1000), /** * Whether request batching is enabled. */ BATCHING_ENABLED(true), /** * */ MAX_LOG_FILE_SIZE(64 * 1024 * 1024), /** * Wait period for forcibly killing a lower paxos instance version in * order to start a higher version. * <p> * FIXME: Unclear what a good default is for good liveness. It doesn't * really matter for safety of reconfiguration. */ CAN_CREATE_TIMEOUT(5000), /** * Wait period before going forth with a missed birthing paxos instance * creation to see if the instance gets normally created anyway. */ WAIT_TO_GET_CREATED_TIMEOUT(2000), /** * The maximum log message size. The higher the batching, the higher * this value needs to be. */ MAX_LOG_MESSAGE_SIZE(1024 * 1024 * 5), /** * The maximum checkpoint size. The default below is the maximum size of * varchar in embedded derby, which is probably somewhat faster than * clobs, which would be automatically used with bigger checkpoint * sizes. */ MAX_CHECKPOINT_SIZE(32672), /** * Number of checkpoints after which log messages will be garbage * collected for a paxos group. We really don't need to do garbage * collection at all until the size of the table starts affecting log * message retrieval time or the size of the table starts causing the * indexing overhead to become high at insertion time; the latter is * unlikely as we maintain an index on the paxosID key. */ LOG_GC_FREQUENCY(10), /** * Number of log files after which GC will be attempted. */ JOURNAL_GC_FREQUENCY(5), /** * Number of log files after which compaction will be attempted. */ COMPACTION_FREQUENCY(2), /** * The number of log messages after which they are indexed into the DB. * Indexing every log message doubles the logging overhead and doesn't * have to be done (unless #SYNC_INDEX_JOURNAL is enabled). Upon * recovery however, we need to do slightly more work to ensure that all * uncommitted log messages are indexed into the DB. */ LOG_INDEX_FREQUENCY(100), /** * Whether fields in the log messages table in the DB should be indexed. * This index refers to the DB's internal index as opposed to * {@link #DB_INDEX_JOURNAL} that is an explicit index of log messages * journaled on the file system. */ INDEX_LOG_TABLE(true), /** * A tiny amount of minimum sleep imposed on every request in order to * improve batching benefits. Also refer to {@link #BATCH_OVERHEAD}. */ BATCH_SLEEP_DURATION(0), /** * Inverse of the percentage overhead of agreement latency added to the * sleep duration used for increasing batching gains. Also refer to * {@value #BATCH_SLEEP_DURATION}. */ BATCH_OVERHEAD(0.01), /** * */ DISABLE_SYNC_DECISIONS(false), /** * Maximum number of batched requests. Setting it to infinity means that * the log message size will still limit it. */ MAX_BATCH_SIZE(2000), /** * Checkpoint interval. A larger value means slower recovery, slower * coordinator changes, and less frequent garbage collection, but it * also means less frequent IO or higher request throughput. */ CHECKPOINT_INTERVAL(400), /** * Number of threads in packet demultiplexer. More than 0 means that we * may not preserve the order of client requests while processing them. */ PACKET_DEMULTIPLEXER_THREADS(4), /** * Whether request order is preserved for requests sent by the same * replica and committed by the same coordinator. */ ORDER_PRESERVING_REQUESTS(true), /** * The replica receiving the request will simply send the request to the * local application replica, i.e., this essentially disables all paxos * coordination. This is used only for testing. */ EMULATE_UNREPLICATED(false), /** * If true, the servers will send no response. For testing only. */ NO_RESPONSE(false), /** * Only for performance instrumentation. If true, replicas will simply * execute the request upon receiving an ACCEPT. This option will break * RSM safety. */ EXECUTE_UPON_ACCEPT(false), /** * Also used for testing. Lazily propagates requests to other replicas * when emulating unreplicated execution mode. */ LAZY_PROPAGATION(false), /** * Enables coalescing of accept replies. */ BATCHED_ACCEPT_REPLIES(true), /** * Enables coalescing of commits. For coalesced commits, a replica must * have the corresponding accept logged, otherwise it will end up * sync'ing and increasing overhead. Enabling this option but not * persistent logging can cause liveness problems. */ BATCHED_COMMITS(true), /** * Whether to store compressed logs in the DB. */ DB_COMPRESSION(true), /** * Instrumentation at various places. Should be enabled only during * testing and disabled during production use. */ ENABLE_INSTRUMENTATION(false), /** * */ ENABLE_STATIC_CHECKS(false), /** * Whether DelayProfiler should be enabled. */ DELAY_PROFILER(true), /** * */ JSON_LIBRARY("json.smart"), /** * The top-level directory inside which all gigapaxos-related data is * stored. Paxos logs and checkpoints are stored in the sub-directory * PAXOS_LOGS_DIR. Reconfiguration logs are stored in the sub-directory * RECONFIGURATION_DB_DIR. */ GIGAPAXOS_DATA_DIR("."), /** * Location for paxos logs when an embedded DB is used. This can not be * changed. */ PAXOS_LOGS_DIR("paxos_logs"), /** * Prefix of the paxos DB's name. The whole name is obtained by * concatenating this prefix with the node ID. * * In the embedded DB case, paxos logs for "nodeID" are stored at * GIGAPAXOS_DATA_DIR/PAXOS_LOGS_DIR/PAXOS_DB_PREFIX"nodeID". */ PAXOS_DB_PREFIX("paxos_db"), /** * Maximum length in characters of a paxos group name. */ MAX_PAXOS_ID_SIZE(40), /** * {@link edu.umass.cs.gigapaxos.paxosutil.SQL.SQLType} type. Currently, * the only other alternative is "MYSQL". Refer the above class to * specify the user name and password. */ SQL_TYPE("EMBEDDED_DERBY"), /** * Maximum size of a paxos replica group. */ MAX_GROUP_SIZE(16), /** * Threshold for throttling client request load. */ MAX_OUTSTANDING_REQUESTS(8000), /** * Sleep millis to throttle client requests if overloaded. Used only for * testing. */ THROTTLE_SLEEP(0), /** * Client-server SSL mode. */ CLIENT_SSL_MODE(SSLDataProcessingWorker.SSL_MODES.CLEAR), /** * Server-server SSL mode. */ SERVER_SSL_MODE(SSLDataProcessingWorker.SSL_MODES.CLEAR), /** * Number of additional sending connections used by paxos. We need this * because the sending throughput of a single TCP connection is limited * and can become a bottleneck at the coordinator. */ NUM_MESSENGER_WORKERS(1), /** * */ USE_NIO_SENDER_TASK(false), /** * Disable congestion pushback. */ DISABLE_CC(false), /** * If true, we use a garbage collected map that has higher overhead than * a regular map, but is still not a bottleneck. */ USE_GC_MAP(true), /** * Only log meta decisions if corresponding accept was previously * received. */ LOG_META_DECISIONS(true), /** * Whether select packets should be byteified as opposed to * json-stringified. */ BYTEIFICATION(true), /** * */ INSTRUMENT_SERIALIZATION(false), /** * */ STRICT_ADDRESS_CHECKS(false), /** * */ CLIENT_DEMULTIPLEXER_THREADS(0), /** * Disables the feature that redirects requests to the most recent * replica from which a response to a coordinated request, i.e., a * {@link ReplicableRequest} with * {@link ReplicableRequest#needsCoordination()} {@code true}, was * received. Note that enabling this feature means that latency-based * request redirection at the client will not happen, so the client may * be sending requests to far away active replicas even though nearer * ones exist. This is because latency-based redirection works by * probing, i.e., a small fraction, * {@link E2ELatencyAwareRedirector#PROBE_RATIO} of requests are sent to * a random active replica, in order to enable nearest-server * redirection. */ READ_YOUR_WRITES(false), /** * If true, gigapaxos will try to prevent executing (retransmitted) * requests if they had already been executed in the <i>recent</i> past. * In such cases, the response from the first execution will be returned * to the app. This method can not be relied upon for safety as * gigapaxos will cache executed requests for a limited time and is * space-contrained. */ PREVENT_DOUBLE_EXECUTION(true), /** * Whether journal entries should be synchronously indexed in the DB. * Makes journaling (and overall throughput) slower but makes safe * retrieval of logged messages easier both during normal operations and * upon recovery. During normal operations, we just have to check the DB * and also check the pending log in memory to ensure that we don't miss * any log messages. Upon recovery however, there is no pending log in * memory and the system may have crashed with some pending log messages * before they could be inserted into the DB, so we just have to find * the last message logged in the DB and put the rest in a pending queue * for logging into the DB. */ PAUSABLE_INDEX_JOURNAL(true), /** * Whether more than one thread is used to log messages. */ MULTITHREAD_LOGGER(false), /** * True means that the journal entries will be indexed in the DB. False (default) * means we maintain an in-memory index while infrequently pausing unused entries * to disk (using {@link DiskMap} while reconstructing unsaved entries upon * recovery using the written-ahead journal log files. */ DB_INDEX_JOURNAL(false), /** * Failure detection timeout in seconds after which a node will be * considered dead if no keepalives have been received from it. Used to * detect coordinator failures. */ FAILURE_DETECTION_TIMEOUT(6), /** * Request timeout in seconds after which the request will be deleted * from the outstanding queue. Currently, there is no effort to remove * any other state for that request from the system. */ REQUEST_TIMEOUT(10), /** * Whether the mapdb package should be used. It seems too slow for our * purposes, so we use our own custom write-ahead logger. */ USE_MAP_DB(false, true), /** * If true, the checkpoints table will be used to also store paused * state as opposed to storing paused state in its own table. The reason * to store paused state in the same table as checkpoints is that we can * easily compute FIXME: */ USE_CHECKPOINTS_AS_PAUSE_TABLE(true), /** * */ USE_DISK_MAP(true), /** * */ USE_HEX_TIMESTAMP(true), /** * */ LAZY_COMPACTION(true), /** * */ PAUSE_BATCH_SIZE(1000), /** * */ SYNC(false), /** * */ FLUSH(true), /** * */ SYNC_FCLOSE(true), /** * */ FLUSH_FCLOSE(true), /** * Minimum seconds after last modification when a compaction attempt can * be made. */ LOGFILE_AGE_THRESHOLD(10 * 60), /** * Percentage variation around mean in checkpoint interval. */ CPI_NOISE(0), /** * Whether checkpoints should be batched. We rely on the fact that * synchronous checkpointing is not necessary for safety except for the * initial state and the state after the stop request. We just need to * ensure that the state for the checkpoint is synchronously obtained * from the application immediately after the corresponding request * execution. */ BATCH_CHECKPOINTS(true), /** * */ MAX_DB_BATCH_SIZE(10000), /** * Number of milliseconds after which * {@link edu.umass.cs.gigapaxos.interfaces.Replicable#execute(edu.umass.cs.gigapaxos.interfaces.Request)} * will be re-attempted until it returns true. */ HANDLE_REQUEST_RETRY_INTERVAL(100), /** * Maximum number of retry attempts for * {@link edu.umass.cs.gigapaxos.interfaces.Replicable#execute(edu.umass.cs.gigapaxos.interfaces.Request)} * . After these many unsuccessful attempts, the paxos instance will be * killed. */ HANDLE_REQUEST_RETRY_LIMIT(10), /** * Broadcast requests at entry replica and use digests in accepts. This * makes a noticeable difference only when the number of groups is small * (like 1 or 2). For more groups, the reordering effects seem to hurt * more than help. * * Disabled by default. */ DIGEST_REQUESTS(true), /** * Number of active groups up to which digesting is done. Digests seem * to hurt with many groups probably because the cost more than offsets * the benefit. With many groups, the coordinator load balancing benefit * of digests is negligible. The main benefit is that they save one * transmission of the request body, but they increase the total number * of messages by one and lose out on stringification optimizations at * acceptors. Furthermore, a digested accept is useless unless the * corresponding request body arrives, which seems to slow down the * overall throughput of the system. */ DIGEST_THRESHOLD(5), /** * Whether paxos packets across different paxos groups should be batched * if they are going to the same set of destinations. */ BATCH_ACROSS_GROUPS(true), /** * Whether accept batching should be different from * {@link #BATCH_ACROSS_GROUPS}. True means that we won't batch accepts * even if {@link #BATCH_ACROSS_GROUPS} is true. Accept batching doesn't * really help unless {@link #DIGEST_REQUESTS} is enabled and that is by * default enabled only if the number of active instances is small. */ FLIP_BATCHED_ACCEPTS(false), /** * Whether {@link edu.umass.cs.gigapaxos.paxospackets.RequestPacket} and * inherited classes should be batched. This batching is different from * the batching in {@link #BATCHING_ENABLED}. It refers to batching of * entire packets to marginally reduce network overhead. It really makes * little difference either way. With the new byteification methods and * batching opportunities (as in {@link #BATCHING_ENABLED}), this option * actually has a small net cost, so it should be disabled by default. * It may give small benefits with a large number of groups and little * room for batching within each group. */ BATCHED_REQUESTS(true), /** * Local messages are not put in {@link PaxosPacketBatcher}. */ SHORT_CIRCUIT_LOCAL(true), /** * */ NUM_MESSAGE_DIGESTS(5), /** * */ DEBUG_MONITOR(0), /** * */ ACCEPT_TIMEOUT(Integer.MAX_VALUE), /** * */ POKE_COORDINATOR(true), /** * Minimum number of packets in order to consider * {@link edu.umass.cs.gigapaxos.paxospackets.PaxosPacket} batching. */ MIN_PP_BATCH_SIZE(3), /** * */ LOG_DISKMAP_CAPACITY(Config.getGlobalInt(PINSTANCES_CAPACITY)), /** * */ DIGEST_THRESHOLD_SIZE(512), /** * */ BLOCKING_CHECKPOINT(false), /** * True means we garbage collect accepts up to the slot that a majority * have executed; otherwise up to the slot that a majority have * checkpointed. */ GC_MAJORITY_EXECUTED(true), /** * */ DB_USER("user"), /** * */ DB_PASSWORD("password"), /** * Turns on delay emulation. */ EMULATE_DELAYS(false), /** * FIXME: The options below only exist for testing stringification * overhead. They should probably be moved to {@link TESTPaxosConfig}. * Most of these will compromise safety. */ /***************** Start of unsafe testing options *******************/ /** * Testing option. */ JOURNAL_COMPRESSION(false, true), /** * Testing option. */ STRINGIFY_WO_JOURNALING(false, true), /** * Testing option. */ NON_COORD_ONLY(false, true), /** * Testing option. */ NO_STRINGIFY_JOURNALING(false, true), /** * Testing option. */ COORD_STRINGIFIES_WO_JOURNALING(false, true), /** * Testing option. */ DONT_LOG_DECISIONS(false, true), /** * Testing option. */ NON_COORD_DONT_LOG_DECISIONS(false, true), /** * Testing option. */ COORD_DONT_LOG_DECISIONS(false, true), /** * Testing option. */ COORD_JOURNALS_WO_STRINGIFYING(false, true), /** * Testing option */ ALL_BUT_APPEND(false, true), /** * Testing option. Implies no coordinator fault-tolerance. */ DISABLE_GET_LOGGED_MESSAGES(false, true), /** * If true, identical requests, i.e., requests with the same requestID, * paxosID, and sending client's socket address, will get a recently * cached response if any instead of re-coordinating the request. This * is useful to reduce the likelihood of double-execution, but does not * eliminate it completely. */ ENABLE_RESPONSE_CACHING(true), /*********** End of unsafe testing options *****************/ ; final Object defaultValue; final boolean unsafeTestingOnly; PC(Object defaultValue) { this(defaultValue, false); } PC(Object defaultValue, boolean testingOnly) { this.defaultValue = defaultValue; this.unsafeTestingOnly = testingOnly; } @Override public Object getDefaultValue() { return this.defaultValue; } @Override public String getDefaultConfigFile() { return DEFAULT_GIGAPAXOS_CONFIG_FILE; } @Override public String getConfigFileKey() { return GIGAPAXOS_CONFIG_FILE_KEY; } @Override public boolean isDisabled() { return UNSAFE_TESTING ? false : this.unsafeTestingOnly; } } private static boolean UNSAFE_TESTING = false; /** * @return Default client port offset based on whether ssl is enabled. */ public static int getClientPortOffset() { if (SSL_MODES.valueOf(Config.getGlobalString(PC.CLIENT_SSL_MODE)) == SSL_MODES.CLEAR) return Config.getGlobalInt(PC.CLIENT_PORT_OFFSET); else return Config.getGlobalInt(PC.CLIENT_PORT_SSL_OFFSET); } /** * @param servers * @param globalInt * @return Socket addresses with the port offset added to each element. */ public static Set<InetSocketAddress> offsetSocketAddresses(Set<InetSocketAddress> servers, int globalInt) { Set<InetSocketAddress> offsetted = new HashSet<InetSocketAddress>(); for (InetSocketAddress isa : servers) { offsetted.add(new InetSocketAddress(isa.getAddress(), isa.getPort() + globalInt)); } return offsetted; } /** * @param level */ public static void setConsoleHandler(Level level) { ConsoleHandler handler = new ConsoleHandler(); handler.setLevel(level); PaxosManager.getLogger().setLevel(level); PaxosManager.getLogger().addHandler(handler); PaxosManager.getLogger().setUseParentHandlers(false); NIOTransport.getLogger().setLevel(level); NIOTransport.getLogger().addHandler(handler); NIOTransport.getLogger().setUseParentHandlers(false); } protected static void setConsoleHandler() { if (System.getProperty("java.util.logging.config.file") == null) setConsoleHandler(Level.INFO); } @SuppressWarnings({ "javadoc", "unchecked", "rawtypes" }) public static void sanityCheck(NodeConfig nodeConfig) throws IOException { for (Object n : nodeConfig.getNodeIDs()) { for (Object m : nodeConfig.getNodeIDs()) if (!n.equals(m) && nodeConfig.getNodeAddress(n).equals(nodeConfig.getNodeAddress(m)) && (nodeConfig.getNodePort(n) == nodeConfig.getNodePort(m) || nodeConfig.getNodePort(n) + Config.getGlobalInt(PC.CLIENT_PORT_OFFSET) == nodeConfig.getNodePort(m) || nodeConfig.getNodePort(n) + Config.getGlobalInt(PC.CLIENT_PORT_SSL_OFFSET) == nodeConfig .getNodePort(m) )) throw new IOException("Clash in nodeConfig between " + n + " and " + m + ": node socket addresses should not be identical or " + "be exactly " + "CLIENT_PORT_OFFSET=" + Config.getGlobalInt(PC.CLIENT_PORT_OFFSET) + " or " + "CLIENT_PORT_SSL_OFFSET=" + Config.getGlobalInt(PC.CLIENT_PORT_SSL_OFFSET) + " apart."); } } /** * @return Default node config. */ public static NodeConfig<String> getDefaultNodeConfig() { final Map<String, InetSocketAddress> actives = PaxosConfig.getActives(); // FIXME: don't use reconfiguration classes in gigapaxos return new ReconfigurableNodeConfig<String>() { @Override public boolean nodeExists(String id) { return actives.containsKey(id); } @Override public InetAddress getNodeAddress(String id) { return actives.containsKey(id) ? actives.get(id).getAddress() : null; } /** * Bind address is returned as the same as the regular address coz * we don't really need a bind address after all. * * @param id * @return Bind address. */ @Override public InetAddress getBindAddress(String id) { return actives.containsKey(id) ? actives.get(id).getAddress() : null; } @Override public int getNodePort(String id) { return actives.containsKey(id) ? actives.get(id).getPort() : null; } @Override public Set<String> getNodeIDs() { return new HashSet<String>(actives.keySet()); } @Override public String valueOf(String strValue) { return this.nodeExists(strValue) ? strValue : null; } @Override public Set<String> getValuesFromStringSet(Set<String> strNodes) { throw new RuntimeException("Method not yet implemented"); } @Override public Set<String> getValuesFromJSONArray(JSONArray array) throws JSONException { throw new RuntimeException("Method not yet implemented"); } @Override public Set<String> getActiveReplicas() { return new HashSet<String>(actives.keySet()); } @Override public Set<String> getReconfigurators() { return new HashSet<String>(actives.keySet()); } }; } private static boolean noPropertiesFile = false; /** * Used mainly for testing. */ public static void setNoPropertiesFile() { noPropertiesFile = true; } /** * @return Name of gigapaxos properties file. */ public static String getPropertiesFile() { //assert(System.getProperty(PaxosConfig.GIGAPAXOS_CONFIG_FILE_KEY) ==null); return System.getProperty(PaxosConfig.GIGAPAXOS_CONFIG_FILE_KEY) != null ? System.getProperty(PaxosConfig.GIGAPAXOS_CONFIG_FILE_KEY) : !noPropertiesFile ? PaxosConfig.DEFAULT_GIGAPAXOS_CONFIG_FILE : null; } }