atomic-storage: remove type dependency at segment level I/O
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / DatastoreContext.java
1 /*
2  * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.datastore;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
13 import akka.util.Timeout;
14 import com.google.common.annotations.VisibleForTesting;
15 import java.util.Set;
16 import java.util.concurrent.ConcurrentHashMap;
17 import java.util.concurrent.TimeUnit;
18 import org.apache.commons.text.WordUtils;
19 import org.opendaylight.controller.cluster.access.client.AbstractClientConnection;
20 import org.opendaylight.controller.cluster.access.client.ClientActorConfig;
21 import org.opendaylight.controller.cluster.common.actor.AkkaConfigurationReader;
22 import org.opendaylight.controller.cluster.common.actor.FileAkkaConfigurationReader;
23 import org.opendaylight.controller.cluster.raft.ConfigParams;
24 import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl;
25 import org.opendaylight.controller.cluster.raft.PeerAddressResolver;
26 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
27 import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStoreConfigProperties;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31 import scala.concurrent.duration.FiniteDuration;
32
33 /**
34  * Contains contextual data for a data store.
35  *
36  * @author Thomas Pantelis
37  */
38 // Non-final for mocking
39 public class DatastoreContext implements ClientActorConfig {
40     public static final String METRICS_DOMAIN = "org.opendaylight.controller.cluster.datastore";
41
42     public static final FiniteDuration DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT = FiniteDuration.create(10,
43         TimeUnit.MINUTES);
44     public static final int DEFAULT_OPERATION_TIMEOUT_IN_MS = 5000;
45     public static final int DEFAULT_SHARD_TX_COMMIT_TIMEOUT_IN_SECONDS = 30;
46     public static final int DEFAULT_JOURNAL_RECOVERY_BATCH_SIZE = 1;
47     public static final int DEFAULT_SNAPSHOT_BATCH_COUNT = 20000;
48     public static final int DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS = 500;
49     public static final int DEFAULT_ISOLATED_LEADER_CHECK_INTERVAL_IN_MILLIS =
50             DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS * 10;
51     public static final int DEFAULT_SHARD_TX_COMMIT_QUEUE_CAPACITY = 50000;
52     public static final Timeout DEFAULT_SHARD_INITIALIZATION_TIMEOUT = new Timeout(5, TimeUnit.MINUTES);
53     public static final Timeout DEFAULT_SHARD_LEADER_ELECTION_TIMEOUT = new Timeout(30, TimeUnit.SECONDS);
54     public static final boolean DEFAULT_PERSISTENT = true;
55     public static final FileAkkaConfigurationReader DEFAULT_CONFIGURATION_READER = new FileAkkaConfigurationReader();
56     public static final int DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE = 12;
57     public static final int DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR = 2;
58     public static final int DEFAULT_SHARD_CANDIDATE_ELECTION_TIMEOUT_DIVISOR = 1;
59     public static final int DEFAULT_TX_CREATION_INITIAL_RATE_LIMIT = 100;
60     public static final String UNKNOWN_DATA_STORE_TYPE = "unknown";
61     public static final int DEFAULT_SHARD_BATCHED_MODIFICATION_COUNT = 1000;
62     public static final long DEFAULT_SHARD_COMMIT_QUEUE_EXPIRY_TIMEOUT_IN_MS =
63             TimeUnit.MILLISECONDS.convert(2, TimeUnit.MINUTES);
64     public static final int DEFAULT_MAX_MESSAGE_SLICE_SIZE = 2048 * 1000; // 2MB
65     public static final int DEFAULT_INITIAL_PAYLOAD_SERIALIZED_BUFFER_CAPACITY = 512;
66
67     public static final long DEFAULT_SYNC_INDEX_THRESHOLD = 10;
68
69     private static final Logger LOG = LoggerFactory.getLogger(DatastoreContext.class);
70
71     private static final Set<String> GLOBAL_DATASTORE_NAMES = ConcurrentHashMap.newKeySet();
72
73     private final DefaultConfigParamsImpl raftConfig = new DefaultConfigParamsImpl();
74
75     private InMemoryDOMDataStoreConfigProperties dataStoreProperties;
76     private FiniteDuration shardTransactionIdleTimeout = DatastoreContext.DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT;
77     private long operationTimeoutInMillis = DEFAULT_OPERATION_TIMEOUT_IN_MS;
78     private String dataStoreMXBeanType;
79     private int shardTransactionCommitTimeoutInSeconds = DEFAULT_SHARD_TX_COMMIT_TIMEOUT_IN_SECONDS;
80     private int shardTransactionCommitQueueCapacity = DEFAULT_SHARD_TX_COMMIT_QUEUE_CAPACITY;
81     private Timeout shardInitializationTimeout = DEFAULT_SHARD_INITIALIZATION_TIMEOUT;
82     private Timeout shardLeaderElectionTimeout = DEFAULT_SHARD_LEADER_ELECTION_TIMEOUT;
83     private boolean persistent = DEFAULT_PERSISTENT;
84     private AkkaConfigurationReader configurationReader = DEFAULT_CONFIGURATION_READER;
85     private long transactionCreationInitialRateLimit = DEFAULT_TX_CREATION_INITIAL_RATE_LIMIT;
86     private String dataStoreName = UNKNOWN_DATA_STORE_TYPE;
87     private LogicalDatastoreType logicalStoreType = LogicalDatastoreType.OPERATIONAL;
88     private YangInstanceIdentifier storeRoot = YangInstanceIdentifier.empty();
89     private int shardBatchedModificationCount = DEFAULT_SHARD_BATCHED_MODIFICATION_COUNT;
90     private boolean writeOnlyTransactionOptimizationsEnabled = true;
91     private long shardCommitQueueExpiryTimeoutInMillis = DEFAULT_SHARD_COMMIT_QUEUE_EXPIRY_TIMEOUT_IN_MS;
92     private boolean useTellBasedProtocol = false;
93     private boolean transactionDebugContextEnabled = false;
94     private String shardManagerPersistenceId;
95     private int maximumMessageSliceSize = DEFAULT_MAX_MESSAGE_SLICE_SIZE;
96     private long backendAlivenessTimerInterval = AbstractClientConnection.DEFAULT_BACKEND_ALIVE_TIMEOUT_NANOS;
97     private long requestTimeout = AbstractClientConnection.DEFAULT_REQUEST_TIMEOUT_NANOS;
98     private long noProgressTimeout = AbstractClientConnection.DEFAULT_NO_PROGRESS_TIMEOUT_NANOS;
99     private int initialPayloadSerializedBufferCapacity = DEFAULT_INITIAL_PAYLOAD_SERIALIZED_BUFFER_CAPACITY;
100
101     public static Set<String> getGlobalDatastoreNames() {
102         return GLOBAL_DATASTORE_NAMES;
103     }
104
105     DatastoreContext() {
106         setShardJournalRecoveryLogBatchSize(DEFAULT_JOURNAL_RECOVERY_BATCH_SIZE);
107         setSnapshotBatchCount(DEFAULT_SNAPSHOT_BATCH_COUNT);
108         setHeartbeatInterval(DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS);
109         setIsolatedLeaderCheckInterval(DEFAULT_ISOLATED_LEADER_CHECK_INTERVAL_IN_MILLIS);
110         setSnapshotDataThresholdPercentage(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE);
111         setElectionTimeoutFactor(DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR);
112         setCandidateElectionTimeoutDivisor(DEFAULT_SHARD_CANDIDATE_ELECTION_TIMEOUT_DIVISOR);
113         setSyncIndexThreshold(DEFAULT_SYNC_INDEX_THRESHOLD);
114         setMaximumMessageSliceSize(DEFAULT_MAX_MESSAGE_SLICE_SIZE);
115     }
116
117     private DatastoreContext(final DatastoreContext other) {
118         this.dataStoreProperties = other.dataStoreProperties;
119         this.shardTransactionIdleTimeout = other.shardTransactionIdleTimeout;
120         this.operationTimeoutInMillis = other.operationTimeoutInMillis;
121         this.dataStoreMXBeanType = other.dataStoreMXBeanType;
122         this.shardTransactionCommitTimeoutInSeconds = other.shardTransactionCommitTimeoutInSeconds;
123         this.shardTransactionCommitQueueCapacity = other.shardTransactionCommitQueueCapacity;
124         this.shardInitializationTimeout = other.shardInitializationTimeout;
125         this.shardLeaderElectionTimeout = other.shardLeaderElectionTimeout;
126         this.persistent = other.persistent;
127         this.configurationReader = other.configurationReader;
128         this.transactionCreationInitialRateLimit = other.transactionCreationInitialRateLimit;
129         this.dataStoreName = other.dataStoreName;
130         this.logicalStoreType = other.logicalStoreType;
131         this.storeRoot = other.storeRoot;
132         this.shardBatchedModificationCount = other.shardBatchedModificationCount;
133         this.writeOnlyTransactionOptimizationsEnabled = other.writeOnlyTransactionOptimizationsEnabled;
134         this.shardCommitQueueExpiryTimeoutInMillis = other.shardCommitQueueExpiryTimeoutInMillis;
135         this.transactionDebugContextEnabled = other.transactionDebugContextEnabled;
136         this.shardManagerPersistenceId = other.shardManagerPersistenceId;
137         this.useTellBasedProtocol = other.useTellBasedProtocol;
138         this.backendAlivenessTimerInterval = other.backendAlivenessTimerInterval;
139         this.requestTimeout = other.requestTimeout;
140         this.noProgressTimeout = other.noProgressTimeout;
141         this.initialPayloadSerializedBufferCapacity = other.initialPayloadSerializedBufferCapacity;
142
143         setShardJournalRecoveryLogBatchSize(other.raftConfig.getJournalRecoveryLogBatchSize());
144         setSnapshotBatchCount(other.raftConfig.getSnapshotBatchCount());
145         setHeartbeatInterval(other.raftConfig.getHeartBeatInterval().toMillis());
146         setIsolatedLeaderCheckInterval(other.raftConfig.getIsolatedCheckIntervalInMillis());
147         setSnapshotDataThresholdPercentage(other.raftConfig.getSnapshotDataThresholdPercentage());
148         setElectionTimeoutFactor(other.raftConfig.getElectionTimeoutFactor());
149         setCandidateElectionTimeoutDivisor(other.raftConfig.getCandidateElectionTimeoutDivisor());
150         setCustomRaftPolicyImplementation(other.raftConfig.getCustomRaftPolicyImplementationClass());
151         setMaximumMessageSliceSize(other.getMaximumMessageSliceSize());
152         setShardSnapshotChunkSize(other.raftConfig.getSnapshotChunkSize());
153         setPeerAddressResolver(other.raftConfig.getPeerAddressResolver());
154         setTempFileDirectory(other.getTempFileDirectory());
155         setFileBackedStreamingThreshold(other.getFileBackedStreamingThreshold());
156         setSyncIndexThreshold(other.raftConfig.getSyncIndexThreshold());
157     }
158
159     public static Builder newBuilder() {
160         return new Builder(new DatastoreContext());
161     }
162
163     public static Builder newBuilderFrom(final DatastoreContext context) {
164         return new Builder(new DatastoreContext(context));
165     }
166
167     public InMemoryDOMDataStoreConfigProperties getDataStoreProperties() {
168         return dataStoreProperties;
169     }
170
171     public FiniteDuration getShardTransactionIdleTimeout() {
172         return shardTransactionIdleTimeout;
173     }
174
175     public String getDataStoreMXBeanType() {
176         return dataStoreMXBeanType;
177     }
178
179     public long getOperationTimeoutInMillis() {
180         return operationTimeoutInMillis;
181     }
182
183     public ConfigParams getShardRaftConfig() {
184         return raftConfig;
185     }
186
187     public int getShardTransactionCommitTimeoutInSeconds() {
188         return shardTransactionCommitTimeoutInSeconds;
189     }
190
191     public int getShardTransactionCommitQueueCapacity() {
192         return shardTransactionCommitQueueCapacity;
193     }
194
195     public Timeout getShardInitializationTimeout() {
196         return shardInitializationTimeout;
197     }
198
199     public Timeout getShardLeaderElectionTimeout() {
200         return shardLeaderElectionTimeout;
201     }
202
203     public boolean isPersistent() {
204         return persistent;
205     }
206
207     public AkkaConfigurationReader getConfigurationReader() {
208         return configurationReader;
209     }
210
211     public long getShardElectionTimeoutFactor() {
212         return raftConfig.getElectionTimeoutFactor();
213     }
214
215     public String getDataStoreName() {
216         return dataStoreName;
217     }
218
219     public LogicalDatastoreType getLogicalStoreType() {
220         return logicalStoreType;
221     }
222
223     public YangInstanceIdentifier getStoreRoot() {
224         return storeRoot;
225     }
226
227     public long getTransactionCreationInitialRateLimit() {
228         return transactionCreationInitialRateLimit;
229     }
230
231     public String getShardManagerPersistenceId() {
232         return shardManagerPersistenceId;
233     }
234
235     @Override
236     public String getTempFileDirectory() {
237         return raftConfig.getTempFileDirectory();
238     }
239
240     private void setTempFileDirectory(final String tempFileDirectory) {
241         raftConfig.setTempFileDirectory(tempFileDirectory);
242     }
243
244     @Override
245     public int getFileBackedStreamingThreshold() {
246         return raftConfig.getFileBackedStreamingThreshold();
247     }
248
249     private void setFileBackedStreamingThreshold(final int fileBackedStreamingThreshold) {
250         raftConfig.setFileBackedStreamingThreshold(fileBackedStreamingThreshold);
251     }
252
253     private void setPeerAddressResolver(final PeerAddressResolver resolver) {
254         raftConfig.setPeerAddressResolver(resolver);
255     }
256
257     private void setHeartbeatInterval(final long shardHeartbeatIntervalInMillis) {
258         raftConfig.setHeartBeatInterval(new FiniteDuration(shardHeartbeatIntervalInMillis,
259                 TimeUnit.MILLISECONDS));
260     }
261
262     private void setShardJournalRecoveryLogBatchSize(final int shardJournalRecoveryLogBatchSize) {
263         raftConfig.setJournalRecoveryLogBatchSize(shardJournalRecoveryLogBatchSize);
264     }
265
266
267     private void setIsolatedLeaderCheckInterval(final long shardIsolatedLeaderCheckIntervalInMillis) {
268         raftConfig.setIsolatedLeaderCheckInterval(
269                 new FiniteDuration(shardIsolatedLeaderCheckIntervalInMillis, TimeUnit.MILLISECONDS));
270     }
271
272     private void setElectionTimeoutFactor(final long shardElectionTimeoutFactor) {
273         raftConfig.setElectionTimeoutFactor(shardElectionTimeoutFactor);
274     }
275
276     private void setCandidateElectionTimeoutDivisor(final long candidateElectionTimeoutDivisor) {
277         raftConfig.setCandidateElectionTimeoutDivisor(candidateElectionTimeoutDivisor);
278     }
279
280     private void setCustomRaftPolicyImplementation(final String customRaftPolicyImplementation) {
281         raftConfig.setCustomRaftPolicyImplementationClass(customRaftPolicyImplementation);
282     }
283
284     private void setSnapshotDataThresholdPercentage(final int shardSnapshotDataThresholdPercentage) {
285         checkArgument(shardSnapshotDataThresholdPercentage >= 0 && shardSnapshotDataThresholdPercentage <= 100);
286         raftConfig.setSnapshotDataThresholdPercentage(shardSnapshotDataThresholdPercentage);
287     }
288
289     private void setSnapshotBatchCount(final long shardSnapshotBatchCount) {
290         raftConfig.setSnapshotBatchCount(shardSnapshotBatchCount);
291     }
292
293     @Deprecated
294     private void setShardSnapshotChunkSize(final int shardSnapshotChunkSize) {
295         // We'll honor the shardSnapshotChunkSize setting for backwards compatibility but only if it doesn't exceed
296         // maximumMessageSliceSize.
297         if (shardSnapshotChunkSize < maximumMessageSliceSize) {
298             raftConfig.setSnapshotChunkSize(shardSnapshotChunkSize);
299         }
300     }
301
302     private void setMaximumMessageSliceSize(final int maximumMessageSliceSize) {
303         raftConfig.setSnapshotChunkSize(maximumMessageSliceSize);
304         this.maximumMessageSliceSize = maximumMessageSliceSize;
305     }
306
307     private void setSyncIndexThreshold(final long syncIndexThreshold) {
308         raftConfig.setSyncIndexThreshold(syncIndexThreshold);
309     }
310
311     public int getShardBatchedModificationCount() {
312         return shardBatchedModificationCount;
313     }
314
315     public boolean isWriteOnlyTransactionOptimizationsEnabled() {
316         return writeOnlyTransactionOptimizationsEnabled;
317     }
318
319     public long getShardCommitQueueExpiryTimeoutInMillis() {
320         return shardCommitQueueExpiryTimeoutInMillis;
321     }
322
323     public boolean isTransactionDebugContextEnabled() {
324         return transactionDebugContextEnabled;
325     }
326
327     public boolean isUseTellBasedProtocol() {
328         return useTellBasedProtocol;
329     }
330
331     @Override
332     public int getMaximumMessageSliceSize() {
333         return maximumMessageSliceSize;
334     }
335
336     @Override
337     public long getBackendAlivenessTimerInterval() {
338         return backendAlivenessTimerInterval;
339     }
340
341     @Override
342     public long getRequestTimeout() {
343         return requestTimeout;
344     }
345
346     @Override
347     public long getNoProgressTimeout() {
348         return noProgressTimeout;
349     }
350
351     public int getInitialPayloadSerializedBufferCapacity() {
352         return initialPayloadSerializedBufferCapacity;
353     }
354
355     public static class Builder implements org.opendaylight.yangtools.concepts.Builder<DatastoreContext> {
356         private final DatastoreContext datastoreContext;
357         private int maxShardDataChangeExecutorPoolSize =
358                 InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_CHANGE_EXECUTOR_POOL_SIZE;
359         private int maxShardDataChangeExecutorQueueSize =
360                 InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_CHANGE_EXECUTOR_QUEUE_SIZE;
361         private int maxShardDataChangeListenerQueueSize =
362                 InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_CHANGE_LISTENER_QUEUE_SIZE;
363         private int maxShardDataStoreExecutorQueueSize =
364                 InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_STORE_EXECUTOR_QUEUE_SIZE;
365
366         Builder(final DatastoreContext datastoreContext) {
367             this.datastoreContext = datastoreContext;
368
369             if (datastoreContext.getDataStoreProperties() != null) {
370                 maxShardDataChangeExecutorPoolSize =
371                         datastoreContext.getDataStoreProperties().getMaxDataChangeExecutorPoolSize();
372                 maxShardDataChangeExecutorQueueSize =
373                         datastoreContext.getDataStoreProperties().getMaxDataChangeExecutorQueueSize();
374                 maxShardDataChangeListenerQueueSize =
375                         datastoreContext.getDataStoreProperties().getMaxDataChangeListenerQueueSize();
376                 maxShardDataStoreExecutorQueueSize =
377                         datastoreContext.getDataStoreProperties().getMaxDataStoreExecutorQueueSize();
378             }
379         }
380
381         public Builder boundedMailboxCapacity(final int boundedMailboxCapacity) {
382             // TODO - this is defined in the yang DataStoreProperties but not currently used.
383             return this;
384         }
385
386         public Builder enableMetricCapture(final boolean enableMetricCapture) {
387             // TODO - this is defined in the yang DataStoreProperties but not currently used.
388             return this;
389         }
390
391
392         public Builder shardTransactionIdleTimeout(final long timeout, final TimeUnit unit) {
393             datastoreContext.shardTransactionIdleTimeout = FiniteDuration.create(timeout, unit);
394             return this;
395         }
396
397         public Builder shardTransactionIdleTimeoutInMinutes(final long timeout) {
398             return shardTransactionIdleTimeout(timeout, TimeUnit.MINUTES);
399         }
400
401         public Builder operationTimeoutInSeconds(final int operationTimeoutInSeconds) {
402             datastoreContext.operationTimeoutInMillis = TimeUnit.SECONDS.toMillis(operationTimeoutInSeconds);
403             return this;
404         }
405
406         public Builder operationTimeoutInMillis(final long operationTimeoutInMillis) {
407             datastoreContext.operationTimeoutInMillis = operationTimeoutInMillis;
408             return this;
409         }
410
411         public Builder dataStoreMXBeanType(final String dataStoreMXBeanType) {
412             datastoreContext.dataStoreMXBeanType = dataStoreMXBeanType;
413             return this;
414         }
415
416         public Builder shardTransactionCommitTimeoutInSeconds(final int shardTransactionCommitTimeoutInSeconds) {
417             datastoreContext.shardTransactionCommitTimeoutInSeconds = shardTransactionCommitTimeoutInSeconds;
418             return this;
419         }
420
421         public Builder shardJournalRecoveryLogBatchSize(final int shardJournalRecoveryLogBatchSize) {
422             datastoreContext.setShardJournalRecoveryLogBatchSize(shardJournalRecoveryLogBatchSize);
423             return this;
424         }
425
426         public Builder shardSnapshotBatchCount(final int shardSnapshotBatchCount) {
427             datastoreContext.setSnapshotBatchCount(shardSnapshotBatchCount);
428             return this;
429         }
430
431         public Builder shardSnapshotDataThresholdPercentage(final int shardSnapshotDataThresholdPercentage) {
432             datastoreContext.setSnapshotDataThresholdPercentage(shardSnapshotDataThresholdPercentage);
433             return this;
434         }
435
436         public Builder shardHeartbeatIntervalInMillis(final int shardHeartbeatIntervalInMillis) {
437             datastoreContext.setHeartbeatInterval(shardHeartbeatIntervalInMillis);
438             return this;
439         }
440
441         public Builder shardTransactionCommitQueueCapacity(final int shardTransactionCommitQueueCapacity) {
442             datastoreContext.shardTransactionCommitQueueCapacity = shardTransactionCommitQueueCapacity;
443             return this;
444         }
445
446         public Builder shardInitializationTimeout(final long timeout, final TimeUnit unit) {
447             datastoreContext.shardInitializationTimeout = new Timeout(timeout, unit);
448             return this;
449         }
450
451         public Builder shardInitializationTimeoutInSeconds(final long timeout) {
452             return shardInitializationTimeout(timeout, TimeUnit.SECONDS);
453         }
454
455         public Builder shardLeaderElectionTimeout(final long timeout, final TimeUnit unit) {
456             datastoreContext.shardLeaderElectionTimeout = new Timeout(timeout, unit);
457             return this;
458         }
459
460         public Builder shardLeaderElectionTimeoutInSeconds(final long timeout) {
461             return shardLeaderElectionTimeout(timeout, TimeUnit.SECONDS);
462         }
463
464         public Builder configurationReader(final AkkaConfigurationReader configurationReader) {
465             datastoreContext.configurationReader = configurationReader;
466             return this;
467         }
468
469         public Builder persistent(final boolean persistent) {
470             datastoreContext.persistent = persistent;
471             return this;
472         }
473
474         public Builder shardIsolatedLeaderCheckIntervalInMillis(final int shardIsolatedLeaderCheckIntervalInMillis) {
475             datastoreContext.setIsolatedLeaderCheckInterval(shardIsolatedLeaderCheckIntervalInMillis);
476             return this;
477         }
478
479         public Builder shardElectionTimeoutFactor(final long shardElectionTimeoutFactor) {
480             datastoreContext.setElectionTimeoutFactor(shardElectionTimeoutFactor);
481             return this;
482         }
483
484         public Builder shardCandidateElectionTimeoutDivisor(final long candidateElectionTimeoutDivisor) {
485             datastoreContext.setCandidateElectionTimeoutDivisor(candidateElectionTimeoutDivisor);
486             return this;
487         }
488
489         public Builder transactionCreationInitialRateLimit(final long initialRateLimit) {
490             datastoreContext.transactionCreationInitialRateLimit = initialRateLimit;
491             return this;
492         }
493
494         public Builder logicalStoreType(final LogicalDatastoreType logicalStoreType) {
495             datastoreContext.logicalStoreType = requireNonNull(logicalStoreType);
496
497             // Retain compatible naming
498             switch (logicalStoreType) {
499                 case CONFIGURATION:
500                     dataStoreName("config");
501                     break;
502                 case OPERATIONAL:
503                     dataStoreName("operational");
504                     break;
505                 default:
506                     dataStoreName(logicalStoreType.name());
507             }
508
509             return this;
510         }
511
512         public Builder storeRoot(final YangInstanceIdentifier storeRoot) {
513             datastoreContext.storeRoot = storeRoot;
514             return this;
515         }
516
517         public Builder dataStoreName(final String dataStoreName) {
518             datastoreContext.dataStoreName = requireNonNull(dataStoreName);
519             datastoreContext.dataStoreMXBeanType = "Distributed" + WordUtils.capitalize(dataStoreName) + "Datastore";
520             return this;
521         }
522
523         public Builder shardBatchedModificationCount(final int shardBatchedModificationCount) {
524             datastoreContext.shardBatchedModificationCount = shardBatchedModificationCount;
525             return this;
526         }
527
528         public Builder writeOnlyTransactionOptimizationsEnabled(final boolean value) {
529             datastoreContext.writeOnlyTransactionOptimizationsEnabled = value;
530             return this;
531         }
532
533         public Builder shardCommitQueueExpiryTimeoutInMillis(final long value) {
534             datastoreContext.shardCommitQueueExpiryTimeoutInMillis = value;
535             return this;
536         }
537
538         public Builder shardCommitQueueExpiryTimeoutInSeconds(final long value) {
539             datastoreContext.shardCommitQueueExpiryTimeoutInMillis = TimeUnit.MILLISECONDS.convert(
540                     value, TimeUnit.SECONDS);
541             return this;
542         }
543
544         public Builder transactionDebugContextEnabled(final boolean value) {
545             datastoreContext.transactionDebugContextEnabled = value;
546             return this;
547         }
548
549         public Builder maxShardDataChangeExecutorPoolSize(final int newMaxShardDataChangeExecutorPoolSize) {
550             this.maxShardDataChangeExecutorPoolSize = newMaxShardDataChangeExecutorPoolSize;
551             return this;
552         }
553
554         public Builder maxShardDataChangeExecutorQueueSize(final int newMaxShardDataChangeExecutorQueueSize) {
555             this.maxShardDataChangeExecutorQueueSize = newMaxShardDataChangeExecutorQueueSize;
556             return this;
557         }
558
559         public Builder maxShardDataChangeListenerQueueSize(final int newMaxShardDataChangeListenerQueueSize) {
560             this.maxShardDataChangeListenerQueueSize = newMaxShardDataChangeListenerQueueSize;
561             return this;
562         }
563
564         public Builder maxShardDataStoreExecutorQueueSize(final int newMaxShardDataStoreExecutorQueueSize) {
565             this.maxShardDataStoreExecutorQueueSize = newMaxShardDataStoreExecutorQueueSize;
566             return this;
567         }
568
569         public Builder useTellBasedProtocol(final boolean value) {
570             datastoreContext.useTellBasedProtocol = value;
571             return this;
572         }
573
574         /**
575          * For unit tests only.
576          */
577         @VisibleForTesting
578         public Builder shardManagerPersistenceId(final String id) {
579             datastoreContext.shardManagerPersistenceId = id;
580             return this;
581         }
582
583         public Builder customRaftPolicyImplementation(final String customRaftPolicyImplementation) {
584             datastoreContext.setCustomRaftPolicyImplementation(customRaftPolicyImplementation);
585             return this;
586         }
587
588         @Deprecated
589         public Builder shardSnapshotChunkSize(final int shardSnapshotChunkSize) {
590             LOG.warn("The shard-snapshot-chunk-size configuration parameter is deprecated - "
591                     + "use maximum-message-slice-size instead");
592             datastoreContext.setShardSnapshotChunkSize(shardSnapshotChunkSize);
593             return this;
594         }
595
596         public Builder maximumMessageSliceSize(final int maximumMessageSliceSize) {
597             datastoreContext.setMaximumMessageSliceSize(maximumMessageSliceSize);
598             return this;
599         }
600
601         public Builder shardPeerAddressResolver(final PeerAddressResolver resolver) {
602             datastoreContext.setPeerAddressResolver(resolver);
603             return this;
604         }
605
606         public Builder tempFileDirectory(final String tempFileDirectory) {
607             datastoreContext.setTempFileDirectory(tempFileDirectory);
608             return this;
609         }
610
611         public Builder fileBackedStreamingThresholdInMegabytes(final int fileBackedStreamingThreshold) {
612             datastoreContext.setFileBackedStreamingThreshold(fileBackedStreamingThreshold * ConfigParams.MEGABYTE);
613             return this;
614         }
615
616         public Builder syncIndexThreshold(final long syncIndexThreshold) {
617             datastoreContext.setSyncIndexThreshold(syncIndexThreshold);
618             return this;
619         }
620
621         public Builder backendAlivenessTimerIntervalInSeconds(final long interval) {
622             datastoreContext.backendAlivenessTimerInterval = TimeUnit.SECONDS.toNanos(interval);
623             return this;
624         }
625
626         public Builder frontendRequestTimeoutInSeconds(final long timeout) {
627             datastoreContext.requestTimeout = TimeUnit.SECONDS.toNanos(timeout);
628             return this;
629         }
630
631         public Builder frontendNoProgressTimeoutInSeconds(final long timeout) {
632             datastoreContext.noProgressTimeout = TimeUnit.SECONDS.toNanos(timeout);
633             return this;
634         }
635
636         public Builder initialPayloadSerializedBufferCapacity(final int capacity) {
637             datastoreContext.initialPayloadSerializedBufferCapacity = capacity;
638             return this;
639         }
640
641         @Override
642         public DatastoreContext build() {
643             datastoreContext.dataStoreProperties = InMemoryDOMDataStoreConfigProperties.builder()
644                     .maxDataChangeExecutorPoolSize(maxShardDataChangeExecutorPoolSize)
645                     .maxDataChangeExecutorQueueSize(maxShardDataChangeExecutorQueueSize)
646                     .maxDataChangeListenerQueueSize(maxShardDataChangeListenerQueueSize)
647                     .maxDataStoreExecutorQueueSize(maxShardDataStoreExecutorQueueSize)
648                     .build();
649
650             if (datastoreContext.dataStoreName != null) {
651                 GLOBAL_DATASTORE_NAMES.add(datastoreContext.dataStoreName);
652             }
653
654             return datastoreContext;
655         }
656     }
657 }