+ store.setRunOnPendingTransactionsComplete(null);
+
+ // Restore tell-based protocol state as if we were becoming the leader
+ knownFrontends = verifyNotNull(frontendMetadata.toLeaderState(this));
+ }
+
+ @Override
+ protected final OnDemandRaftState.AbstractBuilder<?, ?> newOnDemandRaftStateBuilder() {
+ return OnDemandShardState.newBuilder()
+ .treeChangeListenerActors(treeChangeSupport.getListenerActors())
+ .commitCohortActors(store.getCohortActors());
+ }
+
+ @Override
+ public final String persistenceId() {
+ return name;
+ }
+
+ @Override
+ public final String journalPluginId() {
+ // This method may be invoked from super constructor (wonderful), hence we also need to handle the case of
+ // the field being uninitialized because our constructor is not finished.
+ if (datastoreContext != null && !datastoreContext.isPersistent()) {
+ return NON_PERSISTENT_JOURNAL_ID;
+ }
+ return super.journalPluginId();
+ }
+
+ @VisibleForTesting
+ final ShardCommitCoordinator getCommitCoordinator() {
+ return commitCoordinator;
+ }
+
+ // non-final for mocking
+ DatastoreContext getDatastoreContext() {
+ return datastoreContext;
+ }
+
+ @VisibleForTesting
+ final ShardDataTree getDataStore() {
+ return store;
+ }
+
+ @VisibleForTesting
+ // non-final for mocking
+ ShardStats getShardMBean() {
+ return shardMBean;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public abstract static class AbstractBuilder<T extends AbstractBuilder<T, S>, S extends Shard> {
+ private final Class<? extends S> shardClass;
+ private ShardIdentifier id;
+ private Map<String, String> peerAddresses = Collections.emptyMap();
+ private DatastoreContext datastoreContext;
+ private EffectiveModelContextProvider schemaContextProvider;
+ private DatastoreSnapshot.ShardSnapshot restoreFromSnapshot;
+ private DataTree dataTree;
+
+ private volatile boolean sealed;
+
+ AbstractBuilder(final Class<? extends S> shardClass) {
+ this.shardClass = shardClass;
+ }
+
+ final void checkSealed() {
+ checkState(!sealed, "Builder is already sealed - further modifications are not allowed");
+ }
+
+ @SuppressWarnings("unchecked")
+ private T self() {
+ return (T) this;
+ }
+
+ public T id(final ShardIdentifier newId) {
+ checkSealed();
+ this.id = newId;
+ return self();
+ }
+
+ public T peerAddresses(final Map<String, String> newPeerAddresses) {
+ checkSealed();
+ this.peerAddresses = newPeerAddresses;
+ return self();
+ }
+
+ public T datastoreContext(final DatastoreContext newDatastoreContext) {
+ checkSealed();
+ this.datastoreContext = newDatastoreContext;
+ return self();
+ }
+
+ public T schemaContextProvider(final EffectiveModelContextProvider newSchemaContextProvider) {
+ checkSealed();
+ this.schemaContextProvider = requireNonNull(newSchemaContextProvider);
+ return self();
+ }
+
+ public T restoreFromSnapshot(final DatastoreSnapshot.ShardSnapshot newRestoreFromSnapshot) {
+ checkSealed();
+ this.restoreFromSnapshot = newRestoreFromSnapshot;
+ return self();
+ }
+
+ public T dataTree(final DataTree newDataTree) {
+ checkSealed();
+ this.dataTree = newDataTree;
+ return self();
+ }
+
+ public ShardIdentifier getId() {
+ return id;
+ }
+
+ public Map<String, String> getPeerAddresses() {
+ return peerAddresses;
+ }
+
+ public DatastoreContext getDatastoreContext() {
+ return datastoreContext;
+ }
+
+ public EffectiveModelContext getSchemaContext() {
+ return verifyNotNull(schemaContextProvider.getEffectiveModelContext());
+ }
+
+ public DatastoreSnapshot.ShardSnapshot getRestoreFromSnapshot() {
+ return restoreFromSnapshot;
+ }
+
+ public DataTree getDataTree() {
+ return dataTree;
+ }
+
+ public TreeType getTreeType() {
+ switch (datastoreContext.getLogicalStoreType()) {
+ case CONFIGURATION:
+ return TreeType.CONFIGURATION;
+ case OPERATIONAL:
+ return TreeType.OPERATIONAL;
+ default:
+ throw new IllegalStateException("Unhandled logical store type "
+ + datastoreContext.getLogicalStoreType());
+ }
+ }
+
+ protected void verify() {
+ requireNonNull(id, "id should not be null");
+ requireNonNull(peerAddresses, "peerAddresses should not be null");
+ requireNonNull(datastoreContext, "dataStoreContext should not be null");
+ requireNonNull(schemaContextProvider, "schemaContextProvider should not be null");
+ }
+
+ public Props props() {
+ sealed = true;
+ verify();
+ return Props.create(shardClass, this);
+ }