within two election timeout periods the operation fails.";
}
- rpc add-prefix-shard-replica {
- input {
- leaf shard-prefix {
- mandatory true;
- type instance-identifier;
- }
-
- leaf data-store-type {
- mandatory true;
- type data-store-type;
- description "The type of the data store to which the replica belongs";
- }
- }
-
- description "Adds a replica of a shard to this node and joins it to an existing cluster. There must already be
- a shard existing on another node with a leader. This RPC first contacts peer member seed nodes
- searching for a shard. When found, an AddServer message is sent to the shard leader and applied as
- described in the Raft paper.";
- }
-
- rpc remove-prefix-shard-replica {
- input {
- leaf shard-prefix {
- mandatory true;
- type instance-identifier;
- }
- leaf member-name {
- mandatory true;
- type string;
- description "The cluster member from which the shard replica should be removed";
- }
-
- leaf data-store-type {
- mandatory true;
- type data-store-type;
- description "The type of the data store to which the replica belongs";
- }
- }
-
- description "Removes an existing replica of a prefix shard from this node via the RemoveServer mechanism as
- described in the Raft paper.";
- }
-
rpc add-replicas-for-all-shards {
output {
uses shard-result-output;
}
}
- rpc get-prefix-shard-role {
- input {
- leaf shard-prefix {
- mandatory true;
- type instance-identifier;
- }
-
- leaf data-store-type {
- mandatory true;
- type data-store-type;
- description "The type of the data store to which the replica belongs";
- }
- }
-
- output {
- leaf role {
- type string;
- description "Current role for the given shard, if not present the shard currently does not have a role";
- }
- }
-
- description "Returns the current role for the requested module shard.";
- }
-
rpc get-known-clients-for-all-shards {
description "Request all shards to report their known frontend clients. This is useful for determining what
generation should a resurrected member node should use.";
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.controller.cluster.access.concepts.MemberName;
import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
-import org.opendaylight.controller.cluster.datastore.messages.AddPrefixShardReplica;
import org.opendaylight.controller.cluster.datastore.messages.AddShardReplica;
import org.opendaylight.controller.cluster.datastore.messages.ChangeShardMembersVotingStatus;
import org.opendaylight.controller.cluster.datastore.messages.FlipShardMembersVotingStatus;
import org.opendaylight.controller.cluster.datastore.messages.GetShardRoleReply;
import org.opendaylight.controller.cluster.datastore.messages.MakeLeaderLocal;
import org.opendaylight.controller.cluster.datastore.messages.PrimaryShardInfo;
-import org.opendaylight.controller.cluster.datastore.messages.RemovePrefixShardReplica;
import org.opendaylight.controller.cluster.datastore.messages.RemoveShardReplica;
import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshotList;
import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
-import org.opendaylight.controller.cluster.datastore.utils.ClusterUtils;
import org.opendaylight.controller.cluster.raft.client.messages.GetSnapshot;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.AddPrefixShardReplicaInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.AddPrefixShardReplicaOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.AddPrefixShardReplicaOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.AddReplicasForAllShardsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.AddReplicasForAllShardsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.AddReplicasForAllShardsOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.GetKnownClientsForAllShardsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.GetKnownClientsForAllShardsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.GetKnownClientsForAllShardsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.GetPrefixShardRoleInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.GetPrefixShardRoleOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.GetPrefixShardRoleOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.GetShardRoleInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.GetShardRoleOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.GetShardRoleOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.RemoveAllShardReplicasInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.RemoveAllShardReplicasOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.RemoveAllShardReplicasOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.RemovePrefixShardReplicaInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.RemovePrefixShardReplicaOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.RemovePrefixShardReplicaOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.RemoveShardReplicaInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.RemoveShardReplicaOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.RemoveShardReplicaOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.shard.result.output.ShardResult;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.shard.result.output.ShardResultBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.shard.result.output.ShardResultKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.common.Uint32;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.concurrent.Future;
return future;
}
- @Override
- public ListenableFuture<RpcResult<AddPrefixShardReplicaOutput>> addPrefixShardReplica(
- final AddPrefixShardReplicaInput input) {
-
- final InstanceIdentifier<?> identifier = input.getShardPrefix();
- if (identifier == null) {
- return newFailedRpcResultFuture("A valid shard identifier must be specified");
- }
-
- final DataStoreType dataStoreType = input.getDataStoreType();
- if (dataStoreType == null) {
- return newFailedRpcResultFuture("A valid DataStoreType must be specified");
- }
-
- LOG.info("Adding replica for shard {}, datastore type {}", identifier, dataStoreType);
-
- final YangInstanceIdentifier prefix = serializer.toYangInstanceIdentifier(identifier);
- final SettableFuture<RpcResult<AddPrefixShardReplicaOutput>> returnFuture = SettableFuture.create();
- ListenableFuture<Success> future = sendMessageToShardManager(dataStoreType, new AddPrefixShardReplica(prefix));
- Futures.addCallback(future, new FutureCallback<Success>() {
- @Override
- public void onSuccess(final Success success) {
- LOG.info("Successfully added replica for shard {}", prefix);
- returnFuture.set(newSuccessfulResult(new AddPrefixShardReplicaOutputBuilder().build()));
- }
-
- @Override
- public void onFailure(final Throwable failure) {
- onMessageFailure(String.format("Failed to add replica for shard %s", prefix),
- returnFuture, failure);
- }
- }, MoreExecutors.directExecutor());
-
- return returnFuture;
- }
-
- @Override
- public ListenableFuture<RpcResult<RemovePrefixShardReplicaOutput>> removePrefixShardReplica(
- final RemovePrefixShardReplicaInput input) {
-
- final InstanceIdentifier<?> identifier = input.getShardPrefix();
- if (identifier == null) {
- return newFailedRpcResultFuture("A valid shard identifier must be specified");
- }
-
- final DataStoreType dataStoreType = input.getDataStoreType();
- if (dataStoreType == null) {
- return newFailedRpcResultFuture("A valid DataStoreType must be specified");
- }
-
- final String memberName = input.getMemberName();
- if (Strings.isNullOrEmpty(memberName)) {
- return newFailedRpcResultFuture("A valid member name must be specified");
- }
-
- LOG.info("Removing replica for shard {} memberName {}, datastoreType {}",
- identifier, memberName, dataStoreType);
- final YangInstanceIdentifier prefix = serializer.toYangInstanceIdentifier(identifier);
-
- final SettableFuture<RpcResult<RemovePrefixShardReplicaOutput>> returnFuture = SettableFuture.create();
- final ListenableFuture<Success> future = sendMessageToShardManager(dataStoreType,
- new RemovePrefixShardReplica(prefix, MemberName.forName(memberName)));
- Futures.addCallback(future, new FutureCallback<Success>() {
- @Override
- public void onSuccess(final Success success) {
- LOG.info("Successfully removed replica for shard {}", prefix);
- returnFuture.set(newSuccessfulResult(new RemovePrefixShardReplicaOutputBuilder().build()));
- }
-
- @Override
- public void onFailure(final Throwable failure) {
- onMessageFailure(String.format("Failed to remove replica for shard %s", prefix),
- returnFuture, failure);
- }
- }, MoreExecutors.directExecutor());
-
- return returnFuture;
- }
-
@Override
public ListenableFuture<RpcResult<AddReplicasForAllShardsOutput>> addReplicasForAllShards(
final AddReplicasForAllShardsInput input) {
return returnFuture;
}
- @Override
- public ListenableFuture<RpcResult<GetPrefixShardRoleOutput>> getPrefixShardRole(
- final GetPrefixShardRoleInput input) {
- final InstanceIdentifier<?> identifier = input.getShardPrefix();
- if (identifier == null) {
- return newFailedRpcResultFuture("A valid shard identifier must be specified");
- }
-
- final DataStoreType dataStoreType = input.getDataStoreType();
- if (dataStoreType == null) {
- return newFailedRpcResultFuture("A valid DataStoreType must be specified");
- }
-
- LOG.info("Getting prefix shard role for shard: {}, datastore type {}", identifier, dataStoreType);
-
- final YangInstanceIdentifier prefix = serializer.toYangInstanceIdentifier(identifier);
- final String shardName = ClusterUtils.getCleanShardName(prefix);
- final SettableFuture<RpcResult<GetPrefixShardRoleOutput>> returnFuture = SettableFuture.create();
- ListenableFuture<GetShardRoleReply> future = sendMessageToShardManager(dataStoreType,
- new GetShardRole(shardName));
- Futures.addCallback(future, new FutureCallback<GetShardRoleReply>() {
- @Override
- public void onSuccess(final GetShardRoleReply reply) {
- if (reply == null) {
- returnFuture.set(ClusterAdminRpcService.<GetPrefixShardRoleOutput>newFailedRpcResultBuilder(
- "No Shard role present. Please retry..").build());
- return;
- }
-
- LOG.info("Successfully received role:{} for shard {}", reply.getRole(), shardName);
- final GetPrefixShardRoleOutputBuilder builder = new GetPrefixShardRoleOutputBuilder();
- if (reply.getRole() != null) {
- builder.setRole(reply.getRole());
- }
- returnFuture.set(newSuccessfulResult(builder.build()));
- }
-
- @Override
- public void onFailure(final Throwable failure) {
- returnFuture.set(ClusterAdminRpcService.<GetPrefixShardRoleOutput>newFailedRpcResultBuilder(
- "Failed to get shard role.", failure).build());
- }
- }, MoreExecutors.directExecutor());
-
- return returnFuture;
- }
-
@Override
public ListenableFuture<RpcResult<BackupDatastoreOutput>> backupDatastore(final BackupDatastoreInput input) {
LOG.debug("backupDatastore: {}", input);
import org.opendaylight.controller.cluster.datastore.shardmanager.AbstractShardManagerCreator;
import org.opendaylight.controller.cluster.datastore.shardmanager.ShardManagerCreator;
import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
-import org.opendaylight.controller.cluster.datastore.utils.ClusterUtils;
import org.opendaylight.controller.cluster.datastore.utils.PrimaryShardInfoFutureCache;
import org.opendaylight.mdsal.dom.api.ClusteredDOMDataTreeChangeListener;
import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
return (ListenerRegistration<L>) listenerRegistrationProxy;
}
- @Override
- @SuppressWarnings("unchecked")
- public <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerShardConfigListener(
- final YangInstanceIdentifier internalPath, final DOMDataTreeChangeListener delegate) {
- requireNonNull(delegate, "delegate should not be null");
-
- LOG.debug("Registering a listener for the configuration shard: {}", internalPath);
-
- final DataTreeChangeListenerProxy<DOMDataTreeChangeListener> proxy =
- new DataTreeChangeListenerProxy<>(actorUtils, delegate, internalPath);
- proxy.init(ClusterUtils.PREFIX_CONFIG_SHARD_ID);
-
- return (ListenerRegistration<L>) proxy;
- }
-
private Duration initialSettleTime() {
final DatastoreContext context = actorUtils.getDatastoreContext();
final int multiplier = context.getInitialSettleTimeoutMultiplier();
ActorUtils getActorUtils();
- @Beta
- <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerShardConfigListener(
- YangInstanceIdentifier internalPath, DOMDataTreeChangeListener delegate);
-
@Beta
<L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerProxyListener(
YangInstanceIdentifier shardLookup, YangInstanceIdentifier insideShard,
return datastore.getActorUtils();
}
- @Override
- public <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerShardConfigListener(
- final YangInstanceIdentifier internalPath, final DOMDataTreeChangeListener delegate) {
- return datastore.registerShardConfigListener(internalPath, delegate);
- }
-
@Override
public <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerProxyListener(
final YangInstanceIdentifier shardLookup, final YangInstanceIdentifier insideShard,
package org.opendaylight.controller.cluster.datastore.config;
import java.util.Collection;
-import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.concepts.MemberName;
import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategy;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
public interface Configuration {
*/
@Nullable String getShardNameForModule(@NonNull String moduleName);
- /**
- * Return the shard name corresponding to the prefix, or null if none is configured.
- */
- @Nullable String getShardNameForPrefix(@NonNull DOMDataTreeIdentifier prefix);
-
/**
* Returns the member replicas for the given shard name.
*/
*/
void addModuleShardConfiguration(@NonNull ModuleShardConfiguration config);
- /**
- * Adds a new configuration for a shard based on prefix.
- */
- void addPrefixShardConfiguration(@NonNull PrefixShardConfiguration config);
-
- /**
- * Removes a shard configuration for the specified prefix.
- */
- void removePrefixShardConfiguration(@NonNull DOMDataTreeIdentifier prefix);
-
- /**
- * Returns the configuration for all configured prefix shards.
- *
- * @return An immutable copy of the currently configured prefix shards.
- */
- Map<DOMDataTreeIdentifier, PrefixShardConfiguration> getAllPrefixShardConfigurations();
-
/**
* Returns a unique set of all member names configured for all shards.
*/
* Removes the given member as a replica for the given shardName.
*/
void removeMemberReplicaForShard(String shardName, MemberName memberName);
-
- /**
- * Returns the ShardStrategy for the given prefix or null if the prefix is not found.
- */
- @Nullable ShardStrategy getStrategyForPrefix(@NonNull DOMDataTreeIdentifier prefix);
}
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.controller.cluster.datastore.shardstrategy.PrefixShardStrategy;
import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategy;
import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategyFactory;
-import org.opendaylight.controller.cluster.datastore.utils.ClusterUtils;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-// TODO clean this up once we get rid of module based configuration, prefix one should be alot simpler
public class ConfigurationImpl implements Configuration {
private volatile Map<String, ModuleConfig> moduleConfigMap;
- // TODO should this be initialized with something? on restart we should restore the shards from configuration?
- private volatile Map<DOMDataTreeIdentifier, PrefixShardConfiguration> prefixConfigMap = Collections.emptyMap();
-
// Look up maps to speed things up
private volatile Map<String, String> namespaceToModuleName;
return moduleConfigMap.get(requireNonNull(moduleName, "moduleName should not be null"));
}
- @Override
- public String getShardNameForPrefix(final DOMDataTreeIdentifier prefix) {
- requireNonNull(prefix, "prefix should not be null");
-
- Entry<DOMDataTreeIdentifier, PrefixShardConfiguration> bestMatchEntry = new SimpleEntry<>(
- new DOMDataTreeIdentifier(prefix.getDatastoreType(), YangInstanceIdentifier.empty()), null);
-
- for (Entry<DOMDataTreeIdentifier, PrefixShardConfiguration> entry : prefixConfigMap.entrySet()) {
- if (entry.getKey().contains(prefix) && entry.getKey().getRootIdentifier().getPathArguments().size()
- > bestMatchEntry.getKey().getRootIdentifier().getPathArguments().size()) {
- bestMatchEntry = entry;
- }
- }
-
- //TODO we really should have mapping based on prefix instead of Strings
- return ClusterUtils.getCleanShardName(bestMatchEntry.getKey().getRootIdentifier());
- }
-
@Override
public Collection<MemberName> getMembersFromShardName(final String shardName) {
checkNotNullShardName(shardName);
}
}
- for (final PrefixShardConfiguration prefixConfig : prefixConfigMap.values()) {
- if (shardName.equals(ClusterUtils.getCleanShardName(prefixConfig.getPrefix().getRootIdentifier()))) {
- return prefixConfig.getShardMemberNames();
- }
- }
-
return Collections.emptyList();
}
allShardNames = ImmutableSet.<String>builder().addAll(allShardNames).add(config.getShardName()).build();
}
- @Override
- public void addPrefixShardConfiguration(final PrefixShardConfiguration config) {
- addPrefixConfig(requireNonNull(config, "PrefixShardConfiguration cannot be null"));
- allShardNames = ImmutableSet.<String>builder().addAll(allShardNames)
- .add(ClusterUtils.getCleanShardName(config.getPrefix().getRootIdentifier())).build();
- }
-
- @Override
- public void removePrefixShardConfiguration(final DOMDataTreeIdentifier prefix) {
- removePrefixConfig(requireNonNull(prefix, "Prefix cannot be null"));
-
- final HashSet<String> temp = new HashSet<>(allShardNames);
- temp.remove(ClusterUtils.getCleanShardName(prefix.getRootIdentifier()));
-
- allShardNames = ImmutableSet.copyOf(temp);
- }
-
- @Override
- public Map<DOMDataTreeIdentifier, PrefixShardConfiguration> getAllPrefixShardConfigurations() {
- return ImmutableMap.copyOf(prefixConfigMap);
- }
-
- private void addPrefixConfig(final PrefixShardConfiguration config) {
- final Map<DOMDataTreeIdentifier, PrefixShardConfiguration> newPrefixConfigMap = new HashMap<>(prefixConfigMap);
- newPrefixConfigMap.put(config.getPrefix(), config);
- prefixConfigMap = ImmutableMap.copyOf(newPrefixConfigMap);
- }
-
- private void removePrefixConfig(final DOMDataTreeIdentifier prefix) {
- final Map<DOMDataTreeIdentifier, PrefixShardConfiguration> newPrefixConfigMap = new HashMap<>(prefixConfigMap);
- newPrefixConfigMap.remove(prefix);
- prefixConfigMap = ImmutableMap.copyOf(newPrefixConfigMap);
- }
-
private ShardStrategy createShardStrategy(final String moduleName, final String shardStrategyName) {
return ShardStrategyFactory.newShardStrategyInstance(moduleName, shardStrategyName, this);
}
}
}
- @Override
- public ShardStrategy getStrategyForPrefix(final DOMDataTreeIdentifier prefix) {
- requireNonNull(prefix, "Prefix cannot be null");
- // FIXME using prefix tables like in mdsal will be better
- Entry<DOMDataTreeIdentifier, PrefixShardConfiguration> bestMatchEntry = new SimpleEntry<>(
- new DOMDataTreeIdentifier(prefix.getDatastoreType(), YangInstanceIdentifier.empty()), null);
-
- for (Entry<DOMDataTreeIdentifier, PrefixShardConfiguration> entry : prefixConfigMap.entrySet()) {
- if (entry.getKey().contains(prefix) && entry.getKey().getRootIdentifier().getPathArguments().size()
- > bestMatchEntry.getKey().getRootIdentifier().getPathArguments().size()) {
- bestMatchEntry = entry;
- }
- }
-
- if (bestMatchEntry.getValue() == null) {
- return null;
- }
- return new PrefixShardStrategy(ClusterUtils
- .getCleanShardName(bestMatchEntry.getKey().getRootIdentifier()),
- bestMatchEntry.getKey().getRootIdentifier());
- }
-
private void updateModuleConfigMap(final ModuleConfig moduleConfig) {
final Map<String, ModuleConfig> newModuleConfigMap = new HashMap<>(moduleConfigMap);
newModuleConfigMap.put(moduleConfig.getName(), moduleConfig);
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.datastore.config;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ImmutableSet;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-
-/**
- * Configuration for prefix based shards.
- */
-public class PrefixShardConfiguration implements Serializable {
- private static final class Proxy implements Externalizable {
- private static final long serialVersionUID = 1L;
-
- private PrefixShardConfiguration prefixShardConfiguration;
-
- // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
- // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
- @SuppressWarnings("checkstyle:RedundantModifier")
- public Proxy() {
- }
-
- Proxy(final PrefixShardConfiguration prefixShardConfiguration) {
- this.prefixShardConfiguration = prefixShardConfiguration;
- }
-
- @Override
- public void writeExternal(final ObjectOutput objectOutput) throws IOException {
- objectOutput.writeObject(prefixShardConfiguration.getPrefix());
- objectOutput.writeObject(prefixShardConfiguration.getShardStrategyName());
-
- objectOutput.writeInt(prefixShardConfiguration.getShardMemberNames().size());
- for (MemberName name : prefixShardConfiguration.getShardMemberNames()) {
- name.writeTo(objectOutput);
- }
- }
-
- @Override
- public void readExternal(final ObjectInput objectInput) throws IOException, ClassNotFoundException {
- final DOMDataTreeIdentifier localPrefix = (DOMDataTreeIdentifier) objectInput.readObject();
- final String localStrategyName = (String) objectInput.readObject();
-
- final int size = objectInput.readInt();
- final Collection<MemberName> localShardMemberNames = new ArrayList<>(size);
- for (int i = 0; i < size; i++) {
- localShardMemberNames.add(MemberName.readFrom(objectInput));
- }
-
- prefixShardConfiguration = new PrefixShardConfiguration(localPrefix, localStrategyName,
- localShardMemberNames);
- }
-
- private Object readResolve() {
- return prefixShardConfiguration;
- }
- }
-
- private static final long serialVersionUID = 1L;
-
- private final DOMDataTreeIdentifier prefix;
- private final String shardStrategyName;
- private final Collection<MemberName> shardMemberNames;
-
- public PrefixShardConfiguration(final DOMDataTreeIdentifier prefix,
- final String shardStrategyName,
- final Collection<MemberName> shardMemberNames) {
- this.prefix = requireNonNull(prefix);
- this.shardStrategyName = requireNonNull(shardStrategyName);
- this.shardMemberNames = ImmutableSet.copyOf(shardMemberNames);
- }
-
- public DOMDataTreeIdentifier getPrefix() {
- return prefix;
- }
-
- public String getShardStrategyName() {
- return shardStrategyName;
- }
-
- public Collection<MemberName> getShardMemberNames() {
- return shardMemberNames;
- }
-
- @Override
- public String toString() {
- return "PrefixShardConfiguration{"
- + "prefix=" + prefix
- + ", shardStrategyName='"
- + shardStrategyName + '\''
- + ", shardMemberNames=" + shardMemberNames
- + '}';
- }
-
- private Object writeReplace() {
- return new Proxy(this);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.datastore.messages;
-
-import static java.util.Objects.requireNonNull;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-/**
- * A message sent to the ShardManager to dynamically add a new local shard
- * that is a replica for an existing prefix shard that is already available
- * in the cluster.
- */
-public class AddPrefixShardReplica {
-
- private final YangInstanceIdentifier prefix;
-
- /**
- * Constructor.
- *
- * @param prefix prefix of the shard that is to be locally replicated.
- */
-
- public AddPrefixShardReplica(final @NonNull YangInstanceIdentifier prefix) {
- this.prefix = requireNonNull(prefix, "prefix should not be null");
- }
-
- public YangInstanceIdentifier getShardPrefix() {
- return this.prefix;
- }
-
- @Override
- public String toString() {
- return "AddPrefixShardReplica[prefix=" + prefix + "]";
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.datastore.messages;
-
-import static java.util.Objects.requireNonNull;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-/**
- * A message sent to the ShardManager to dynamically remove a local prefix shard
- * replica available in this node.
- */
-public class RemovePrefixShardReplica {
-
- private final YangInstanceIdentifier prefix;
- private final MemberName memberName;
-
- /**
- * Constructor.
- *
- * @param prefix prefix of the local shard that is to be dynamically removed.
- */
- public RemovePrefixShardReplica(final @NonNull YangInstanceIdentifier prefix,
- final @NonNull MemberName memberName) {
- this.prefix = requireNonNull(prefix, "prefix should not be null");
- this.memberName = requireNonNull(memberName, "memberName should not be null");
- }
-
- public YangInstanceIdentifier getShardPrefix() {
- return prefix;
- }
-
- public MemberName getMemberName() {
- return memberName;
- }
-
- @Override
- public String toString() {
- return "RemovePrefixShardReplica [prefix=" + prefix + ", memberName=" + memberName + "]";
- }
-}
package org.opendaylight.controller.cluster.datastore.persisted;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.controller.cluster.datastore.config.PrefixShardConfiguration;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
/**
* Represents the persisted snapshot state for the ShardManager.
for (String shard: snapshot.shardList) {
out.writeObject(shard);
}
-
- out.writeInt(snapshot.prefixShardConfiguration.size());
- for (Map.Entry<?, ?> prefixShardConfigEntry : snapshot.prefixShardConfiguration.entrySet()) {
- out.writeObject(prefixShardConfigEntry.getKey());
- out.writeObject(prefixShardConfigEntry.getValue());
- }
}
@Override
localShardList.add((String) in.readObject());
}
- size = in.readInt();
- Map<DOMDataTreeIdentifier, PrefixShardConfiguration> localPrefixShardConfiguration = new HashMap<>(size);
- for (int i = 0; i < size; i++) {
- localPrefixShardConfiguration.put((DOMDataTreeIdentifier) in.readObject(),
- (PrefixShardConfiguration) in.readObject());
- }
-
- snapshot = new ShardManagerSnapshot(localShardList, localPrefixShardConfiguration);
+ snapshot = new ShardManagerSnapshot(localShardList);
}
private Object readResolve() {
}
private final List<String> shardList;
- private final Map<DOMDataTreeIdentifier, PrefixShardConfiguration> prefixShardConfiguration;
- public ShardManagerSnapshot(final @NonNull List<String> shardList,
- final Map<DOMDataTreeIdentifier, PrefixShardConfiguration> prefixShardConfiguration) {
+ public ShardManagerSnapshot(final @NonNull List<String> shardList) {
this.shardList = ImmutableList.copyOf(shardList);
- this.prefixShardConfiguration = ImmutableMap.copyOf(prefixShardConfiguration);
}
public List<String> getShardList() {
import org.opendaylight.controller.cluster.common.actor.Dispatchers;
import org.opendaylight.controller.cluster.datastore.ClusterWrapper;
import org.opendaylight.controller.cluster.datastore.DatastoreContext;
-import org.opendaylight.controller.cluster.datastore.DatastoreContext.Builder;
import org.opendaylight.controller.cluster.datastore.DatastoreContextFactory;
import org.opendaylight.controller.cluster.datastore.Shard;
import org.opendaylight.controller.cluster.datastore.config.Configuration;
import org.opendaylight.controller.cluster.datastore.config.ModuleShardConfiguration;
-import org.opendaylight.controller.cluster.datastore.config.PrefixShardConfiguration;
import org.opendaylight.controller.cluster.datastore.exceptions.AlreadyExistsException;
import org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException;
import org.opendaylight.controller.cluster.datastore.exceptions.NotInitializedException;
import org.opendaylight.controller.cluster.datastore.exceptions.PrimaryNotFoundException;
import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
import org.opendaylight.controller.cluster.datastore.messages.ActorInitialized;
-import org.opendaylight.controller.cluster.datastore.messages.AddPrefixShardReplica;
import org.opendaylight.controller.cluster.datastore.messages.AddShardReplica;
import org.opendaylight.controller.cluster.datastore.messages.ChangeShardMembersVotingStatus;
import org.opendaylight.controller.cluster.datastore.messages.CreateShard;
import org.opendaylight.controller.cluster.datastore.messages.LocalShardNotFound;
import org.opendaylight.controller.cluster.datastore.messages.RemoteFindPrimary;
import org.opendaylight.controller.cluster.datastore.messages.RemotePrimaryShardFound;
-import org.opendaylight.controller.cluster.datastore.messages.RemovePrefixShardReplica;
import org.opendaylight.controller.cluster.datastore.messages.RemoveShardReplica;
import org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged;
import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
import org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot;
-import org.opendaylight.controller.cluster.datastore.utils.ClusterUtils;
import org.opendaylight.controller.cluster.datastore.utils.CompositeOnComplete;
import org.opendaylight.controller.cluster.datastore.utils.PrimaryShardInfoFutureCache;
import org.opendaylight.controller.cluster.notifications.RegisterRoleChangeListener;
import org.opendaylight.controller.cluster.raft.messages.ServerChangeStatus;
import org.opendaylight.controller.cluster.raft.messages.ServerRemoved;
import org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
onCreateShard((CreateShard)message);
} else if (message instanceof AddShardReplica) {
onAddShardReplica((AddShardReplica) message);
- } else if (message instanceof AddPrefixShardReplica) {
- onAddPrefixShardReplica((AddPrefixShardReplica) message);
} else if (message instanceof ForwardedAddServerReply) {
ForwardedAddServerReply msg = (ForwardedAddServerReply)message;
onAddServerReply(msg.shardInfo, msg.addServerReply, getSender(), msg.leaderPath,
onAddServerFailure(msg.shardName, msg.failureMessage, msg.failure, getSender(), msg.removeShardOnFailure);
} else if (message instanceof RemoveShardReplica) {
onRemoveShardReplica((RemoveShardReplica) message);
- } else if (message instanceof RemovePrefixShardReplica) {
- onRemovePrefixShardReplica((RemovePrefixShardReplica) message);
} else if (message instanceof WrappedShardResponse) {
onWrappedShardResponse((WrappedShardResponse) message);
} else if (message instanceof GetSnapshot) {
}
}
- @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
- justification = "https://github.com/spotbugs/spotbugs/issues/811")
- private void removePrefixShardReplica(final RemovePrefixShardReplica contextMessage, final String shardName,
- final String primaryPath, final ActorRef sender) {
- if (isShardReplicaOperationInProgress(shardName, sender)) {
- return;
- }
-
- shardReplicaOperationsInProgress.add(shardName);
-
- final ShardIdentifier shardId = getShardIdentifier(contextMessage.getMemberName(), shardName);
-
- final DatastoreContext datastoreContext = newShardDatastoreContextBuilder(shardName).build();
-
- //inform ShardLeader to remove this shard as a replica by sending an RemoveServer message
- LOG.debug("{}: Sending RemoveServer message to peer {} for shard {}", persistenceId(),
- primaryPath, shardId);
-
- Timeout removeServerTimeout = new Timeout(datastoreContext.getShardLeaderElectionTimeout().duration());
- Future<Object> futureObj = ask(getContext().actorSelection(primaryPath),
- new RemoveServer(shardId.toString()), removeServerTimeout);
-
- futureObj.onComplete(new OnComplete<>() {
- @Override
- public void onComplete(final Throwable failure, final Object response) {
- if (failure != null) {
- shardReplicaOperationsInProgress.remove(shardName);
-
- LOG.debug("{}: RemoveServer request to leader {} for shard {} failed", persistenceId(), primaryPath,
- shardName, failure);
-
- // FAILURE
- sender.tell(new Status.Failure(new RuntimeException(
- String.format("RemoveServer request to leader %s for shard %s failed", primaryPath, shardName),
- failure)), self());
- } else {
- // SUCCESS
- self().tell(new WrappedShardResponse(shardId, response, primaryPath), sender);
- }
- }
- }, new Dispatchers(context().system().dispatchers()).getDispatcher(Dispatchers.DispatcherType.Client));
- }
-
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
justification = "https://github.com/spotbugs/spotbugs/issues/811")
private void removeShardReplica(final RemoveShardReplica contextMessage, final String shardName,
return false;
}
- private void onAddPrefixShardReplica(final AddPrefixShardReplica message) {
- LOG.debug("{}: onAddPrefixShardReplica: {}", persistenceId(), message);
-
- final ShardIdentifier shardId = getShardIdentifier(cluster.getCurrentMemberName(),
- ClusterUtils.getCleanShardName(message.getShardPrefix()));
- final String shardName = shardId.getShardName();
-
- // Create the localShard
- if (schemaContext == null) {
- LOG.debug("{}: No SchemaContext is available in order to create a local shard instance for {}",
- persistenceId(), shardName);
- getSender().tell(new Status.Failure(new IllegalStateException(
- "No SchemaContext is available in order to create a local shard instance for " + shardName)),
- getSelf());
- return;
- }
-
- findPrimary(shardName, new AutoFindPrimaryFailureResponseHandler(getSender(), shardName, persistenceId(),
- getSelf()) {
- @Override
- public void onRemotePrimaryShardFound(final RemotePrimaryShardFound response) {
- final RunnableMessage runnable = (RunnableMessage) () -> addPrefixShard(getShardName(),
- message.getShardPrefix(), response, getSender());
- if (!isPreviousShardActorStopInProgress(getShardName(), runnable)) {
- getSelf().tell(runnable, getTargetActor());
- }
- }
-
- @Override
- public void onLocalPrimaryFound(final LocalPrimaryShardFound message) {
- sendLocalReplicaAlreadyExistsReply(getShardName(), getTargetActor());
- }
- });
- }
-
private void onAddShardReplica(final AddShardReplica shardReplicaMsg) {
final String shardName = shardReplicaMsg.getShardName();
String.format("Local shard %s already exists", shardName))), getSelf());
}
- @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
- justification = "https://github.com/spotbugs/spotbugs/issues/811")
- private void addPrefixShard(final String shardName, final YangInstanceIdentifier shardPrefix,
- final RemotePrimaryShardFound response, final ActorRef sender) {
- if (isShardReplicaOperationInProgress(shardName, sender)) {
- return;
- }
-
- shardReplicaOperationsInProgress.add(shardName);
-
- final ShardInformation shardInfo;
- final boolean removeShardOnFailure;
- ShardInformation existingShardInfo = localShards.get(shardName);
- if (existingShardInfo == null) {
- removeShardOnFailure = true;
- ShardIdentifier shardId = getShardIdentifier(cluster.getCurrentMemberName(), shardName);
-
- final Builder builder = newShardDatastoreContextBuilder(shardName);
- builder.storeRoot(shardPrefix).customRaftPolicyImplementation(DisableElectionsRaftPolicy.class.getName());
-
- DatastoreContext datastoreContext = builder.build();
-
- shardInfo = new ShardInformation(shardName, shardId, getPeerAddresses(shardName), datastoreContext,
- Shard.builder(), peerAddressResolver);
- shardInfo.setActiveMember(false);
- shardInfo.setSchemaContext(schemaContext);
- localShards.put(shardName, shardInfo);
- shardInfo.setActor(newShardActor(shardInfo));
- } else {
- removeShardOnFailure = false;
- shardInfo = existingShardInfo;
- }
-
- execAddShard(shardName, shardInfo, response, removeShardOnFailure, sender);
- }
-
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
justification = "https://github.com/spotbugs/spotbugs/issues/811")
private void addShard(final String shardName, final RemotePrimaryShardFound response, final ActorRef sender) {
});
}
- private void onRemovePrefixShardReplica(final RemovePrefixShardReplica message) {
- LOG.debug("{}: onRemovePrefixShardReplica: {}", persistenceId(), message);
-
- final ShardIdentifier shardId = getShardIdentifier(cluster.getCurrentMemberName(),
- ClusterUtils.getCleanShardName(message.getShardPrefix()));
- final String shardName = shardId.getShardName();
-
- findPrimary(shardName, new AutoFindPrimaryFailureResponseHandler(getSender(),
- shardName, persistenceId(), getSelf()) {
- @Override
- public void onRemotePrimaryShardFound(final RemotePrimaryShardFound response) {
- doRemoveShardReplicaAsync(response.getPrimaryPath());
- }
-
- @Override
- public void onLocalPrimaryFound(final LocalPrimaryShardFound response) {
- doRemoveShardReplicaAsync(response.getPrimaryPath());
- }
-
- private void doRemoveShardReplicaAsync(final String primaryPath) {
- getSelf().tell((RunnableMessage) () -> removePrefixShardReplica(message, getShardName(),
- primaryPath, getSender()), getTargetActor());
- }
- });
- }
-
private void persistShardList() {
List<String> shardList = new ArrayList<>(localShards.keySet());
for (ShardInformation shardInfo : localShards.values()) {
}
}
LOG.debug("{}: persisting the shard list {}", persistenceId(), shardList);
- saveSnapshot(updateShardManagerSnapshot(shardList, configuration.getAllPrefixShardConfigurations()));
+ saveSnapshot(updateShardManagerSnapshot(shardList));
}
- private ShardManagerSnapshot updateShardManagerSnapshot(
- final List<String> shardList,
- final Map<DOMDataTreeIdentifier, PrefixShardConfiguration> allPrefixShardConfigurations) {
- currentSnapshot = new ShardManagerSnapshot(shardList, allPrefixShardConfigurations);
+ private ShardManagerSnapshot updateShardManagerSnapshot(final List<String> shardList) {
+ currentSnapshot = new ShardManagerSnapshot(shardList);
return currentSnapshot;
}
import com.google.common.collect.ImmutableList;
import java.io.Serializable;
-import java.util.Collections;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
}
private Object readResolve() {
- return new org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot(shardList,
- Collections.emptyMap());
+ return new org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot(shardList);
}
@Override
public String findShard(YangInstanceIdentifier path) {
return DEFAULT_SHARD;
}
-
- @Override
- public YangInstanceIdentifier getPrefixForPath(YangInstanceIdentifier path) {
- return YangInstanceIdentifier.empty();
- }
}
String shardName = configuration.getShardNameForModule(moduleName);
return shardName != null ? shardName : DefaultShardStrategy.DEFAULT_SHARD;
}
-
- @Override
- public YangInstanceIdentifier getPrefixForPath(YangInstanceIdentifier path) {
- return YangInstanceIdentifier.empty();
- }
-
-
}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.cluster.datastore.shardstrategy;
-
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-/**
- * Shard Strategy that resolves a path to a prefix shard name.
- */
-public class PrefixShardStrategy implements ShardStrategy {
-
- public static final String NAME = "prefix";
-
- private final String shardName;
- private final YangInstanceIdentifier prefix;
-
- public PrefixShardStrategy(final String shardName,
- final YangInstanceIdentifier prefix) {
- this.shardName = shardName != null ? shardName : DefaultShardStrategy.DEFAULT_SHARD;
- this.prefix = prefix;
- }
-
- @Override
- public String findShard(final YangInstanceIdentifier path) {
- return shardName;
- }
-
- @Override
- public YangInstanceIdentifier getPrefixForPath(YangInstanceIdentifier path) {
- return prefix;
- }
-}
* @return the corresponding shard name.
*/
String findShard(YangInstanceIdentifier path);
-
- /**
- * Get the prefix of the shard that contains the data pointed to by the specified path.
- * @param path the location of the data in the logical tree.
- * @return the corresponding shards prefix.
- */
- YangInstanceIdentifier getPrefixForPath(YangInstanceIdentifier path);
}
import static java.util.Objects.requireNonNull;
import org.opendaylight.controller.cluster.datastore.config.Configuration;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
public class ShardStrategyFactory {
private static final String UNKNOWN_MODULE_NAME = "unknown";
private final Configuration configuration;
- private final LogicalDatastoreType logicalStoreType;
- public ShardStrategyFactory(final Configuration configuration, final LogicalDatastoreType logicalStoreType) {
+ public ShardStrategyFactory(final Configuration configuration) {
checkState(configuration != null, "configuration should not be missing");
this.configuration = configuration;
- this.logicalStoreType = requireNonNull(logicalStoreType);
}
public ShardStrategy getStrategy(final YangInstanceIdentifier path) {
- // try with the legacy module based shard mapping
final String moduleName = getModuleName(requireNonNull(path, "path should not be null"));
final ShardStrategy shardStrategy = configuration.getStrategyForModule(moduleName);
if (shardStrategy == null) {
- // retry with prefix based sharding
- final ShardStrategy strategyForPrefix =
- configuration.getStrategyForPrefix(new DOMDataTreeIdentifier(logicalStoreType, path));
- if (strategyForPrefix == null) {
- return DefaultShardStrategy.getInstance();
- }
- return strategyForPrefix;
+ return DefaultShardStrategy.getInstance();
}
return shardStrategy;
import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategyFactory;
import org.opendaylight.controller.cluster.raft.client.messages.Shutdown;
import org.opendaylight.controller.cluster.reporting.MetricsReporter;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.yangtools.yang.data.api.schema.tree.ReadOnlyDataTree;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.slf4j.Logger;
this.datastoreContext = datastoreContext;
this.dispatchers = new Dispatchers(actorSystem.dispatchers());
this.primaryShardInfoCache = primaryShardInfoCache;
-
- final LogicalDatastoreType convertedType =
- LogicalDatastoreType.valueOf(datastoreContext.getLogicalStoreType().name());
- this.shardStrategyFactory = new ShardStrategyFactory(configuration, convertedType);
+ this.shardStrategyFactory = new ShardStrategyFactory(configuration);
setCachedProperties();
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.datastore.utils;
-
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utils for encoding prefix shard name.
- */
-public final class ClusterUtils {
- private static final Logger LOG = LoggerFactory.getLogger(ClusterUtils.class);
-
- // id for the shard used to store prefix configuration
- public static final String PREFIX_CONFIG_SHARD_ID = "prefix-configuration-shard";
-
- public static final QName PREFIX_SHARDS_QNAME =
- QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:clustering:prefix-shard-configuration",
- "2017-01-10", "prefix-shards").intern();
- public static final QName SHARD_LIST_QNAME =
- QName.create(PREFIX_SHARDS_QNAME, "shard").intern();
- public static final QName SHARD_PREFIX_QNAME =
- QName.create(PREFIX_SHARDS_QNAME, "prefix").intern();
- public static final QName SHARD_REPLICAS_QNAME =
- QName.create(PREFIX_SHARDS_QNAME, "replicas").intern();
- public static final QName SHARD_REPLICA_QNAME =
- QName.create(PREFIX_SHARDS_QNAME, "replica").intern();
-
- public static final YangInstanceIdentifier PREFIX_SHARDS_PATH =
- YangInstanceIdentifier.of(PREFIX_SHARDS_QNAME).toOptimized();
- public static final YangInstanceIdentifier SHARD_LIST_PATH =
- PREFIX_SHARDS_PATH.node(SHARD_LIST_QNAME).toOptimized();
-
- private ClusterUtils() {
- }
-
- public static ShardIdentifier getShardIdentifier(final MemberName memberName, final DOMDataTreeIdentifier prefix) {
- final String type;
- switch (prefix.getDatastoreType()) {
- case OPERATIONAL:
- type = "operational";
- break;
- case CONFIGURATION:
- type = "config";
- break;
- default:
- type = prefix.getDatastoreType().name();
- LOG.warn("Unknown data store type {}", type);
- }
-
- return ShardIdentifier.create(getCleanShardName(prefix.getRootIdentifier()), memberName, type);
- }
-
- /**
- * Returns an encoded shard name based on the provided path that should doesn't contain characters that cannot be
- * present in akka actor paths.
- *
- * @param path Path on which to base the shard name
- * @return encoded name that doesn't contain characters that cannot be in actor path.
- */
- public static String getCleanShardName(final YangInstanceIdentifier path) {
- if (path.isEmpty()) {
- return "default";
- }
-
- final StringBuilder builder = new StringBuilder();
- // TODO need a better mapping that includes namespace, but we'll need to cleanup the string beforehand
- // we have to fight both javax and akka url path restrictions..
- path.getPathArguments().forEach(p -> {
- builder.append(p.getNodeType().getLocalName());
- if (p instanceof NodeIdentifierWithPredicates) {
- builder.append("-key_");
- ((NodeIdentifierWithPredicates) p).entrySet().forEach(entry -> {
- builder.append(entry.getKey().getLocalName()).append(entry.getValue()).append('-');
- });
- builder.append('_');
- }
- builder.append('!');
- });
- return builder.toString();
- }
-}
+++ /dev/null
-module prefix-shard-configuration {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:clustering:prefix-shard-configuration";
- prefix "prefix-config";
-
- description
- "This module contains the base YANG definitions for
- shards based on prefix configuration";
-
- revision "2017-01-10" {
- description "Initial revision.";
- }
-
- container prefix-shards {
-
- list shard {
- key prefix;
- leaf prefix {
- type instance-identifier;
- description "Prefix that this shard is rooted at.";
- }
-
- container replicas {
- leaf-list replica {
- type string;
- }
-
- description "List of cluster member nodes that this shard is replicated on";
- }
-
- description "List of prefix-based shards configured.";
- }
- }
-}
import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
import org.opendaylight.controller.md.cluster.datastore.model.CarsModel;
import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.common.api.ReadFailedException;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
public String findShard(final YangInstanceIdentifier path) {
return TestModel.JUNK_QNAME.getLocalName();
}
-
- @Override
- public YangInstanceIdentifier getPrefixForPath(final YangInstanceIdentifier path) {
- return YangInstanceIdentifier.empty();
- }
}).put(
CarsModel.BASE_QNAME.getLocalName(), new ShardStrategy() {
@Override
public String findShard(final YangInstanceIdentifier path) {
return CarsModel.BASE_QNAME.getLocalName();
}
-
- @Override
- public YangInstanceIdentifier getPrefixForPath(final YangInstanceIdentifier path) {
- return YangInstanceIdentifier.empty();
- }
}).build();
@Override
doReturn(getSystem()).when(mockActorContext).getActorSystem();
doReturn(getSystem().dispatchers().defaultGlobalDispatcher()).when(mockActorContext).getClientDispatcher();
doReturn(MemberName.forName(memberName)).when(mockActorContext).getCurrentMemberName();
- doReturn(new ShardStrategyFactory(configuration,
- LogicalDatastoreType.CONFIGURATION)).when(mockActorContext).getShardStrategyFactory();
+ doReturn(new ShardStrategyFactory(configuration)).when(mockActorContext).getShardStrategyFactory();
doReturn(SCHEMA_CONTEXT).when(mockActorContext).getSchemaContext();
doReturn(new Timeout(operationTimeoutInSeconds, TimeUnit.SECONDS)).when(mockActorContext).getOperationTimeout();
doReturn(mockClusterWrapper).when(mockActorContext).getClusterWrapper();
}
private static ShardManagerSnapshot newShardManagerSnapshot(final String... shards) {
- return new ShardManagerSnapshot(Arrays.asList(shards), Collections.emptyMap());
+ return new ShardManagerSnapshot(Arrays.asList(shards));
}
private static Snapshot newSnapshot(final YangInstanceIdentifier path, final NormalizedNode node) throws Exception {
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
-import java.util.Collections;
import org.apache.commons.lang.SerializationUtils;
import org.junit.Test;
@Test
public void testSerialization() {
ShardManagerSnapshot expected =
- new ShardManagerSnapshot(Arrays.asList("shard1", "shard2"), Collections.emptyMap());
+ new ShardManagerSnapshot(Arrays.asList("shard1", "shard2"));
ShardManagerSnapshot cloned = (ShardManagerSnapshot) SerializationUtils.clone(expected);
assertEquals("getShardList", expected.getShardList(), cloned.getShardList());
TestKit kit = new TestKit(getSystem());
List<String> shardList = Arrays.asList("shard1", "shard2", "shard3");
- ShardManagerSnapshot shardManagerSnapshot = new ShardManagerSnapshot(shardList, Collections.emptyMap());
+ ShardManagerSnapshot shardManagerSnapshot = new ShardManagerSnapshot(shardList);
ActorRef replyActor = getSystem().actorOf(ShardManagerGetSnapshotReplyActor.props(
shardList, "config", shardManagerSnapshot, kit.getRef(),
"shard-manager", FiniteDuration.create(100, TimeUnit.SECONDS)), "testSuccess");
.put("astronauts", Collections.<String>emptyList()).build());
ShardManagerSnapshot snapshot =
- new ShardManagerSnapshot(Arrays.asList("shard1", "shard2", "astronauts"), Collections.emptyMap());
+ new ShardManagerSnapshot(Arrays.asList("shard1", "shard2", "astronauts"));
DatastoreSnapshot restoreFromSnapshot = new DatastoreSnapshot(shardMrgIDSuffix, snapshot,
Collections.<ShardSnapshot>emptyList());
TestActorRef<TestShardManager> shardManager = actorFactory.createTestActor(newTestShardMgrBuilder(mockConfig)
// persisted.
String[] restoredShards = { "default", "people" };
ShardManagerSnapshot snapshot =
- new ShardManagerSnapshot(Arrays.asList(restoredShards), Collections.emptyMap());
+ new ShardManagerSnapshot(Arrays.asList(restoredShards));
InMemorySnapshotStore.addSnapshot(shardManagerID, snapshot);
Uninterruptibles.sleepUninterruptibly(2, TimeUnit.MILLISECONDS);
.put("people", Arrays.asList("member-1", "member-2")).build());
String[] restoredShards = {"default", "astronauts"};
ShardManagerSnapshot snapshot =
- new ShardManagerSnapshot(Arrays.asList(restoredShards), Collections.emptyMap());
+ new ShardManagerSnapshot(Arrays.asList(restoredShards));
InMemorySnapshotStore.addSnapshot("shard-manager-" + shardMrgIDSuffix, snapshot);
// create shardManager to come up with restored data
import org.opendaylight.controller.cluster.datastore.config.ConfigurationImpl;
import org.opendaylight.controller.md.cluster.datastore.model.CarsModel;
import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
public class ShardStrategyFactoryTest {
@Before
public void setUp() {
- factory = new ShardStrategyFactory(new ConfigurationImpl("module-shards.conf", "modules.conf"),
- LogicalDatastoreType.CONFIGURATION);
+ factory = new ShardStrategyFactory(new ConfigurationImpl("module-shards.conf", "modules.conf"));
}
@Test
import org.opendaylight.controller.cluster.access.concepts.MemberName;
import org.opendaylight.controller.cluster.datastore.config.ConfigurationImpl;
import org.opendaylight.controller.cluster.datastore.config.ModuleConfig;
-import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategy;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
public class MockConfiguration extends ConfigurationImpl {
public MockConfiguration() {
return retMap;
});
}
-
- @Override
- public ShardStrategy getStrategyForPrefix(final DOMDataTreeIdentifier prefix) {
- return null;
- }
}
public static EffectiveModelContext select(final String... schemaFiles) {
return YangParserTestUtils.parseYangResources(SchemaContextHelper.class, schemaFiles);
}
-
- public static EffectiveModelContext distributedShardedDOMDataTreeSchemaContext() {
- // we need prefix-shard-configuration and odl-datastore-test models
- // for DistributedShardedDOMDataTree tests
- return YangParserTestUtils.parseYangResources(SchemaContextHelper.class, ODL_DATASTORE_TEST_YANG,
- "/META-INF/yang/prefix-shard-configuration@2017-01-10.yang");
- }
}
}
}
- rpc produce-transactions {
- description "Upon receiving this, the member shall make sure the outer list item
- of llt:in-ints exists for the given id, make sure a shard for
- the whole (config) id-ints is created (by creating and closing producer
- for the whole id-ints), and create a DOMDataTreeProducer for that item (using that shard).
-
- FIXME: Is the above the normal way of creating prefix-based chards?
-
- Then start creating (one by one) and submitting transactions
- to randomly add or delete items on the inner list for that id.
- To ensure balanced number of deletes, the first write can create
- a random set of random numbers. Other writes shall be one per number.
- The writes shall use DOMDataTreeProducer API, as opposed to transaction (chains)
- created directly on datastore.
- .get with a timeout on currently earliest non-complete Future (from .submit)
- shall be used as the primary wait method to throttle the submission rate.
- This RPC shall not return until all transactions are confirmed successful,
- or an exception is raised (the exception should propagate to restconf response).
- OptimisticLockException is always considered an error.
- In either case, the producer should be closed before returning,
- but the shard and the whole id item shall be kept as they are.";
- input {
- uses llc:id-grouping;
- uses transactions-params;
- leaf isolated-transactions {
- description "The value for DOMDataTreeProducer#createTransaction argument.";
- mandatory true;
- type boolean;
- }
- }
- output {
- uses transactions-result;
- }
- }
-
- rpc create-prefix-shard {
- description "Upon receiving this, the member creates a prefix shard at the instance-identifier, with replicas
- on the required members.";
- input {
-
- leaf prefix {
- mandatory true;
- type instance-identifier;
- }
- leaf-list replicas {
- min-elements 1;
- type string;
- }
- }
- }
-
- rpc remove-prefix-shard {
- description "Upon receiving this, the member removes the prefix based shard identifier by this prefix.
- This must be called from the same node that created the shard.";
-
- input {
- leaf prefix {
- mandatory true;
- type instance-identifier;
- }
- }
- }
-
-
- rpc become-prefix-leader {
- description "Upon receiving this, the member shall ask the appropriate API
- to become Leader of the given shard (presumably the llt:list-ints one,
- created by produce-transactions) and return immediatelly.";
- input {
- leaf prefix {
- mandatory true;
- type instance-identifier;
- }
- }
- // No output.
- }
-
rpc remove-shard-replica {
description "A specialised copy of cluster-admin:remove-shard-replica.
// The following calls are not required for Carbon testing.
- rpc deconfigure-id-ints-shard {
- description "Upon receiving this, the member shall ask the appropriate API
- to remove the llt:id-ints shard (presumably created by produce-transactions)
- and return immediatelly.
- It is expected the data would move to the root prefix shard seamlessly.
-
- TODO: Make shard name configurable by input?";
- // No input.
- // No output.
- }
-
rpc register-default-constant {
description "Upon receiving this, the member has to create and register
a default llt:get-contexted-constant implementation (routed RPC).
}
}
}
-
- rpc shutdown-prefix-shard-replica {
- description "Upon receiving this, the member will try to gracefully shutdown local configuration
- data store prefix-based shard replica.";
- input {
- leaf prefix {
- description "The prefix of the configuration data store prefix-based shard to be shutdown
- gracefully.";
- mandatory true;
- type instance-identifier;
- }
- }
- }
}
import org.opendaylight.controller.cluster.ActorSystemProvider;
import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
-import org.opendaylight.controller.cluster.datastore.utils.ClusterUtils;
import org.opendaylight.controller.cluster.raft.client.messages.Shutdown;
import org.opendaylight.controller.clustering.it.provider.impl.FlappingSingletonService;
import org.opendaylight.controller.clustering.it.provider.impl.GetConstantService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.AddShardReplicaInput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.AddShardReplicaOutput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.BecomePrefixLeaderInput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.BecomePrefixLeaderOutput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.CheckPublishNotificationsInput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.CheckPublishNotificationsOutput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.CheckPublishNotificationsOutputBuilder;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.CreatePrefixShardInput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.CreatePrefixShardOutput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.DeconfigureIdIntsShardInput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.DeconfigureIdIntsShardOutput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.IsClientAbortedInput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.IsClientAbortedOutput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.OdlMdsalLowlevelControlService;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ProduceTransactionsInput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ProduceTransactionsOutput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterBoundConstantInput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterBoundConstantOutput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterBoundConstantOutputBuilder;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterSingletonConstantInput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterSingletonConstantOutput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RegisterSingletonConstantOutputBuilder;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RemovePrefixShardInput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RemovePrefixShardOutput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RemoveShardReplicaInput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.RemoveShardReplicaOutput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownPrefixShardReplicaInput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownPrefixShardReplicaOutput;
-import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownPrefixShardReplicaOutputBuilder;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownShardReplicaInput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownShardReplicaOutput;
import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.ShutdownShardReplicaOutputBuilder;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return RpcResultBuilder.success(new SubscribeYnlOutputBuilder().build()).buildFuture();
}
- @Override
- public ListenableFuture<RpcResult<RemovePrefixShardOutput>> removePrefixShard(final RemovePrefixShardInput input) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ListenableFuture<RpcResult<BecomePrefixLeaderOutput>> becomePrefixLeader(
- final BecomePrefixLeaderInput input) {
- throw new UnsupportedOperationException();
- }
@Override
public ListenableFuture<RpcResult<UnregisterBoundConstantOutput>> unregisterBoundConstant(
}
}
- @Override
- public ListenableFuture<RpcResult<CreatePrefixShardOutput>> createPrefixShard(final CreatePrefixShardInput input) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ListenableFuture<RpcResult<DeconfigureIdIntsShardOutput>> deconfigureIdIntsShard(
- final DeconfigureIdIntsShardInput input) {
- return null;
- }
-
@Override
public ListenableFuture<RpcResult<UnsubscribeYnlOutput>> unsubscribeYnl(final UnsubscribeYnlInput input) {
LOG.info("In unsubscribeYnl - input: {}", input);
return RpcResultBuilder.success(output).buildFuture();
}
- @Override
- public ListenableFuture<RpcResult<ProduceTransactionsOutput>> produceTransactions(
- final ProduceTransactionsInput input) {
- throw new UnsupportedOperationException();
- }
-
@Override
public ListenableFuture<RpcResult<ShutdownShardReplicaOutput>> shutdownShardReplica(
final ShutdownShardReplicaInput input) {
return shutdownShardGracefully(shardName, new ShutdownShardReplicaOutputBuilder().build());
}
- @Override
- public ListenableFuture<RpcResult<ShutdownPrefixShardReplicaOutput>> shutdownPrefixShardReplica(
- final ShutdownPrefixShardReplicaInput input) {
- LOG.info("shutdownPrefixShardReplica - input: {}", input);
-
- final InstanceIdentifier<?> shardPrefix = input.getPrefix();
-
- if (shardPrefix == null) {
- return RpcResultBuilder.<ShutdownPrefixShardReplicaOutput>failed().withError(ErrorType.RPC, "bad-element",
- "A valid shard prefix must be specified").buildFuture();
- }
-
- final YangInstanceIdentifier shardPath = bindingNormalizedNodeSerializer.toYangInstanceIdentifier(shardPrefix);
- final String cleanPrefixShardName = ClusterUtils.getCleanShardName(shardPath);
-
- return shutdownShardGracefully(cleanPrefixShardName, new ShutdownPrefixShardReplicaOutputBuilder().build());
- }
-
private <T> SettableFuture<RpcResult<T>> shutdownShardGracefully(final String shardName, final T success) {
final SettableFuture<RpcResult<T>> rpcResult = SettableFuture.create();
final ActorUtils context = configDataStore.getActorUtils();