BUG-5280: split DistributedDataStore
[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
9 package org.opendaylight.controller.cluster.datastore;
10
11 import akka.util.Timeout;
12 import com.google.common.annotations.VisibleForTesting;
13 import com.google.common.base.Preconditions;
14 import com.google.common.collect.Sets;
15 import java.util.Set;
16 import java.util.concurrent.TimeUnit;
17 import org.apache.commons.lang3.text.WordUtils;
18 import org.opendaylight.controller.cluster.common.actor.AkkaConfigurationReader;
19 import org.opendaylight.controller.cluster.common.actor.FileAkkaConfigurationReader;
20 import org.opendaylight.controller.cluster.raft.ConfigParams;
21 import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl;
22 import org.opendaylight.controller.cluster.raft.PeerAddressResolver;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreConfigProperties;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
26 import scala.concurrent.duration.Duration;
27 import scala.concurrent.duration.FiniteDuration;
28
29 /**
30  * Contains contextual data for a data store.
31  *
32  * @author Thomas Pantelis
33  */
34 public class DatastoreContext {
35     public static final String METRICS_DOMAIN = "org.opendaylight.controller.cluster.datastore";
36
37     public static final Duration DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT = Duration.create(10, TimeUnit.MINUTES);
38     public static final int DEFAULT_OPERATION_TIMEOUT_IN_MS = 5000;
39     public static final int DEFAULT_SHARD_TX_COMMIT_TIMEOUT_IN_SECONDS = 30;
40     public static final int DEFAULT_JOURNAL_RECOVERY_BATCH_SIZE = 1;
41     public static final int DEFAULT_SNAPSHOT_BATCH_COUNT = 20000;
42     public static final int DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS = 500;
43     public static final int DEFAULT_ISOLATED_LEADER_CHECK_INTERVAL_IN_MILLIS =
44             DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS * 10;
45     public static final int DEFAULT_SHARD_TX_COMMIT_QUEUE_CAPACITY = 50000;
46     public static final Timeout DEFAULT_SHARD_INITIALIZATION_TIMEOUT = new Timeout(5, TimeUnit.MINUTES);
47     public static final Timeout DEFAULT_SHARD_LEADER_ELECTION_TIMEOUT = new Timeout(30, TimeUnit.SECONDS);
48     public static final boolean DEFAULT_PERSISTENT = true;
49     public static final FileAkkaConfigurationReader DEFAULT_CONFIGURATION_READER = new FileAkkaConfigurationReader();
50     public static final int DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE = 12;
51     public static final int DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR = 2;
52     public static final int DEFAULT_TX_CREATION_INITIAL_RATE_LIMIT = 100;
53     public static final String UNKNOWN_DATA_STORE_TYPE = "unknown";
54     public static final int DEFAULT_SHARD_BATCHED_MODIFICATION_COUNT = 1000;
55     public static final long DEFAULT_SHARD_COMMIT_QUEUE_EXPIRY_TIMEOUT_IN_MS =
56             TimeUnit.MILLISECONDS.convert(2, TimeUnit.MINUTES);
57     public static final int DEFAULT_SHARD_SNAPSHOT_CHUNK_SIZE = 2048000;
58
59     private static final Set<String> GLOBAL_DATASTORE_NAMES = Sets.newConcurrentHashSet();
60
61     private InMemoryDOMDataStoreConfigProperties dataStoreProperties;
62     private Duration shardTransactionIdleTimeout = DatastoreContext.DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT;
63     private long operationTimeoutInMillis = DEFAULT_OPERATION_TIMEOUT_IN_MS;
64     private String dataStoreMXBeanType;
65     private int shardTransactionCommitTimeoutInSeconds = DEFAULT_SHARD_TX_COMMIT_TIMEOUT_IN_SECONDS;
66     private int shardTransactionCommitQueueCapacity = DEFAULT_SHARD_TX_COMMIT_QUEUE_CAPACITY;
67     private Timeout shardInitializationTimeout = DEFAULT_SHARD_INITIALIZATION_TIMEOUT;
68     private Timeout shardLeaderElectionTimeout = DEFAULT_SHARD_LEADER_ELECTION_TIMEOUT;
69     private boolean persistent = DEFAULT_PERSISTENT;
70     private AkkaConfigurationReader configurationReader = DEFAULT_CONFIGURATION_READER;
71     private long transactionCreationInitialRateLimit = DEFAULT_TX_CREATION_INITIAL_RATE_LIMIT;
72     private final DefaultConfigParamsImpl raftConfig = new DefaultConfigParamsImpl();
73     private String dataStoreName = UNKNOWN_DATA_STORE_TYPE;
74     private LogicalDatastoreType logicalStoreType = LogicalDatastoreType.OPERATIONAL;
75     private YangInstanceIdentifier storeRoot = YangInstanceIdentifier.EMPTY;
76     private int shardBatchedModificationCount = DEFAULT_SHARD_BATCHED_MODIFICATION_COUNT;
77     private boolean writeOnlyTransactionOptimizationsEnabled = true;
78     private long shardCommitQueueExpiryTimeoutInMillis = DEFAULT_SHARD_COMMIT_QUEUE_EXPIRY_TIMEOUT_IN_MS;
79     private boolean useTellBasedProtocol = false;
80     private boolean transactionDebugContextEnabled = false;
81     private String shardManagerPersistenceId;
82
83     public static Set<String> getGlobalDatastoreNames() {
84         return GLOBAL_DATASTORE_NAMES;
85     }
86
87     private DatastoreContext() {
88         setShardJournalRecoveryLogBatchSize(DEFAULT_JOURNAL_RECOVERY_BATCH_SIZE);
89         setSnapshotBatchCount(DEFAULT_SNAPSHOT_BATCH_COUNT);
90         setHeartbeatInterval(DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS);
91         setIsolatedLeaderCheckInterval(DEFAULT_ISOLATED_LEADER_CHECK_INTERVAL_IN_MILLIS);
92         setSnapshotDataThresholdPercentage(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE);
93         setElectionTimeoutFactor(DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR);
94         setShardSnapshotChunkSize(DEFAULT_SHARD_SNAPSHOT_CHUNK_SIZE);
95     }
96
97     private DatastoreContext(final DatastoreContext other) {
98         this.dataStoreProperties = other.dataStoreProperties;
99         this.shardTransactionIdleTimeout = other.shardTransactionIdleTimeout;
100         this.operationTimeoutInMillis = other.operationTimeoutInMillis;
101         this.dataStoreMXBeanType = other.dataStoreMXBeanType;
102         this.shardTransactionCommitTimeoutInSeconds = other.shardTransactionCommitTimeoutInSeconds;
103         this.shardTransactionCommitQueueCapacity = other.shardTransactionCommitQueueCapacity;
104         this.shardInitializationTimeout = other.shardInitializationTimeout;
105         this.shardLeaderElectionTimeout = other.shardLeaderElectionTimeout;
106         this.persistent = other.persistent;
107         this.configurationReader = other.configurationReader;
108         this.transactionCreationInitialRateLimit = other.transactionCreationInitialRateLimit;
109         this.dataStoreName = other.dataStoreName;
110         this.logicalStoreType = other.logicalStoreType;
111         this.storeRoot = other.storeRoot;
112         this.shardBatchedModificationCount = other.shardBatchedModificationCount;
113         this.writeOnlyTransactionOptimizationsEnabled = other.writeOnlyTransactionOptimizationsEnabled;
114         this.shardCommitQueueExpiryTimeoutInMillis = other.shardCommitQueueExpiryTimeoutInMillis;
115         this.transactionDebugContextEnabled = other.transactionDebugContextEnabled;
116         this.shardManagerPersistenceId = other.shardManagerPersistenceId;
117         this.useTellBasedProtocol = other.useTellBasedProtocol;
118
119         setShardJournalRecoveryLogBatchSize(other.raftConfig.getJournalRecoveryLogBatchSize());
120         setSnapshotBatchCount(other.raftConfig.getSnapshotBatchCount());
121         setHeartbeatInterval(other.raftConfig.getHeartBeatInterval().toMillis());
122         setIsolatedLeaderCheckInterval(other.raftConfig.getIsolatedCheckIntervalInMillis());
123         setSnapshotDataThresholdPercentage(other.raftConfig.getSnapshotDataThresholdPercentage());
124         setElectionTimeoutFactor(other.raftConfig.getElectionTimeoutFactor());
125         setCustomRaftPolicyImplementation(other.raftConfig.getCustomRaftPolicyImplementationClass());
126         setShardSnapshotChunkSize(other.raftConfig.getSnapshotChunkSize());
127         setPeerAddressResolver(other.raftConfig.getPeerAddressResolver());
128     }
129
130     public static Builder newBuilder() {
131         return new Builder(new DatastoreContext());
132     }
133
134     public static Builder newBuilderFrom(DatastoreContext context) {
135         return new Builder(new DatastoreContext(context));
136     }
137
138     public InMemoryDOMDataStoreConfigProperties getDataStoreProperties() {
139         return dataStoreProperties;
140     }
141
142     public Duration getShardTransactionIdleTimeout() {
143         return shardTransactionIdleTimeout;
144     }
145
146     public String getDataStoreMXBeanType() {
147         return dataStoreMXBeanType;
148     }
149
150     public long getOperationTimeoutInMillis() {
151         return operationTimeoutInMillis;
152     }
153
154     public ConfigParams getShardRaftConfig() {
155         return raftConfig;
156     }
157
158     public int getShardTransactionCommitTimeoutInSeconds() {
159         return shardTransactionCommitTimeoutInSeconds;
160     }
161
162     public int getShardTransactionCommitQueueCapacity() {
163         return shardTransactionCommitQueueCapacity;
164     }
165
166     public Timeout getShardInitializationTimeout() {
167         return shardInitializationTimeout;
168     }
169
170     public Timeout getShardLeaderElectionTimeout() {
171         return shardLeaderElectionTimeout;
172     }
173
174     public boolean isPersistent() {
175         return persistent;
176     }
177
178     public AkkaConfigurationReader getConfigurationReader() {
179         return configurationReader;
180     }
181
182     public long getShardElectionTimeoutFactor() {
183         return raftConfig.getElectionTimeoutFactor();
184     }
185
186     public String getDataStoreName() {
187         return dataStoreName;
188     }
189
190     public LogicalDatastoreType getLogicalStoreType() {
191         return logicalStoreType;
192     }
193
194     public YangInstanceIdentifier getStoreRoot() {
195         return storeRoot;
196     }
197
198     public long getTransactionCreationInitialRateLimit() {
199         return transactionCreationInitialRateLimit;
200     }
201
202     public String getShardManagerPersistenceId() {
203         return shardManagerPersistenceId;
204     }
205
206     private void setPeerAddressResolver(PeerAddressResolver resolver) {
207         raftConfig.setPeerAddressResolver(resolver);
208     }
209
210     private void setHeartbeatInterval(long shardHeartbeatIntervalInMillis) {
211         raftConfig.setHeartBeatInterval(new FiniteDuration(shardHeartbeatIntervalInMillis,
212                 TimeUnit.MILLISECONDS));
213     }
214
215     private void setShardJournalRecoveryLogBatchSize(int shardJournalRecoveryLogBatchSize) {
216         raftConfig.setJournalRecoveryLogBatchSize(shardJournalRecoveryLogBatchSize);
217     }
218
219
220     private void setIsolatedLeaderCheckInterval(long shardIsolatedLeaderCheckIntervalInMillis) {
221         raftConfig.setIsolatedLeaderCheckInterval(
222                 new FiniteDuration(shardIsolatedLeaderCheckIntervalInMillis, TimeUnit.MILLISECONDS));
223     }
224
225     private void setElectionTimeoutFactor(long shardElectionTimeoutFactor) {
226         raftConfig.setElectionTimeoutFactor(shardElectionTimeoutFactor);
227     }
228
229     private void setCustomRaftPolicyImplementation(String customRaftPolicyImplementation) {
230         raftConfig.setCustomRaftPolicyImplementationClass(customRaftPolicyImplementation);
231     }
232
233     private void setSnapshotDataThresholdPercentage(int shardSnapshotDataThresholdPercentage) {
234         Preconditions.checkArgument(shardSnapshotDataThresholdPercentage >= 0
235                 && shardSnapshotDataThresholdPercentage <= 100);
236         raftConfig.setSnapshotDataThresholdPercentage(shardSnapshotDataThresholdPercentage);
237     }
238
239     private void setSnapshotBatchCount(long shardSnapshotBatchCount) {
240         raftConfig.setSnapshotBatchCount(shardSnapshotBatchCount);
241     }
242
243     private void setShardSnapshotChunkSize(int shardSnapshotChunkSize) {
244         raftConfig.setSnapshotChunkSize(shardSnapshotChunkSize);
245     }
246
247     public int getShardBatchedModificationCount() {
248         return shardBatchedModificationCount;
249     }
250
251     public boolean isWriteOnlyTransactionOptimizationsEnabled() {
252         return writeOnlyTransactionOptimizationsEnabled;
253     }
254
255     public long getShardCommitQueueExpiryTimeoutInMillis() {
256         return shardCommitQueueExpiryTimeoutInMillis;
257     }
258
259     public boolean isTransactionDebugContextEnabled() {
260         return transactionDebugContextEnabled;
261     }
262
263     public boolean isUseTellBasedProtocol() {
264         return useTellBasedProtocol;
265     }
266
267     public int getShardSnapshotChunkSize() {
268         return raftConfig.getSnapshotChunkSize();
269     }
270
271     public static class Builder {
272         private final DatastoreContext datastoreContext;
273         private int maxShardDataChangeExecutorPoolSize =
274                 InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_CHANGE_EXECUTOR_POOL_SIZE;
275         private int maxShardDataChangeExecutorQueueSize =
276                 InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_CHANGE_EXECUTOR_QUEUE_SIZE;
277         private int maxShardDataChangeListenerQueueSize =
278                 InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_CHANGE_LISTENER_QUEUE_SIZE;
279         private int maxShardDataStoreExecutorQueueSize =
280                 InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_STORE_EXECUTOR_QUEUE_SIZE;
281
282         private Builder(DatastoreContext datastoreContext) {
283             this.datastoreContext = datastoreContext;
284
285             if (datastoreContext.getDataStoreProperties() != null) {
286                 maxShardDataChangeExecutorPoolSize =
287                         datastoreContext.getDataStoreProperties().getMaxDataChangeExecutorPoolSize();
288                 maxShardDataChangeExecutorQueueSize =
289                         datastoreContext.getDataStoreProperties().getMaxDataChangeExecutorQueueSize();
290                 maxShardDataChangeListenerQueueSize =
291                         datastoreContext.getDataStoreProperties().getMaxDataChangeListenerQueueSize();
292                 maxShardDataStoreExecutorQueueSize =
293                         datastoreContext.getDataStoreProperties().getMaxDataStoreExecutorQueueSize();
294             }
295         }
296
297         public Builder boundedMailboxCapacity(int boundedMailboxCapacity) {
298             // TODO - this is defined in the yang DataStoreProperties but not currently used.
299             return this;
300         }
301
302         public Builder enableMetricCapture(boolean enableMetricCapture) {
303             // TODO - this is defined in the yang DataStoreProperties but not currently used.
304             return this;
305         }
306
307
308         public Builder shardTransactionIdleTimeout(long timeout, TimeUnit unit) {
309             datastoreContext.shardTransactionIdleTimeout = Duration.create(timeout, unit);
310             return this;
311         }
312
313         public Builder shardTransactionIdleTimeoutInMinutes(long timeout) {
314             return shardTransactionIdleTimeout(timeout, TimeUnit.MINUTES);
315         }
316
317         public Builder operationTimeoutInSeconds(int operationTimeoutInSeconds) {
318             datastoreContext.operationTimeoutInMillis = TimeUnit.SECONDS.toMillis(operationTimeoutInSeconds);
319             return this;
320         }
321
322         public Builder operationTimeoutInMillis(long operationTimeoutInMillis) {
323             datastoreContext.operationTimeoutInMillis = operationTimeoutInMillis;
324             return this;
325         }
326
327         public Builder dataStoreMXBeanType(String dataStoreMXBeanType) {
328             datastoreContext.dataStoreMXBeanType = dataStoreMXBeanType;
329             return this;
330         }
331
332         public Builder shardTransactionCommitTimeoutInSeconds(int shardTransactionCommitTimeoutInSeconds) {
333             datastoreContext.shardTransactionCommitTimeoutInSeconds = shardTransactionCommitTimeoutInSeconds;
334             return this;
335         }
336
337         public Builder shardJournalRecoveryLogBatchSize(int shardJournalRecoveryLogBatchSize) {
338             datastoreContext.setShardJournalRecoveryLogBatchSize(shardJournalRecoveryLogBatchSize);
339             return this;
340         }
341
342         public Builder shardSnapshotBatchCount(int shardSnapshotBatchCount) {
343             datastoreContext.setSnapshotBatchCount(shardSnapshotBatchCount);
344             return this;
345         }
346
347         public Builder shardSnapshotDataThresholdPercentage(int shardSnapshotDataThresholdPercentage) {
348             datastoreContext.setSnapshotDataThresholdPercentage(shardSnapshotDataThresholdPercentage);
349             return this;
350         }
351
352         public Builder shardHeartbeatIntervalInMillis(int shardHeartbeatIntervalInMillis) {
353             datastoreContext.setHeartbeatInterval(shardHeartbeatIntervalInMillis);
354             return this;
355         }
356
357         public Builder shardTransactionCommitQueueCapacity(int shardTransactionCommitQueueCapacity) {
358             datastoreContext.shardTransactionCommitQueueCapacity = shardTransactionCommitQueueCapacity;
359             return this;
360         }
361
362         public Builder shardInitializationTimeout(long timeout, TimeUnit unit) {
363             datastoreContext.shardInitializationTimeout = new Timeout(timeout, unit);
364             return this;
365         }
366
367         public Builder shardInitializationTimeoutInSeconds(long timeout) {
368             return shardInitializationTimeout(timeout, TimeUnit.SECONDS);
369         }
370
371         public Builder shardLeaderElectionTimeout(long timeout, TimeUnit unit) {
372             datastoreContext.shardLeaderElectionTimeout = new Timeout(timeout, unit);
373             return this;
374         }
375
376         public Builder shardLeaderElectionTimeoutInSeconds(long timeout) {
377             return shardLeaderElectionTimeout(timeout, TimeUnit.SECONDS);
378         }
379
380         public Builder configurationReader(AkkaConfigurationReader configurationReader) {
381             datastoreContext.configurationReader = configurationReader;
382             return this;
383         }
384
385         public Builder persistent(boolean persistent) {
386             datastoreContext.persistent = persistent;
387             return this;
388         }
389
390         public Builder shardIsolatedLeaderCheckIntervalInMillis(int shardIsolatedLeaderCheckIntervalInMillis) {
391             datastoreContext.setIsolatedLeaderCheckInterval(shardIsolatedLeaderCheckIntervalInMillis);
392             return this;
393         }
394
395         public Builder shardElectionTimeoutFactor(long shardElectionTimeoutFactor) {
396             datastoreContext.setElectionTimeoutFactor(shardElectionTimeoutFactor);
397             return this;
398         }
399
400         public Builder transactionCreationInitialRateLimit(long initialRateLimit) {
401             datastoreContext.transactionCreationInitialRateLimit = initialRateLimit;
402             return this;
403         }
404
405         public Builder logicalStoreType(LogicalDatastoreType logicalStoreType) {
406             datastoreContext.logicalStoreType = Preconditions.checkNotNull(logicalStoreType);
407
408             // Retain compatible naming
409             switch (logicalStoreType) {
410                 case CONFIGURATION:
411                     dataStoreName("config");
412                     break;
413                 case OPERATIONAL:
414                     dataStoreName("operational");
415                     break;
416                 default:
417                     dataStoreName(logicalStoreType.name());
418             }
419
420             return this;
421         }
422
423         public Builder storeRoot(final YangInstanceIdentifier storeRoot) {
424             datastoreContext.storeRoot = storeRoot;
425             return this;
426         }
427
428         public Builder dataStoreName(String dataStoreName) {
429             datastoreContext.dataStoreName = Preconditions.checkNotNull(dataStoreName);
430             datastoreContext.dataStoreMXBeanType = "Distributed" + WordUtils.capitalize(dataStoreName) + "Datastore";
431             return this;
432         }
433
434         public Builder shardBatchedModificationCount(final int shardBatchedModificationCount) {
435             datastoreContext.shardBatchedModificationCount = shardBatchedModificationCount;
436             return this;
437         }
438
439         public Builder writeOnlyTransactionOptimizationsEnabled(boolean value) {
440             datastoreContext.writeOnlyTransactionOptimizationsEnabled = value;
441             return this;
442         }
443
444         public Builder shardCommitQueueExpiryTimeoutInMillis(long value) {
445             datastoreContext.shardCommitQueueExpiryTimeoutInMillis = value;
446             return this;
447         }
448
449         public Builder shardCommitQueueExpiryTimeoutInSeconds(long value) {
450             datastoreContext.shardCommitQueueExpiryTimeoutInMillis = TimeUnit.MILLISECONDS.convert(
451                     value, TimeUnit.SECONDS);
452             return this;
453         }
454
455         public Builder transactionDebugContextEnabled(boolean value) {
456             datastoreContext.transactionDebugContextEnabled = value;
457             return this;
458         }
459
460         public Builder maxShardDataChangeExecutorPoolSize(int maxShardDataChangeExecutorPoolSize) {
461             this.maxShardDataChangeExecutorPoolSize = maxShardDataChangeExecutorPoolSize;
462             return this;
463         }
464
465         public Builder maxShardDataChangeExecutorQueueSize(int maxShardDataChangeExecutorQueueSize) {
466             this.maxShardDataChangeExecutorQueueSize = maxShardDataChangeExecutorQueueSize;
467             return this;
468         }
469
470         public Builder maxShardDataChangeListenerQueueSize(int maxShardDataChangeListenerQueueSize) {
471             this.maxShardDataChangeListenerQueueSize = maxShardDataChangeListenerQueueSize;
472             return this;
473         }
474
475         public Builder maxShardDataStoreExecutorQueueSize(int maxShardDataStoreExecutorQueueSize) {
476             this.maxShardDataStoreExecutorQueueSize = maxShardDataStoreExecutorQueueSize;
477             return this;
478         }
479
480         public Builder useTellBasedProtocol(boolean value) {
481             datastoreContext.useTellBasedProtocol = value;
482             return this;
483         }
484
485         /**
486          * For unit tests only.
487          */
488         @VisibleForTesting
489         public Builder shardManagerPersistenceId(String id) {
490             datastoreContext.shardManagerPersistenceId = id;
491             return this;
492         }
493
494         public DatastoreContext build() {
495             datastoreContext.dataStoreProperties = InMemoryDOMDataStoreConfigProperties.create(
496                     maxShardDataChangeExecutorPoolSize, maxShardDataChangeExecutorQueueSize,
497                     maxShardDataChangeListenerQueueSize, maxShardDataStoreExecutorQueueSize);
498
499             if (datastoreContext.dataStoreName != null) {
500                 GLOBAL_DATASTORE_NAMES.add(datastoreContext.dataStoreName);
501             }
502
503             return datastoreContext;
504         }
505
506         public Builder customRaftPolicyImplementation(String customRaftPolicyImplementation) {
507             datastoreContext.setCustomRaftPolicyImplementation(customRaftPolicyImplementation);
508             return this;
509         }
510
511         public Builder shardSnapshotChunkSize(int shardSnapshotChunkSize) {
512             datastoreContext.setShardSnapshotChunkSize(shardSnapshotChunkSize);
513             return this;
514         }
515
516         public Builder shardPeerAddressResolver(PeerAddressResolver resolver) {
517             datastoreContext.setPeerAddressResolver(resolver);
518             return this;
519         }
520     }
521 }