1 /**
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002, 2014 Oracle and/or its affiliates.  All rights reserved.
5  *
6  */
7 
8 package com.sleepycat.je.rep;
9 
10 import java.net.InetSocketAddress;
11 import java.util.Properties;
12 import java.util.Set;
13 import java.util.concurrent.TimeUnit;
14 
15 import com.sleepycat.je.EnvironmentConfig;
16 import com.sleepycat.je.ProgressListener;
17 import com.sleepycat.je.ReplicaConsistencyPolicy;
18 import com.sleepycat.je.config.EnvironmentParams;
19 import com.sleepycat.je.dbi.DbConfigManager;
20 import com.sleepycat.je.dbi.RepConfigProxy;
21 import com.sleepycat.je.rep.impl.RepParams;
22 import com.sleepycat.je.rep.utilint.HostPortPair;
23 import com.sleepycat.je.rep.utilint.RepUtils;
24 
25 /**
26  * Specifies the immutable attributes of a replicated environment.
27  * <p>
28  * To change the default settings for a replicated environment, an application
29  * creates a configuration object, customizes settings and uses it for {@link
30  * ReplicatedEnvironment} construction. The set methods of this class validate
31  * the configuration values when the method is invoked.  An
32  * IllegalArgumentException is thrown if the value is not valid for that
33  * attribute.
34  * <p>
35  * Note that ReplicationConfig only describes those attributes which must be
36  * set at {@code ReplicatedEnvironment} construction time, while its superclass
37  * {@link ReplicationMutableConfig} describes attributes that may be modified
38  * during the life of the replication group.
39  * <p>
40  * ReplicationConfig follows precedence rules similar to those of
41  * {@link EnvironmentConfig}.
42  * <ol>
43  * <li>Configuration parameters specified
44  * in {@literal <environmentHome>/je.properties} take first precedence.</li>
45  * <li>Configuration parameters set in the ReplicationConfig object used
46  * at {@code ReplicatedEnvironment} construction are next.</li>
47  * <li>Any configuration parameters not set by the application are set to
48  * system defaults, described along with the parameter name String constants
49  * in this class.</li>
50  *</ol>
51  * <p>
52  * After a {@code ReplicatedEnvironment} has been constructed, its mutable
53  * properties may be changed using {@code
54  * ReplicatedEnvironment#setMutableConfig}.  See {@code
55  * ReplicationMutableConfig} for a list of mutable properties; all other
56  * properties are immutable.  Whether a property is mutable or immutable is
57  * also described along with the parameter name String constants in this class.
58  *
59  * <h4>Getting the Current ReplicatedEnvironment Properties</h4>
60  *
61  * To get the current "live" properties of a replicated environment after
62  * constructing it or changing its properties, you must call {@link
63  * ReplicatedEnvironment#getRepConfig} or {@link
64  * ReplicatedEnvironment#getRepMutableConfig}.  The original ReplicationConfig
65  * or ReplicationMutableConfig object used to set the properties is not kept up
66  * to date as properties are changed, and does not reflect property validation
67  * or properties that are computed.
68  */
69 public class ReplicationConfig extends ReplicationMutableConfig
70     implements RepConfigProxy {
71 
72     private static final long serialVersionUID = 1L;
73 
74     /*
75      * Note: all replicated parameters should start with
76      * EnvironmentParams.REP_PARAMS_PREFIX, which is "je.rep.",
77      * see SR [#19080].
78      */
79 
80     /**
81      * The name for the replication group.
82      * The name should consist of letters, digits, and/or hyphen ("-"),
83      * underscore ("_"), or period (".").
84      *
85      * <p><table border="1">
86      * <tr><td>Name</td><td>Type</td><td>Mutable</td><td>Default</td></tr>
87      * <tr>
88      * <td>{@value}</td>
89      * <td>String</td>
90      * <td>No</td>
91      * <td>"DefaultGroup"</td>
92      * </tr>
93      * </table></p>
94      * @see ReplicationConfig#setGroupName
95      * @see ReplicationConfig#getGroupName
96      */
97     public static final String GROUP_NAME =
98         EnvironmentParams.REP_PARAM_PREFIX + "groupName";
99 
100     /**
101      * The node name uniquely identifies this node within the replication
102      * group.
103      * The name should consist of letters, digits, and/or hyphen ("-"),
104      * underscore ("_"), or period (".").
105      *
106      * <p>Note that the node name is immutable. Normally the host name should
107      * not be used as the node name, unless you intend to reuse the host
108      * name when a machine fails and is replaced, or the node is upgraded to
109      * new hardware.</p>
110      *
111      * <p><table border="1">
112      * <tr><td>Name</td><td>Type</td><td>Mutable</td><td>Default</td></tr>
113      * <tr>
114      * <td>{@value}</td>
115      * <td>String</td>
116      * <td>No</td>
117      * <td>"DefaultRepNodeName"</td>
118      * </tr>
119      * </table></p>
120      * @see ReplicationConfig#setNodeName
121      * @see ReplicationConfig#getNodeName
122      */
123     public static final String NODE_NAME =
124         EnvironmentParams.REP_PARAM_PREFIX + "nodeName";
125 
126     /**
127      * The type of this node.
128      *
129      * <p><table border="1">
130      * <tr><td>Name</td><td>Type</td><td>Mutable</td><td>Default</td></tr>
131      * <tr>
132      * <td>{@value}</td>
133      * <td>{@link NodeType}</td>
134      * <td>No</td>
135      * <td>ELECTABLE</td>
136      * </tr>
137      * </table></p>
138      * @see ReplicationConfig#setNodeType
139      * @see ReplicationConfig#getNodeType
140      */
141     public static final String NODE_TYPE=
142         EnvironmentParams.REP_PARAM_PREFIX + "nodeType";
143 
144     /**
145      * The string identifying one or more helper host and port pairs in
146      * this format:
147      * <pre>
148      * hostname[:port][,hostname[:port]]*
149      * </pre>
150      * <p><table border="1">
151      * <tr><td>Name</td><td>Type</td><td>Mutable</td><td>Default</td></tr>
152      * <tr>
153      * <td>{@value}</td>
154      * <td>String</td>
155      * <td>No</td>
156      * <td>""</td>
157      * </tr>
158      * </table></p>
159      * @see ReplicationConfig#setHelperHosts
160      * @see ReplicationConfig#getHelperHosts
161      * @deprecated replaced by {@link ReplicationMutableConfig#HELPER_HOSTS}.
162      */
163     @Deprecated
164     public static final String HELPER_HOSTS =
165         EnvironmentParams.REP_PARAM_PREFIX + "helperHosts";
166 
167     /**
168      * The default port used for replication.
169      * <p><table border="1">
170      * <tr><td>Name</td><td>Type</td><td>Mutable</td>
171      * <td>Default</td><td>Minimum</td><td>Maximum</td></tr>
172      * <tr>
173      * <td>{@value}</td>
174      * <td>Integer</td>
175      * <td>No</td>
176      * <td>5001</td>
177      * <td>1024</td>
178      * <td>Short.MAX_VALUE</td>
179      * </tr>
180      * </table></p>
181      */
182     public static final String DEFAULT_PORT =
183         EnvironmentParams.REP_PARAM_PREFIX + "defaultPort";
184 
185     /**
186      * Names the hostname and port associated with this node in the
187      * replication group, e.g. je.rep.nodeHostPort=foo.com:5001.
188      * <p>
189      * The hostname is defaulted to "localhost" to make it easy to prototype
190      * and to execute the examples, but the user should be very sure to set a
191      * specific hostname before starting nodes on multiple machines. The value
192      * of je.rep.nodeHostPort is saved persistently in replication group
193      * metadata and is expected to be a unique address, and a value of
194      * "localhost" in the replication metadata will cause severe communication
195      * confusion.
196      * <p>
197      * The port portion of the host value is optional. If it's not specified,
198      * the value of "je.rep.defaultPort" is used.
199      * <p><table border="1">
200      * <tr><td>Name</td><td>Type</td><td>Mutable</td><td>Default</td></tr>
201      * <tr>
202      * <td>{@value}</td>
203      * <td>String</td>
204      * <td>No</td>
205      * <td>"localhost"</td>
206      * </tr>
207      * </table></p>
208      * @see ReplicationConfig#setNodeHostPort
209      * @see ReplicationConfig#getNodeHostPort
210      */
211     public static final String NODE_HOST_PORT =
212         EnvironmentParams.REP_PARAM_PREFIX + "nodeHostPort";
213 
214     /**
215      * When this configuration parameter is set to true, it binds the HA socket
216      * to INADDR_ANY, so that HA services are available on all network
217      * interfaces. The default value (false) results in the HA socket being
218      * bound to the specific interface specified by the {@link #NODE_HOST_PORT}
219      * configuration.
220      *
221      * <p>
222      * <table border="1">
223      * <tr>
224      * <td>Name</td>
225      * <td>Type</td>
226      * <td>Mutable</td>
227      * <td>Default</td>
228      * </tr>
229      * <tr>
230      * <td>{@value}</td>
231      * <td>Boolean</td>
232      * <td>No</td>
233      * <td>false</td>
234      * </tr>
235      * </table>
236      * </p>
237      */
238     public static final String BIND_INADDR_ANY =
239         EnvironmentParams.REP_PARAM_PREFIX + "bindInaddrAny";
240 
241     /**
242      * The default consistency policy used by a replica. Only two
243      * policies are meaningful as properties denoting environment level default
244      * policies: {@link NoConsistencyRequiredPolicy} and
245      * {@link TimeConsistencyPolicy}.  They
246      * can be specified as:
247      * <pre>  NoConsistencyRequiredPolicy</pre>
248      * or
249      * <pre>  {@code TimeConsistencyPolicy(<permissibleLag>,<timeout>)}</pre>
250      * where {@code <permissibleLag>} and {@code <timeout>} are {@link <a
251      * href="../EnvironmentConfig.html#timeDuration">Time Duration
252      * Properties</a>}.
253      * <p>
254      * For example, a time based consistency policy with a lag of one second
255      * and a timeout of one hour is denoted by the string:
256      * {@code TimeConsistencyPolicy(1 s,1 h)}
257      * <p><table border="1">
258      * <tr><td>Name</td><td>Type</td><td>Mutable</td><td>Default</td></tr>
259      * <tr>
260      * <td>{@value}</td>
261      * <td>String</td>
262      * <td>No</td>
263      * <td>"TimeConsistencyPolicy(1 s,1 h)"</td>
264      * </tr>
265      * </table></p>
266      *
267      * @see ReplicationConfig#setConsistencyPolicy
268      * @see ReplicationConfig#getConsistencyPolicy
269      * @see com.sleepycat.je.TransactionConfig#setConsistencyPolicy
270      * @see com.sleepycat.je.TransactionConfig#getConsistencyPolicy
271      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
272      * Properties</a>
273      */
274     public static final String CONSISTENCY_POLICY =
275         EnvironmentParams.REP_PARAM_PREFIX + "consistencyPolicy";
276 
277     /**
278      * The maximum amount of time the replication group guarantees preservation
279      * of the log files constituting the replication stream. After this period
280      * of time, nodes are free to do log cleaning and to remove log files
281      * earlier than this period. If a node has crashed and does not re-join the
282      * group within this timeout period it may need to perform a network
283      * restore operation to catch up.
284      *
285      * <p><table border="1">
286      * <tr><td>Name</td><td>Type</td><td>Mutable</td>
287      * <td>Default</td><td>Minimum</td><td>Maximum</td></tr>
288      * <tr>
289      * <td>{@value}</td>
290      * <td>
291      * {@link <a href="../EnvironmentConfig.html#timeDuration">Duration</a>}
292      * </td>
293      * <td>No</td>
294      * <td>30 m</td>
295      * <td>0</td>
296      * <td>-none-</td>
297      * </tr>
298      * </table></p>
299      *
300      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
301      * Properties</a>
302      */
303     public static final String REP_STREAM_TIMEOUT =
304         EnvironmentParams.REP_PARAM_PREFIX + "repStreamTimeout";
305 
306     /**
307      * The cost of replaying the replication stream as compared to the cost of
308      * performing a network restore, represented as a percentage.  Specifies
309      * the relative cost of using a log file as the source of transactions to
310      * replay on a replica as compared to using the file as part of a network
311      * restore.  This parameter is used to determine whether a cleaned log file
312      * that could be used to support replay should be removed because a network
313      * restore would be more efficient.  The value is typically larger than
314      * 100, to represent that replay is usually more expensive than network
315      * restore for a given amount of log data due to the cost of replaying
316      * transactions.  If the value is 0, then the parameter is disabled, and no
317      * log files will be removed based on the relative costs of replay and
318      * network restore.
319      *
320      * <p><table border="1">
321      * <tr><td>Name<td>Type<td>Mutable<td>Default<td>Minimum<td>Maximum</tr>
322      * <tr><td>{@value}<td>Integer<td>No<td>150<td>0<td>200</tr>
323      * </table>
324      *
325      * @see #REPLAY_FREE_DISK_PERCENT
326      */
327     public static final String REPLAY_COST_PERCENT =
328         EnvironmentParams.REP_PARAM_PREFIX + "replayCostPercent";
329 
330     /**
331      * The amount of free disk space that should be maintained when deciding
332      * whether to retain log files for use in replaying the replication stream,
333      * specified as a percentage of the total disk space.  This parameter
334      * prevents the retention of log files as determined by the {@link
335      * #REPLAY_COST_PERCENT} parameter if retaining the files would reduce free
336      * space below the specified percentage.  If the value is 0, then the
337      * parameter is disabled, and decisions about which log files to remove
338      * will not consider the amount of free disk space.  This parameter only
339      * has an effect when running with Java 7 or later.
340      *
341      * <p><table border="1">
342      * <tr><td>Name<td>Type<td>Mutable<td>Default<td>Minimum<td>Maximum</tr>
343      * <tr><td>{@value}<td>Integer<td>No<td>10<td>0<td>99</tr>
344      * </table>
345      *
346      * @see #REPLAY_COST_PERCENT
347      */
348     public static final String REPLAY_FREE_DISK_PERCENT =
349         EnvironmentParams.REP_PARAM_PREFIX + "replayFreeDiskPercent";
350 
351     /**
352      * The maximum amount of time for a replay transaction to wait for a lock.
353      *
354      * <p><table border="1">
355      * <tr><td>Name</td><td>Type</td><td>Mutable</td>
356      * <td>Default</td><td>Minimum</td><td>Maximum</td></tr>
357      * <tr>
358      * <td>{@value}</td>
359      * <td>
360      * {@link <a href="../EnvironmentConfig.html#timeDuration">Duration</a>}
361      * </td>
362      * <td>No</td>
363      * <td>500 ms</td>
364      * <td>1 ms</td>
365      * <td>75 min</td>
366      * </tr>
367      * </table></p>
368      *
369      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
370      * Properties</a>
371      */
372     public static final String REPLAY_TXN_LOCK_TIMEOUT =
373         EnvironmentParams.REP_PARAM_PREFIX + "replayTxnLockTimeout";
374 
375     /**
376      * The maximum number of <i>most recently used</i> database handles that
377      * are kept open during the replay of the replication stream.
378      *
379      * <p><table border="1">
380      * <tr><td>Name</td><td>Type</td><td>Mutable</td>
381      * <td>Default</td><td>Minimum</td><td>Maximum</td></tr>
382      * <tr>
383      * <td>{@value}</td>
384      * <td>Int</td>
385      * <td>Yes</td>
386      * <td>10</td>
387      * <td>1</td>
388      * <td>-none-</td>
389      * </tr>
390      * </table></p>
391      *
392      * @deprecated replaced by {@link ReplicationMutableConfig#REPLAY_MAX_OPEN_DB_HANDLES}.
393      */
394     @Deprecated
395     public static final String REPLAY_MAX_OPEN_DB_HANDLES =
396         EnvironmentParams.REP_PARAM_PREFIX + "replayMaxOpenDbHandles";
397 
398     /**
399      * The maximum amount of time that an inactive database handle is kept open
400      * during a replay of the replication stream. Handles that are inactive for
401      * more than this time period are automatically closed. Note that this does
402      * not impact any handles that may have been opened by the application.
403      *
404      * <p><table border="1">
405      * <tr><td>Name</td><td>Type</td><td>Mutable</td>
406      * <td>Default</td><td>Minimum</td><td>Maximum</td></tr>
407      * <tr>
408      * <td>{@value}</td>
409      * <td>{@link <a href="#timeDuration">Duration</a>}</td>
410      * <td>Yes</td>
411      * <td>30 sec</td>
412      * <td>1 sec</td>
413      * <td>-none-</td>
414      * </tr>
415      * </table></p>
416      *
417      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
418      * Properties</a>
419      *
420      * @deprecated replaced by {@link ReplicationMutableConfig#REPLAY_DB_HANDLE_TIMEOUT}.
421      */
422     @Deprecated
423     public static final String REPLAY_DB_HANDLE_TIMEOUT =
424         EnvironmentParams.REP_PARAM_PREFIX + "replayOpenHandleTimeout";
425 
426     /**
427      * The amount of time to wait for a Replica to become consistent with the
428      * Master, when a <code>ReplicatedEnvironment</code> handle is created and
429      * no <code>ConsistencyPolicy</code> is specified. If the Replica does not
430      * become consistent within this period, a
431      * <code>ReplicaConsistencyException</code> is thrown by the
432      * <code>ReplicatedEnvironment</code> constructor.
433      * <p>
434      * If an explicit <code>ConsistencyPolicy</code> is specified via a
435      * constructor argument, then the timeout defined by the
436      * <code>ConsistencyPolicy</code> argument is used instead of this default.
437      * <p>
438      * <table border="1">
439      * <tr>
440      * <td>Name</td>
441      * <td>Type</td>
442      * <td>Mutable</td>
443      * <td>Default</td>
444      * <td>Minimum</td>
445      * <td>Maximum</td>
446      * </tr>
447      * <tr>
448      * <td>{@value}</td>
449      * <td>
450      * {@link <a href="../EnvironmentConfig.html#timeDuration">Duration</a>}
451      * </td>
452      * <td>No</td>
453      * <td>5 min</td>
454      * <td>10 ms</td>
455      * <td>-none-</td>
456      * </tr>
457      * </table>
458      * </p>
459      *
460      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
461      * Properties</a>
462      */
463     public static final String ENV_CONSISTENCY_TIMEOUT =
464         EnvironmentParams.REP_PARAM_PREFIX + "envConsistencyTimeout";
465 
466     /**
467      * The amount of time that the
468      * {@link com.sleepycat.je.Transaction#commit(com.sleepycat.je.Durability)}
469      * on the Master will wait for a sufficient number of acknowledgments from
470      * electable Replicas. If the Master does not receive a sufficient number of
471      * acknowledgments within this timeout period, the <code>commit()</code>
472      * will throw {@link InsufficientAcksException}. In the special case of a
473      * two node group, if this node is the designated <code>Primary</code>,
474      * the <code>Primary</code> will be <code>activated</code>, and the
475      * <code>commit()</code> will proceed normally instead of throwing an
476      * exception.
477      * <p>
478      * <table border="1">
479      * <tr>
480      * <td>Name</td>
481      * <td>Type</td>
482      * <td>Mutable</td>
483      * <td>Default</td>
484      * <td>Minimum</td>
485      * <td>Maximum</td>
486      * </tr>
487      * <tr>
488      * <td>{@value}</td>
489      * <td>
490      * {@link <a href="../EnvironmentConfig.html#timeDuration">Duration</a>}
491      * </td>
492      * <td>No</td>
493      * <td>5 s</td>
494      * <td>10 ms</td>
495      * <td>-none-</td>
496      * </tr>
497      * </table>
498      * </p>
499      *
500      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
501      * Properties</a>
502      * @see ReplicationMutableConfig#DESIGNATED_PRIMARY
503      */
504     public static final String REPLICA_ACK_TIMEOUT =
505         EnvironmentParams.REP_PARAM_PREFIX + "replicaAckTimeout";
506 
507     /**
508      * The amount of time that a
509      * {@link ReplicatedEnvironment#beginTransaction(com.sleepycat.je.Transaction, com.sleepycat.je.TransactionConfig)}
510      * on the Master will wait for a sufficient number of electable Replicas,
511      * as determined by the default <code>Durability</code> policy, to contact
512      * the Master. If the timeout period expires before a sufficient number of
513      * Replicas contact the Master, the
514      * {@link ReplicatedEnvironment#beginTransaction(com.sleepycat.je.Transaction, com.sleepycat.je.TransactionConfig)}
515      * will throw {@link InsufficientReplicasException}. In the special case of
516      * a two node group, if this node is the designated <code>Primary</code>,
517      * the <code>Primary</code> will be <code>activated</code>, and the
518      * <code>beginTransaction()</code> will proceed normally instead of
519      * throwing an exception.
520      * <p>
521      * <table border="1">
522      * <tr>
523      * <td>Name</td>
524      * <td>Type</td>
525      * <td>Mutable</td>
526      * <td>Default</td>
527      * <td>Minimum</td>
528      * <td>Maximum</td>
529      * </tr>
530      * <tr>
531      * <td>{@value}</td>
532      * <td>
533      * {@link <a href="../EnvironmentConfig.html#timeDuration">Duration</a>}
534      * </td>
535      * <td>No</td>
536      * <td>10 s</td>
537      * <td>10 ms</td>
538      * <td>-none-</td>
539      * </tr>
540      * </table>
541      * </p>
542      *
543      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
544      * Properties</a>
545      * @see ReplicationMutableConfig#DESIGNATED_PRIMARY
546      */
547     public static final String INSUFFICIENT_REPLICAS_TIMEOUT =
548         EnvironmentParams.REP_PARAM_PREFIX + "insufficientReplicasTimeout";
549 
550     /**
551      * The maximum message size which will be accepted by a node (to prevent
552      * DOS attacks).  While the default shown here is 0, it dynamically
553      * calculated when the node is created and is set to the half of the
554      * environment cache size. The cache size is mutable, but changing the
555      * cache size at run time (after environment initialization) will not
556      * change the value of this parameter.  If a value other than cache size /
557      * 2 is desired, this non-mutable parameter should be specified at
558      * initialization time.
559      * <p><table border="1">
560      * <tr><td>Name</td><td>Type</td><td>Mutable</td>
561      * <td>Default</td><td>Minimum</td><td>Maximum</td></tr>
562      * <tr>
563      * <td>{@value}</td>
564      * <td>Long</td>
565      * <td>No</td>
566      * <td>half of cache size</td>
567      * <td>256KB</td>
568      * <td>Long.MAX_VALUE</td>
569      * </tr>
570      * </table></p>
571      */
572     public static final String MAX_MESSAGE_SIZE =
573         EnvironmentParams.REP_PARAM_PREFIX + "maxMessageSize";
574 
575     /**
576      * Sets the maximum acceptable clock skew between this Replica and its
577      * Feeder, which is the node that is the source of its replication stream.
578      * This value is checked whenever a Replica establishes a connection to its
579      * replication stream source. The connection is abandoned if the clock skew
580      * is larger than this value.
581      *
582      * <p><table border="1">
583      * <tr><td>Name</td><td>Type</td><td>Mutable</td>
584      * <td>Default</td><td>Minimum</td><td>Maximum</td></tr>
585      * <tr>
586      * <td>{@value}</td>
587      * <td>
588      * {@link <a href="../EnvironmentConfig.html#timeDuration">Duration</a>}
589      * </td>
590      * <td>No</td>
591      * <td>2 s</td>
592      * <td>0 s</td>
593      * <td>1 min</td>
594      * </tr>
595      * </table></p>
596      *
597      * @see ReplicationConfig#setMaxClockDelta
598      * @see ReplicationConfig#getMaxClockDelta
599      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
600      * Properties</a>
601      */
602     public static final String MAX_CLOCK_DELTA =
603         EnvironmentParams.REP_PARAM_PREFIX + "maxClockDelta";
604 
605     /**
606      * The number of times an unsuccessful election will be retried by a
607      * designated <code>Primary</code> in a two node group before it is
608      * activated and becomes the Master.
609      *
610      * <p><table border="1">
611      * <tr><td>Name</td><td>Type</td><td>Mutable</td>
612      * <td>Default</td><td>Minimum</td><td>Maximum</td></tr>
613      * <tr>
614      * <td>{@value}</td>
615      * <td>Integer</td>
616      * <td>No</td>
617      * <td>2</td>
618      * <td>0</td>
619      * <td>Integer.MAX_VALUE</td>
620      * </tr>
621      * </table></p>
622      *
623      * @see ReplicationMutableConfig#DESIGNATED_PRIMARY
624      */
625     public static final String ELECTIONS_PRIMARY_RETRIES =
626         EnvironmentParams.REP_PARAM_PREFIX + "electionsPrimaryRetries";
627 
628     /**
629      * The time interval between rebroadcasts of election results by the master
630      * node to all nodes not currently connected to it. These rebroadcasts help
631      * ensure that a replication group is fully restored after a network
632      * partition, by permitting nodes on either side of the resolved partition
633      * to catch up with the latest election results.
634      * <p>
635      * A network partition, may in some circumstances, result in a node
636      * continuing to think it is the master, even though it is on the side of
637      * the partition containing a minority of electable nodes, and the side
638      * with the majority has elected a new master. Rebroadcasting election
639      * results on a periodic basis ensures that the obsolete master is brought
640      * up to date after the network partition has been resolved. As a result of
641      * the update, the environment at the obsolete master will transition into
642      * a replica state.
643      * <p>
644      * Decreasing the period will result in more frequent broadcasts and thus a
645      * faster return to normal operations after a network partition has been
646      * resolved.
647      *
648      * <p>
649      * <table border="1">
650      * <tr>
651      * <td>Name</td>
652      * <td>Type</td>
653      * <td>Mutable</td>
654      * <td>Default</td>
655      * <td>Minimum</td>
656      * <td>Maximum</td>
657      * </tr>
658      * <tr>
659      * <td>{@value}</td>
660      * <td>
661      * {@link <a href="../EnvironmentConfig.html#timeDuration">Duration</a>}</td>
662      * <td>No</td>
663      * <td>1 min</td>
664      * <td>1 s</td>
665      * <td>none</td>
666      * </tr>
667      * </table>
668      * </p>
669      */
670     public static final String  ELECTIONS_REBROADCAST_PERIOD =
671         EnvironmentParams.REP_PARAM_PREFIX + "electionsRebroadcastPeriod";
672 
673     /**
674      * In rare cases, a node may need to rollback committed transactions in
675      * order to rejoin a replication group. This parameter limits the
676      * number of transactions that may be rolled back. If the number of
677      * committed transactions targeted for rollback exceeds this parameter,
678      * a {@link RollbackProhibitedException} will be thrown.
679      *
680      * <p><table border="1">
681      * <tr><td>Name</td><td>Type</td><td>Mutable</td>
682      * <td>Default</td><td>Minimum</td><td>Maximum</td></tr>
683      * <tr>
684      * <td>{@value}</td>
685      * <td>Integer</td>
686      * <td>No</td>
687      * <td>10</td>
688      * <td>0</td>
689      * <td>Integer.MAX_VALUE</td>
690      * </tr>
691      * </table></p>
692      *
693      * @see RollbackProhibitedException
694      */
695     public static final String TXN_ROLLBACK_LIMIT =
696         EnvironmentParams.REP_PARAM_PREFIX + "txnRollbackLimit";
697 
698     /**
699      * A heartbeat is exchanged between the feeder and replica to ensure they
700      * are alive. This is the timeout associated with the heartbeat on the
701      * feeder side of the connection.
702      * <p>
703      * Reducing this value enables the master to discover failed Replicas, and
704      * recycle feeder connections, faster. However, it increases the chances of
705      * false timeouts, if the network is experiencing transient problems, or
706      * the Java GC is responsible for long pauses. In the latter case, it's
707      * generally better to tune the GC to avoid such pauses.
708      *
709      * <p>
710      * <table border="1">
711      * <tr>
712      * <td>Name</td>
713      * <td>Type</td>
714      * <td>Mutable</td>
715      * <td>Default</td>
716      * <td>Minimum</td>
717      * <td>Maximum</td>
718      * </tr>
719      * <tr>
720      * <td>{@value}</td>
721      * <td>
722      * {@link <a href="../EnvironmentConfig.html#timeDuration">Duration</a>}
723      * </td>
724      * <td>No</td>
725      * <td>30 s</td>
726      * <td>2 s</td>
727      * <td>-none-</td>
728      * </tr>
729      * </table>
730      * </p>
731      *
732      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
733      * Properties</a>
734      * @since 4.0.100
735      */
736     public static final String FEEDER_TIMEOUT =
737         EnvironmentParams.REP_PARAM_PREFIX + "feederTimeout";
738 
739     /**
740      * A heartbeat is exchanged between the feeder and replica to ensure they
741      * are alive. This is the timeout associated with the heartbeat on the
742      * replica side of the connection.
743      * <p>
744      * Reducing the value means that a master failure will be discovered more
745      * promptly in some circumstances and the overall time needed to failover
746      * to a new master will be reduced. However, it increases the chances of
747      * false timeouts, if the network is experiencing transient problems, or
748      * the Java GC is responsible for long pauses. In the latter case, it's
749      * generally better to tune the GC to avoid such pauses.
750      * <p>
751      * <table border="1">
752      * <tr>
753      * <td>Name</td>
754      * <td>Type</td>
755      * <td>Mutable</td>
756      * <td>Default</td>
757      * <td>Minimum</td>
758      * <td>Maximum</td>
759      * </tr>
760      * <tr>
761      * <td>{@value}</td>
762      * <td>
763      * {@link <a href="../EnvironmentConfig.html#timeDuration">Duration</a>}
764      * </td>
765      * <td>No</td>
766      * <td>30 s</td>
767      * <td>2 s</td>
768      * <td>-none-</td>
769      * </tr>
770      * </table>
771      * </p>
772      *
773      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
774      * Properties</a>
775      * @since 4.0.100
776      */
777     public static final String REPLICA_TIMEOUT =
778         EnvironmentParams.REP_PARAM_PREFIX + "replicaTimeout";
779 
780     /**
781      * The size of the the TCP receive buffer associated with the socket used
782      * by the replica to transfer the replication stream.
783      * <p>
784      * Larger values help handle incoming network traffic even when the replica
785      * has been paused for a garbage collection. The parameter default value of
786      * 1 MB should be sufficient in most of the environments. Consider
787      * increasing the value if network monitoring shows packet loss, or if your
788      * JE environment contains large data values. Note that if the size
789      * specified is larger than the operating system constrained maximum, it
790      * will be limited to this maximum value. For example, on Linux you may
791      * need to set the kernel parameter: net.core.rmem_max property using the
792      * command: <i>sysctl -w net.core.rmem_max=1048576</i> to increase the
793      * operating system imposed limit.
794      * <p>
795      * A parameter value of zero will result in the use of operating system
796      * specified default socket buffer size.
797      *
798      * <p>
799      * <table border="1">
800      * <tr>
801      * <td>Name</td>
802      * <td>Type</td>
803      * <td>Mutable</td>
804      * <td>Default</td>
805      * <td>Minimum</td>
806      * <td>Maximum</td>
807      * </tr>
808      * <tr>
809      * <td>{@value}</td>
810      * <td>Integer</td>
811      * <td>No</td>
812      * <td>1048576</td>
813      * <td>0</td>
814      * <td>-none-</td>
815      * </tr>
816      * </table>
817      * </p>
818      *
819      * @since 5.0.37
820      */
821     public static final String REPLICA_RECEIVE_BUFFER_SIZE =
822             EnvironmentParams.REP_PARAM_PREFIX + "replicaReceiveBufferSize";
823 
824     /**
825      * The maximum number of transactions that can be grouped to amortize the
826      * cost of an fsync when a transaction commits with SyncPolicy#SYNC on the
827      * Replica. A value of zero effectively turns off the group commit
828      * optimization.
829      * <p>
830      * Specifying larger values can result in more transactions being grouped
831      * together decreasing average commit times.
832      * <p>
833      * An fsync is issued if the size of the transaction group reaches the
834      * maximum within the time period specified by
835      * {@link #REPLICA_GROUP_COMMIT_INTERVAL}.
836      * <p>
837      * The {@link
838      * ReplicatedEnvironmentStats#getNReplayGroupCommitMaxExceeded()}
839      * statistic may be used to tune this parameter. Large values indicate that
840      * commit throughput could be improved by increasing the current value.
841      * <p>
842      * <table border="1">
843      * <tr>
844      * <td>Name</td>
845      * <td>Type</td>
846      * <td>Mutable</td>
847      * <td>Default</td>
848      * <td>Minimum</td>
849      * <td>Maximum</td>
850      * </tr>
851      * <tr>
852      * <td>{@value}</td>
853      * <td>Integer</td>
854      * <td>No</td>
855      * <td>200</td>
856      * <td>0</td>
857      * <td>-none-</td>
858      * </tr>
859      * </table>
860      * </p>
861      *
862      * @since 5.0.76
863      * @see #REPLICA_GROUP_COMMIT_INTERVAL
864      */
865     public static final String REPLICA_MAX_GROUP_COMMIT =
866         EnvironmentParams.REP_PARAM_PREFIX + "replicaMaxGroupCommit";
867 
868     /**
869      * The time interval during which transactions may be grouped to amortize
870      * the cost of fsync when a transaction commits with SyncPolicy#SYNC on the
871      * Replica. This parameter is only meaningful if the
872      * {@link #REPLICA_MAX_GROUP_COMMIT group commit size} is greater than one.
873      * <p>
874      * The first (as ordered by transaction serialization) transaction in a
875      * transaction group may be delayed by at most this amount. Subsequent
876      * transactions in the group will have smaller delays since they are later
877      * in the serialization order.
878      * <p>
879      * The {@link ReplicatedEnvironmentStats#getNReplayGroupCommitTimeouts()}
880      * statistic may be used to tune this parameter. Large numbers of timeouts
881      * in conjunction with large numbers of group commits (
882      * {@link ReplicatedEnvironmentStats#getNReplayGroupCommits()}) indicate
883      * that commit throughput could be improved by increasing the time
884      * interval.
885      * <p>
886      * <table border="1">
887      * <tr>
888      * <td>Name</td>
889      * <td>Type</td>
890      * <td>Mutable</td>
891      * <td>Default</td>
892      * <td>Minimum</td>
893      * <td>Maximum</td>
894      * </tr>
895      * <tr>
896      * <td>{@value}</td>
897      * <td>{@link <a href="#timeDuration">Duration</a>}</td>
898      * <td>No</td>
899      * <td>3 ms</td>
900      * <td>0</td>
901      * <td>-none-</td>
902      * </tr>
903      * </table>
904      * </p>
905      *
906      * @since 5.0.76
907      * @see #REPLICA_MAX_GROUP_COMMIT
908      */
909     public static final String REPLICA_GROUP_COMMIT_INTERVAL =
910         EnvironmentParams.REP_PARAM_PREFIX + "replicaGroupCommitInterval";
911 
912     /**
913      * The maximum amount of time for the internal housekeeping, like
914      * elections, syncup with the master, etc. to be accomplished when opening
915      * a new handle to an environment.
916      * <p>
917      * This timeout does not encompass the time spent making the node
918      * consistent with the master, if it is a Replica. The timeout associated
919      * with making a replica consistent is normally determined by the
920      * {@link #ENV_CONSISTENCY_TIMEOUT} parameter but can be overridden by the
921      * timeout associated with the <code>ReplicaConsistencyPolicy</code> if a
922      * <code>consistencyPolicy</code> argument was supplied to the handle
923      * constructor.
924      * <p>
925      * Note that the default value (10 hours) is a long time to allow for cases
926      * where elections may take a long time when other nodes are not available.
927      * <p>
928      * <table border="1">
929      * <tr>
930      * <td>Name</td>
931      * <td>Type</td>
932      * <td>Mutable</td>
933      * <td>Default</td>
934      * <td>Minimum</td>
935      * <td>Maximum</td>
936      * </tr>
937      * <tr>
938      * <td>{@value}</td>
939      * <td>Duration</td>
940      * <td>No</td>
941      * <td>10 h</td>
942      * <td>-none-</td>
943      * <td>-none-</td>
944      * </tr>
945      * </table>
946      * </p>
947      *
948      * @see <a href="../EnvironmentConfig.html#timeDuration">Time Duration
949      * Properties</a>
950      */
951     public static final String ENV_SETUP_TIMEOUT =
952         EnvironmentParams.REP_PARAM_PREFIX + "envSetupTimeout";
953 
954     /**
955      * @hidden
956      * @deprecated
957      *
958      * For internal use only.
959      *
960      * When set to <code>true</code>, it permits opening of a
961      * ReplicatedEnvironment handle in the {@link
962      * ReplicatedEnvironment.State#UNKNOWN} state, if a Master could not be
963      * determined within the timeout specified by {@link
964      * ReplicationConfig#ENV_SETUP_TIMEOUT}. If it's false, an <code>
965      * UnknownMasterException</code> exception is thrown upon expiration of
966      * the timeout.
967      * <p>
968      * A ReplicatedEnvironment handle in the {@link
969      * ReplicatedEnvironment.State#UNKNOWN} state can only be used to initiate
970      * read operations with an appropriately relaxed {@link
971      * NoConsistencyRequiredPolicy}; write operations will fail with a
972      * <code>ReplicaWriteException</code>. The handle will transition to
973      * a <code>Master</code> or <code>Replica</code> state when it can contact
974      * a sufficient number of other nodes in the replication group.
975      * <p>
976      * <table border="1">
977      * <tr>
978      * <td>Name</td>
979      * <td>Type</td>
980      * <td>Mutable</td>
981      * <td>Default</td>
982      * </tr>
983      * <tr>
984      * <td>{@value}</td>
985      * <td>Boolean</td>
986      * <td>No</td>
987      * <td>False</td>
988      * </tr>
989      * </table>
990      */
991     @Deprecated
992     public static final String ALLOW_UNKNOWN_STATE_ENV_OPEN =
993         EnvironmentParams.REP_PARAM_PREFIX + "allowUnknownStateEnvOpen";
994 
995     /**
996      * Permits opening of a ReplicatedEnvironment handle in the
997      * {@link ReplicatedEnvironment.State#UNKNOWN} state, if a Master cannot be
998      * determined within this timeout period. For the timeout to be meaningful
999      * it must be less than {@link #ENV_SETUP_TIMEOUT}. This parameter is
1000      * ignored when creating a replicated environment for the first time.
1001      * <p>
1002      * A ReplicatedEnvironment handle in the
1003      * {@link ReplicatedEnvironment.State#UNKNOWN} state can only be used to
1004      * initiate read operations with an appropriately relaxed, e.g.
1005      * {@link NoConsistencyRequiredPolicy}; write operations will fail with a
1006      * {@link ReplicaWriteException}. The handle will transition to a
1007      * {@code Master} or {@code Replica} state when it can contact a
1008      * sufficient number of other nodes in the replication group.
1009      * <p>
1010      * If the parameter is set to zero, and an election cannot be concluded
1011      * within the timeout defined by {@link #ENV_SETUP_TIMEOUT}, the
1012      * ReplicatedEnvironment constructor will throw {@link
1013      * UnknownMasterException}.
1014      * <p>
1015      * <table border="1">
1016      * <tr>
1017      * <td>Name</td>
1018      * <td>Type</td>
1019      * <td>Mutable</td>
1020      * <td>Default</td>
1021      * <td>Minimum</td>
1022      * <td>Maximum</td>
1023      * </tr>
1024      * <tr>
1025      * <td>{@value}</td>
1026      * <td>Duration</td>
1027      * <td>No</td>
1028      * <td>0</td>
1029      * <td>-none-</td>
1030      * <td><code>ENV_SETUP_TIMEOUT</code></td>
1031      * </tr>
1032      *
1033      * @since 5.0.33
1034      */
1035     public static final String ENV_UNKNOWN_STATE_TIMEOUT =
1036         EnvironmentParams.REP_PARAM_PREFIX + "envUnknownStateTimeout";
1037 
1038     /**
1039      * When set to <code>true</code>, which is currently the default, the
1040      * replication network protocol will use the JVM platform default charset
1041      * (text encoding) for node names and host names.  This is incorrect, in
1042      * that it requires that the JVM for all nodes in a replication group have
1043      * the same default charset.
1044      * <p>
1045      * When this parameter is set to <code>false</code>, the UTF-8 charset is
1046      * always used in the replication protocol.  In other words, the JVM
1047      * default charset has no impact on the replication protocol.
1048      * <p>
1049      * An application is <em>not</em> impacted by this issue, and does not need
1050      * to set this parameter, if it has the following characteristics.
1051      * <ul>
1052      * <li>The default charset on all JVMs is UTF-8 or ASCII, or</li>
1053      * <li>all node names and host names contain only ASCII characters, and
1054      * the default charset on all JVMs is a superset of ASCII.</li>
1055      * </ul>
1056      * <p>
1057      * In JE 5.1, the default value for this parameter will be changed to
1058      * false.  In preparation for this, impacted applications should explicitly
1059      * set the parameter to false at the next available opportunity.  For
1060      * applications not yet deployed, this should be done now.  For deployed
1061      * applications, a hot upgrade may not be performed when changing the
1062      * parameter.  Instead, a cold upgrade must be performed:  all nodes must
1063      * be stopped and upgraded before bringing them up again.  In other words,
1064      * for impacted applications the value of this configuration parameter must
1065      * be the same for all running nodes in a replication group.
1066      * <p>
1067      * Note that the default charset issue applies only to the replication
1068      * network protocol and not to stored data of any kind.
1069      * <p>
1070      * <table border="1">
1071      * <tr>
1072      * <td>Name</td>
1073      * <td>Type</td>
1074      * <td>Mutable</td>
1075      * <td>Default</td>
1076      * </tr>
1077      * <tr>
1078      * <td>{@value}</td>
1079      * <td>Boolean</td>
1080      * <td>No</td>
1081      * <td>True</td>
1082      * </tr>
1083      * </table>
1084      */
1085     public static final String PROTOCOL_OLD_STRING_ENCODING =
1086         EnvironmentParams.REP_PARAM_PREFIX + "protocolOldStringEncoding";
1087 
1088     /**
1089      * @hidden
1090      * For internal use, to allow null as a valid value for the config
1091      * parameter.
1092      */
1093     public static final ReplicationConfig DEFAULT =
1094         new ReplicationConfig();
1095 
1096     /* Support conversion of a non-replicated environment to replicated. */
1097     private boolean allowConvert = false;
1098 
1099     /*
1100      * The ReplicationNetworkConfig portion of the overall replication
1101      * configuration.
1102      *
1103      * This field should be typed as ReplicationNetworkConfig, but because this
1104      * class is serializable and field is not transient, javadoc wants to
1105      * describe it as part of the javadoc output, but the fact that the type is
1106      * hidden causes javadoc to encounter a NullPointerException.  As a
1107      * temporary measure, this class is typed as Object in order to avoid
1108      * the javadoc error.  When ReplicationNetworkConfig becomes public, the
1109      * type of the field should be changed to ReplicationNetworkConfig.  This
1110      * will not cause any problems with cross-release serialization as long as
1111      * we take care that only ReplicationNetworkConfig instances are assigned
1112      * to this field.
1113      */
1114     private Object repNetConfig = ReplicationNetworkConfig.createDefault();
1115 
1116     /* A ProgressListener for tracking this node's syncups. */
1117     private transient
1118         ProgressListener<SyncupProgress> syncupProgressListener;
1119 
1120     private transient LogFileRewriteListener logRewriteListener;
1121 
1122     /**
1123      * Creates a ReplicationConfig initialized with the system default
1124      * settings. Defaults are documented with the string constants in this
1125      * class.
1126      */
ReplicationConfig()1127     public ReplicationConfig() {
1128         super();
1129     }
1130 
1131     /**
1132      * Creates a ReplicationConfig initialized with the system default
1133      * settings and the specified group name, node name, and hostname/port
1134      * values.
1135      *
1136      * <p>Note that the node name is immutable. Normally the host name should
1137      * not be used as the node name, unless you intend to reuse the host
1138      * name when a machine fails and is replaced, or the node is upgraded to
1139      * new hardware.</p>
1140      *
1141      * @param groupName the name for the replication group
1142      * @param nodeName the name for this node
1143      * @param hostPort the hostname and port for this node
1144      *
1145      * @see #setGroupName
1146      * @see #setNodeName
1147      */
ReplicationConfig(String groupName, String nodeName, String hostPort)1148     public ReplicationConfig(String groupName,
1149                              String nodeName,
1150                              String hostPort) {
1151         super();
1152         setGroupName(groupName);
1153         setNodeName(nodeName);
1154         setNodeHostPort(hostPort);
1155     }
1156 
1157     /**
1158      * Creates a ReplicationConfig which includes the properties specified in
1159      * the properties parameter.
1160      *
1161      * @param properties Supported properties are described as the string
1162      * constants in this class.
1163      *
1164      * @throws IllegalArgumentException If any properties read from the
1165      * properties parameter are invalid.
1166      */
ReplicationConfig(Properties properties)1167     public ReplicationConfig(Properties properties)
1168         throws IllegalArgumentException {
1169 
1170         super(properties, true /* validateParams */);
1171         propagateRepNetProps();
1172     }
1173 
1174     /**
1175      * Internal use only, from RepConfigManager.
1176      */
ReplicationConfig(Properties properties, boolean validateParams)1177     ReplicationConfig(Properties properties, boolean validateParams)
1178         throws IllegalArgumentException {
1179 
1180         super(properties, validateParams);
1181         propagateRepNetProps();
1182     }
1183 
1184     /**
1185      * Gets the name associated with the replication group.
1186      *
1187      * @return the name of this replication group.
1188      */
getGroupName()1189     public String getGroupName() {
1190         return DbConfigManager.getVal(props, RepParams.GROUP_NAME);
1191     }
1192 
1193     /**
1194      * Sets the name for the replication group.
1195      * <p>
1196      * The name should consist of letters, digits, and/or hyphen ("-"),
1197      * underscore ("_"), or period (".").
1198      *
1199      * @param groupName the string representing the name
1200      *
1201      * @return this
1202      *
1203      * @throws IllegalArgumentException If the string name is not valid
1204      */
setGroupName(String groupName)1205     public ReplicationConfig setGroupName(String groupName)
1206         throws IllegalArgumentException {
1207 
1208         setGroupNameVoid(groupName);
1209         return this;
1210     }
1211 
1212     /**
1213      * @hidden
1214      * The void return setter for use by Bean editors.
1215      */
setGroupNameVoid(String groupName)1216     public void setGroupNameVoid(String groupName)
1217         throws IllegalArgumentException {
1218 
1219         DbConfigManager.setVal(props, RepParams.GROUP_NAME, groupName,
1220                                validateParams);
1221     }
1222 
1223     /**
1224      * For internal use only.
1225      *
1226      * Returns a boolean that specifies if we need to convert the existing logs
1227      * to replicated format.
1228      *
1229      * @return true if we want to convert the existing logs to replicated
1230      * format
1231      */
getAllowConvert()1232     boolean getAllowConvert() {
1233         return allowConvert;
1234     }
1235 
1236     /**
1237      * For internal use only.
1238      *
1239      * If set to true, this environment should be converted to replicated
1240      * format.
1241      *
1242      * @param allowConvert if true, this environment should be converted to
1243      * replicated format.
1244      */
setAllowConvert(boolean allowConvert)1245     void setAllowConvert(boolean allowConvert) {
1246         this.allowConvert = allowConvert;
1247     }
1248 
1249     /**
1250      * Returns the unique name associated with this node.
1251      *
1252      * @return the node name
1253      */
getNodeName()1254     public String getNodeName() {
1255         return DbConfigManager.getVal(props, RepParams.NODE_NAME);
1256     }
1257 
1258     /**
1259      * Sets the name to be associated with this node. It must be unique within
1260      * the group.  When the node is instantiated and joins the replication
1261      * group, a check is done to ensure that the name is unique, and a {@link
1262      * RestartRequiredException} is thrown if it is not.
1263      * <p>
1264      * The name should consist of letters, digits, and/or hyphen ("-"),
1265      * underscore ("_"), or period (".").
1266      *
1267      * <p>Note that the node name is immutable. Normally the host name should
1268      * not be used as the node name, unless you intend to reuse the host
1269      * name when a machine fails and is replaced, or the node is upgraded to
1270      * new hardware.</p>
1271      *
1272      * @param nodeName the node name for this replicated environment.
1273      *
1274      * @return this
1275      * @throws IllegalArgumentException If the name is not valid
1276      */
setNodeName(String nodeName)1277     public ReplicationConfig setNodeName(String nodeName)
1278         throws IllegalArgumentException {
1279 
1280         setNodeNameVoid(nodeName);
1281         return this;
1282     }
1283 
1284     /**
1285      * @hidden
1286      * The void return setter for use by Bean editors.
1287      */
setNodeNameVoid(String nodeName)1288     public void setNodeNameVoid(String nodeName)
1289         throws IllegalArgumentException {
1290 
1291         DbConfigManager.setVal(props, RepParams.NODE_NAME, nodeName,
1292                                validateParams);
1293     }
1294 
1295     /**
1296      * Returns the {@link NodeType} of this node.
1297      *
1298      * @return the node type
1299      */
getNodeType()1300     public NodeType getNodeType() {
1301         return RepParams.NODE_TYPE.getEnumerator
1302             (DbConfigManager.getVal(props, RepParams.NODE_TYPE));
1303     }
1304 
1305     /**
1306      * Sets the type of this node.
1307      *
1308      * @param nodeType the node type
1309      *
1310      * @return this
1311      */
setNodeType(NodeType nodeType)1312     public ReplicationConfig setNodeType(NodeType nodeType){
1313         setNodeTypeVoid(nodeType);
1314         return this;
1315     }
1316 
1317     /**
1318      * @hidden
1319      * The void return setter for use by Bean editors.
1320      */
setNodeTypeVoid(NodeType nodeType)1321     public void setNodeTypeVoid(NodeType nodeType){
1322         DbConfigManager.setVal
1323             (props, RepParams.NODE_TYPE, nodeType.name(), validateParams);
1324     }
1325 
1326     /**
1327      * Returns the hostname and port associated with this node. The hostname
1328      * and port combination are denoted by a string of the form:
1329      * <pre>
1330      *   hostname:port
1331      * </pre>
1332      * @return the hostname and port string.
1333      *
1334      * @see ReplicationConfig#NODE_HOST_PORT
1335      */
getNodeHostPort()1336     public String getNodeHostPort() {
1337         return DbConfigManager.getVal(props, RepParams.NODE_HOST_PORT);
1338     }
1339 
1340     /**
1341      * Sets the hostname and port associated with this node. The hostname
1342      * and port combination are denoted by a string of the form:
1343      * <pre>
1344      *  hostname[:port]
1345      * </pre>
1346      * The port must be outside the range of "Well Known Ports"
1347      * (zero through 1023).
1348      *
1349      * @param hostPort the string containing the hostname and port as above.
1350      *
1351      * @return this
1352      *
1353      * @see ReplicationConfig#NODE_HOST_PORT
1354      */
setNodeHostPort(String hostPort)1355     public ReplicationConfig setNodeHostPort(String hostPort) {
1356         setNodeHostPortVoid(hostPort);
1357         return this;
1358     }
1359 
1360     /**
1361      * @hidden
1362      * The void return setter for use by Bean editors.
1363      */
setNodeHostPortVoid(String hostPort)1364     public void setNodeHostPortVoid(String hostPort) {
1365         DbConfigManager.setVal(props, RepParams.NODE_HOST_PORT, hostPort,
1366                                validateParams);
1367     }
1368 
1369     /**
1370      * Returns the configured replica timeout value.
1371      *
1372      * @return the timeout in milliseconds
1373      */
getReplicaAckTimeout(TimeUnit unit)1374     public long getReplicaAckTimeout(TimeUnit unit) {
1375         return DbConfigManager.getDurationVal
1376             (props, RepParams.REPLICA_ACK_TIMEOUT, unit);
1377     }
1378 
1379     /**
1380      * Set the replica commit timeout.
1381      *
1382      * @param replicaAckTimeout time in milliseconds
1383      *
1384      * @return this
1385      */
setReplicaAckTimeout(long replicaAckTimeout, TimeUnit unit)1386     public ReplicationConfig setReplicaAckTimeout(long replicaAckTimeout,
1387                                                   TimeUnit unit) {
1388         setReplicaAckTimeoutVoid(replicaAckTimeout, unit);
1389         return this;
1390     }
1391 
1392     /**
1393      * @hidden
1394      * The void return setter for use by Bean editors.
1395      */
setReplicaAckTimeoutVoid(long replicaAckTimeout, TimeUnit unit)1396     public void setReplicaAckTimeoutVoid(long replicaAckTimeout,
1397                                          TimeUnit unit) {
1398         DbConfigManager.setDurationVal
1399             (props, RepParams.REPLICA_ACK_TIMEOUT, replicaAckTimeout, unit,
1400              validateParams);
1401     }
1402 
1403     /**
1404      * Returns the maximum acceptable clock skew between this Replica and its
1405      * Feeder, which is the node that is the source of its replication stream.
1406      *
1407      * @return the max permissible clock skew
1408      */
getMaxClockDelta(TimeUnit unit)1409     public long getMaxClockDelta(TimeUnit unit) {
1410         return DbConfigManager.getDurationVal(props, RepParams.MAX_CLOCK_DELTA,
1411                                               unit);
1412     }
1413 
1414     /**
1415      * Sets the maximum acceptable clock skew between this Replica and its
1416      * Feeder, which is the node that is the source of its replication
1417      * stream. This value is checked whenever a Replica establishes a
1418      * connection to its replication stream source. The connection is abandoned
1419      * if the clock skew is larger than this value.
1420      *
1421      * @param maxClockDelta the maximum acceptable clock skew
1422      *
1423      * @return this
1424      *
1425      * @throws IllegalArgumentException if the value is not a positive integer
1426      */
setMaxClockDelta(long maxClockDelta, TimeUnit unit)1427     public ReplicationConfig setMaxClockDelta(long maxClockDelta,
1428                                               TimeUnit unit)
1429         throws IllegalArgumentException {
1430 
1431         setMaxClockDeltaVoid(maxClockDelta, unit);
1432         return this;
1433     }
1434 
1435     /**
1436      * @hidden
1437      * The void return setter for use by Bean editors.
1438      */
setMaxClockDeltaVoid(long maxClockDelta, TimeUnit unit)1439     public void setMaxClockDeltaVoid(long maxClockDelta, TimeUnit unit)
1440         throws IllegalArgumentException {
1441 
1442         DbConfigManager.setDurationVal(props, RepParams.MAX_CLOCK_DELTA,
1443                                        maxClockDelta, unit, validateParams);
1444     }
1445 
1446     /**
1447      * Sets the consistency policy to be associated with the configuration.
1448      * This policy acts as the default policy used to govern the consistency
1449      * requirements when starting new transactions. See the {@link <a
1450      * href="{@docRoot}../ReplicationGuide/consistency.html">overview on
1451      * consistency in replicated systems</a>} for more background.
1452      * <p>
1453      * @param policy the consistency policy to be set for this config.
1454      *
1455      * @return this
1456      */
1457     public ReplicationConfig
setConsistencyPolicy(ReplicaConsistencyPolicy policy)1458         setConsistencyPolicy(ReplicaConsistencyPolicy policy) {
1459 
1460         setConsistencyPolicyVoid(policy);
1461         return this;
1462     }
1463 
1464     /**
1465      * @hidden
1466      * The void return setter for use by Bean editors.
1467      */
setConsistencyPolicyVoid(ReplicaConsistencyPolicy policy)1468     public void setConsistencyPolicyVoid(ReplicaConsistencyPolicy policy) {
1469 
1470         DbConfigManager.setVal(props,
1471                                RepParams.CONSISTENCY_POLICY,
1472                                RepUtils.getPropertyString(policy),
1473                                validateParams);
1474     }
1475 
1476     /**
1477      * Returns the default consistency policy associated with the
1478      * configuration.
1479      * <p>
1480      * If the user does not set the default consistency policy through {@link
1481      * ReplicationConfig#setConsistencyPolicy}, the system will use the policy
1482      * defined by {@link ReplicationConfig#CONSISTENCY_POLICY}.
1483      *
1484      * @return the consistency policy currently associated with this config.
1485      */
1486    @Override
getConsistencyPolicy()1487    public ReplicaConsistencyPolicy getConsistencyPolicy() {
1488         String propertyValue =
1489             DbConfigManager.getVal(props,
1490                                    RepParams.CONSISTENCY_POLICY);
1491         return RepUtils.getReplicaConsistencyPolicy(propertyValue);
1492     }
1493 
1494     @Override
setConfigParam(String paramName, String value)1495     public ReplicationConfig setConfigParam(String paramName, String value)
1496         throws IllegalArgumentException {
1497 
1498         if (ReplicationNetworkConfig.getRepNetPropertySet().
1499             contains(paramName)) {
1500             getRepNetConfig().setConfigParam(paramName, value);
1501         } else {
1502             DbConfigManager.setConfigParam(props,
1503                                            paramName,
1504                                            value,
1505                                            false,   /* require mutability. */
1506                                            validateParams,
1507                                            true,   /* forReplication */
1508                                            true);  /* verifyForReplication */
1509         }
1510         return this;
1511     }
1512 
1513     /**
1514      * @hidden SSL deferred
1515      * Get the replication service net configuration associated with
1516      * this ReplicationConfig.
1517      */
getRepNetConfig()1518     public ReplicationNetworkConfig getRepNetConfig() {
1519         return (ReplicationNetworkConfig) repNetConfig;
1520     }
1521 
1522     /**
1523      * @hidden SSL deferred
1524      * Set the replication service net configuration associated with
1525      * this ReplicationConfig.
1526      *
1527      * @param netConfig the new ReplicationNetworkConfig to be associated
1528      * with this ReplicationConfig.  This must not be null.
1529      *
1530      * @throws IllegalArgumentException if the netConfig is null
1531      */
setRepNetConfig( ReplicationNetworkConfig netConfig)1532     public ReplicationConfig setRepNetConfig(
1533         ReplicationNetworkConfig netConfig) {
1534 
1535         setRepNetConfigVoid(netConfig);
1536         return this;
1537     }
1538 
1539     /**
1540      * @hidden
1541      * For bean editors
1542      */
setRepNetConfigVoid(ReplicationNetworkConfig netConfig)1543     public void setRepNetConfigVoid(ReplicationNetworkConfig netConfig) {
1544         if (netConfig == null) {
1545             throw new IllegalArgumentException("netConfig may not be null");
1546         }
1547         repNetConfig = netConfig;
1548     }
1549 
1550     /**
1551      * Returns a copy of this configuration object.
1552      */
1553     @Override
clone()1554     public ReplicationConfig clone() {
1555         try {
1556             ReplicationConfig copy = (ReplicationConfig) super.clone();
1557             copy.setRepNetConfig(getRepNetConfig().clone());
1558             return copy;
1559         } catch (CloneNotSupportedException willNeverOccur) {
1560             return null;
1561         }
1562     }
1563 
1564     /**
1565      * @hidden
1566      * For use by this class and by ReplicatedEnvironment.setupRepConfig()
1567      * Moves any properties that belong to ReplicationNetworkConfig to
1568      * repNetConfig.
1569      * This is intended to be called after a bulk property load.
1570      */
propagateRepNetProps()1571     void propagateRepNetProps() {
1572 
1573         /* If there is no current RepNetConfig, simply adopt the new config. */
1574         final ReplicationNetworkConfig rnConfig = getRepNetConfig();
1575         if (rnConfig == null) {
1576             setRepNetConfig(ReplicationNetworkConfig.create(props));
1577             return;
1578         }
1579 
1580         /*
1581          * Construct a new properties set that includes both the properties
1582          * that we hold directly, plus any properties stored on an existing
1583          * repNetConfig object.  Our properties will override those on
1584          * repNetConfig.
1585          */
1586         final Properties combProps = new Properties(rnConfig.getProps());
1587         for (String propName : props.stringPropertyNames()) {
1588             combProps.setProperty(propName, props.getProperty(propName));
1589         }
1590 
1591         /*
1592          * Create a new ReplicationNetworkConfig instance based on the combined
1593          * properties.
1594          */
1595         ReplicationNetworkConfig newRepNetConfig =
1596             ReplicationNetworkConfig.create(combProps);
1597 
1598         /*
1599          * If the type of the config object did not change, there may be
1600          * non-property fields that should be retained from the original,
1601          * so use the orignal object and just change the properties.
1602          */
1603         if (newRepNetConfig.getClass() == repNetConfig.getClass()) {
1604             rnConfig.applyRepNetProperties(combProps);
1605         } else {
1606             setRepNetConfig(newRepNetConfig);
1607         }
1608     }
1609 
1610     /**
1611      * @hidden
1612      *
1613      * For internal use only: Internal convenience method.
1614      *
1615      * Returns the set of sockets associated with helper nodes. This method
1616      * should only be used when the configuration object is known to have an
1617      * authoritative value for the helper hosts values. In a replication node,
1618      * the je.properties file may override the values in this configuration
1619      * object.
1620      *
1621      * @return the set of helper sockets, returns an empty set if there are no
1622      * helpers.
1623      */
getHelperSockets()1624     public Set<InetSocketAddress> getHelperSockets() {
1625         return HostPortPair.getSockets(getHelperHosts());
1626     }
1627 
1628     /**
1629      * @hidden
1630      * Internal convenience methods for returning replication sockets.
1631      *
1632      * This method should only be used when the configuration object is known
1633      * to have an authoritative value for its socket value. In a replication
1634      * node, the je.properties file may override the values in this
1635      * configuration object.
1636      */
getNodeSocketAddress()1637     public InetSocketAddress getNodeSocketAddress() {
1638 
1639         return new InetSocketAddress(getNodeHostname(), getNodePort());
1640     }
1641 
1642     /**
1643      * Returns the hostname component of the nodeHost property.
1644      *
1645      * @return the hostname string
1646      */
getNodeHostname()1647     public String getNodeHostname() {
1648         String hostAndPort =
1649             DbConfigManager.getVal(props, RepParams.NODE_HOST_PORT);
1650         int colonToken = hostAndPort.indexOf(":");
1651 
1652         return (colonToken >= 0) ?
1653                 hostAndPort.substring(0,colonToken) : hostAndPort;
1654     }
1655 
1656     /**
1657      * Returns the port component of the nodeHost property.
1658      *
1659      * @return the port number
1660      */
getNodePort()1661     public int getNodePort() {
1662         String hostAndPort =
1663             DbConfigManager.getVal(props, RepParams.NODE_HOST_PORT);
1664         int colonToken = hostAndPort.indexOf(":");
1665 
1666         String portString = (colonToken >= 0) ?
1667             hostAndPort.substring(colonToken+1) :
1668             DbConfigManager.getVal(props, RepParams.DEFAULT_PORT);
1669 
1670         return Integer.parseInt(portString) ;
1671     }
1672 
1673     /**
1674      * Configure the environment to make periodic calls to a {@link
1675      * ProgressListener} to provide feedback on replication stream sync-up.
1676      * The ProgressListener.progress() method is called at different stages of
1677      * the syncup process. See {@link SyncupProgress} for information about
1678      * those stages.
1679      * <p>
1680      * When using progress listeners, review the information at {@link
1681      * ProgressListener#progress} to avoid any unintended disruption to
1682      * replication stream syncup.
1683      * @param progressListener The ProgressListener to callback during
1684      * environment instantiation (syncup).
1685      * @see <a href="{@docRoot}/../ReplicationGuide/progoverviewlifecycle.html"
1686      * target="_top">Replication Group Life Cycle</a>
1687      * @since 5.0
1688      */
setSyncupProgressListener(final ProgressListener<SyncupProgress> progressListener)1689     public ReplicationConfig setSyncupProgressListener
1690         (final ProgressListener<SyncupProgress> progressListener) {
1691         setSyncupProgressListenerVoid(progressListener);
1692         return this;
1693     }
1694 
1695     /**
1696      * @hidden
1697      * The void return setter for use by Bean editors.
1698      */
setSyncupProgressListenerVoid(final ProgressListener<SyncupProgress> progressListener)1699     public void setSyncupProgressListenerVoid
1700         (final ProgressListener<SyncupProgress> progressListener) {
1701         this.syncupProgressListener = progressListener;
1702     }
1703 
1704     /**
1705      * Return the ProgressListener to be used at this environment startup.
1706      */
getSyncupProgressListener()1707     public ProgressListener<SyncupProgress> getSyncupProgressListener() {
1708         return syncupProgressListener;
1709     }
1710 
1711     /**
1712      * @hidden
1713      * Installs a callback to be notified when JE is about to modify previously
1714      * written log files.
1715      */
setLogFileRewriteListener(final LogFileRewriteListener listener)1716     public ReplicationConfig setLogFileRewriteListener
1717         (final LogFileRewriteListener listener) {
1718         setLogFileRewriteListenerVoid(listener);
1719         return this;
1720     }
1721 
1722     /**
1723      * @hidden
1724      * The void return setter for use by Bean editors.
1725      */
setLogFileRewriteListenerVoid(final LogFileRewriteListener l)1726     public void setLogFileRewriteListenerVoid(final LogFileRewriteListener l) {
1727         logRewriteListener = l;
1728     }
1729 
1730     /** @hidden */
getLogFileRewriteListener()1731     public LogFileRewriteListener getLogFileRewriteListener() {
1732         return logRewriteListener;
1733     }
1734 
1735     /**
1736      * @hidden
1737      * For internal use only.
1738      *
1739      * Performs the checks need to ensure that this is a valid replicated
1740      * environment configuration. This method must only be invoked after all
1741      * the appropriate fields are set.
1742      */
verify()1743     public void verify() throws IllegalArgumentException {
1744         if ((getGroupName() == null) || "".equals(getGroupName())) {
1745             throw new IllegalArgumentException("Missing group name");
1746         }
1747 
1748         if ((getNodeName() == null) || "".equals(getNodeName())){
1749             throw new IllegalArgumentException("Missing node name");
1750         }
1751 
1752         if ((getNodeHostPort() == null) || "".equals(getNodeHostPort())) {
1753             throw new IllegalArgumentException("Missing node host");
1754         }
1755     }
1756 }
1757