X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2Fconfig%2FConfigurationImpl.java;h=fcfa615f7e1487d245f2676cbdf9ba405e11e66c;hb=422ac9fbe65c02f942c1fed41ff4aa96545f4224;hp=2038495c5819ffdd0d48e7385786c5c186908fb5;hpb=057b787289f7b909d7013c22ac73a1c91c860af8;p=controller.git diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/config/ConfigurationImpl.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/config/ConfigurationImpl.java index 2038495c58..fcfa615f7e 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/config/ConfigurationImpl.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/config/ConfigurationImpl.java @@ -5,12 +5,13 @@ * 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 com.google.common.base.Preconditions; +import static java.util.Objects.requireNonNull; + 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; @@ -18,14 +19,23 @@ import java.util.HashMap; 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 moduleConfigMap; + // TODO should this be initialized with something? on restart we should restore the shards from configuration? + private volatile Map prefixConfigMap = Collections.emptyMap(); + // Look up maps to speed things up private volatile Map namespaceToModuleName; @@ -47,7 +57,7 @@ public class ConfigurationImpl implements Configuration { this.namespaceToModuleName = createNamespaceToModuleName(moduleConfigMap.values()); } - private static Set createAllShardNames(Iterable moduleConfigs) { + private static Set createAllShardNames(final Iterable moduleConfigs) { final ImmutableSet.Builder builder = ImmutableSet.builder(); for (ModuleConfig moduleConfig : moduleConfigs) { builder.addAll(moduleConfig.getShardNames()); @@ -56,7 +66,7 @@ public class ConfigurationImpl implements Configuration { return builder.build(); } - private static Map createNamespaceToModuleName(Iterable moduleConfigs) { + private static Map createNamespaceToModuleName(final Iterable moduleConfigs) { final ImmutableMap.Builder builder = ImmutableMap.builder(); for (ModuleConfig moduleConfig : moduleConfigs) { if (moduleConfig.getNamespace() != null) { @@ -69,7 +79,7 @@ public class ConfigurationImpl implements Configuration { @Override public Collection getMemberShardNames(final MemberName memberName) { - Preconditions.checkNotNull(memberName, "memberName should not be null"); + requireNonNull(memberName, "memberName should not be null"); List shards = new ArrayList<>(); for (ModuleConfig moduleConfig: moduleConfigMap.values()) { @@ -85,14 +95,14 @@ public class ConfigurationImpl implements Configuration { @Override public String getModuleNameFromNameSpace(final String nameSpace) { - Preconditions.checkNotNull(nameSpace, "nameSpace should not be null"); + requireNonNull(nameSpace, "nameSpace should not be null"); return namespaceToModuleName.get(nameSpace); } @Override - public ShardStrategy getStrategyForModule(String moduleName) { - Preconditions.checkNotNull(moduleName, "moduleName should not be null"); + public ShardStrategy getStrategyForModule(final String moduleName) { + requireNonNull(moduleName, "moduleName should not be null"); ModuleConfig moduleConfig = moduleConfigMap.get(moduleName); return moduleConfig != null ? moduleConfig.getShardStrategy() : null; @@ -100,7 +110,7 @@ public class ConfigurationImpl implements Configuration { @Override public String getShardNameForModule(final String moduleName) { - Preconditions.checkNotNull(moduleName, "moduleName should not be null"); + requireNonNull(moduleName, "moduleName should not be null"); ModuleConfig moduleConfig = moduleConfigMap.get(moduleName); Collection shardConfigs = moduleConfig != null ? moduleConfig.getShardConfigs() : @@ -108,9 +118,27 @@ public class ConfigurationImpl implements Configuration { return !shardConfigs.isEmpty() ? shardConfigs.iterator().next().getName() : null; } + @Override + public String getShardNameForPrefix(final DOMDataTreeIdentifier prefix) { + requireNonNull(prefix, "prefix should not be null"); + + Entry bestMatchEntry = new SimpleEntry<>( + new DOMDataTreeIdentifier(prefix.getDatastoreType(), YangInstanceIdentifier.empty()), null); + + for (Entry 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 getMembersFromShardName(final String shardName) { - Preconditions.checkNotNull(shardName, "shardName should not be null"); + checkNotNullShardName(shardName); for (ModuleConfig moduleConfig: moduleConfigMap.values()) { ShardConfig shardConfig = moduleConfig.getShardConfig(shardName); @@ -119,9 +147,19 @@ public class ConfigurationImpl implements Configuration { } } + for (final PrefixShardConfiguration prefixConfig : prefixConfigMap.values()) { + if (shardName.equals(ClusterUtils.getCleanShardName(prefixConfig.getPrefix().getRootIdentifier()))) { + return prefixConfig.getShardMemberNames(); + } + } + return Collections.emptyList(); } + private static void checkNotNullShardName(final String shardName) { + requireNonNull(shardName, "shardName should not be null"); + } + @Override public Set getAllShardNames() { return allShardNames; @@ -138,8 +176,8 @@ public class ConfigurationImpl implements Configuration { } @Override - public synchronized void addModuleShardConfiguration(ModuleShardConfiguration config) { - Preconditions.checkNotNull(config, "ModuleShardConfiguration should not be null"); + public synchronized void addModuleShardConfiguration(final ModuleShardConfiguration config) { + requireNonNull(config, "ModuleShardConfiguration should not be null"); ModuleConfig moduleConfig = ModuleConfig.builder(config.getModuleName()) .nameSpace(config.getNamespace().toASCIIString()) @@ -153,20 +191,54 @@ public class ConfigurationImpl implements Configuration { allShardNames = ImmutableSet.builder().addAll(allShardNames).add(config.getShardName()).build(); } - private ShardStrategy createShardStrategy(String moduleName, String shardStrategyName) { + @Override + public void addPrefixShardConfiguration(final PrefixShardConfiguration config) { + addPrefixConfig(requireNonNull(config, "PrefixShardConfiguration cannot be null")); + allShardNames = ImmutableSet.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 temp = new HashSet<>(allShardNames); + temp.remove(ClusterUtils.getCleanShardName(prefix.getRootIdentifier())); + + allShardNames = ImmutableSet.copyOf(temp); + } + + @Override + public Map getAllPrefixShardConfigurations() { + return ImmutableMap.copyOf(prefixConfigMap); + } + + private void addPrefixConfig(final PrefixShardConfiguration config) { + final Map newPrefixConfigMap = new HashMap<>(prefixConfigMap); + newPrefixConfigMap.put(config.getPrefix(), config); + prefixConfigMap = ImmutableMap.copyOf(newPrefixConfigMap); + } + + private void removePrefixConfig(final DOMDataTreeIdentifier prefix) { + final Map 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 boolean isShardConfigured(String shardName) { - Preconditions.checkNotNull(shardName, "shardName should not be null"); + public boolean isShardConfigured(final String shardName) { + checkNotNullShardName(shardName); return allShardNames.contains(shardName); } @Override - public void addMemberReplicaForShard(String shardName, MemberName newMemberName) { - Preconditions.checkNotNull(shardName, "shardName should not be null"); - Preconditions.checkNotNull(newMemberName, "MemberName should not be null"); + public void addMemberReplicaForShard(final String shardName, final MemberName newMemberName) { + checkNotNullShardName(shardName); + requireNonNull(newMemberName, "MemberName should not be null"); for (ModuleConfig moduleConfig: moduleConfigMap.values()) { ShardConfig shardConfig = moduleConfig.getShardConfig(shardName); @@ -180,9 +252,9 @@ public class ConfigurationImpl implements Configuration { } @Override - public void removeMemberReplicaForShard(String shardName, MemberName newMemberName) { - Preconditions.checkNotNull(shardName, "shardName should not be null"); - Preconditions.checkNotNull(newMemberName, "MemberName should not be null"); + public void removeMemberReplicaForShard(final String shardName, final MemberName newMemberName) { + checkNotNullShardName(shardName); + requireNonNull(newMemberName, "MemberName should not be null"); for (ModuleConfig moduleConfig: moduleConfigMap.values()) { ShardConfig shardConfig = moduleConfig.getShardConfig(shardName); @@ -195,8 +267,30 @@ public class ConfigurationImpl implements Configuration { } } - private void updateModuleConfigMap(ModuleConfig moduleConfig) { - Map newModuleConfigMap = new HashMap<>(moduleConfigMap); + @Override + public ShardStrategy getStrategyForPrefix(final DOMDataTreeIdentifier prefix) { + requireNonNull(prefix, "Prefix cannot be null"); + // FIXME using prefix tables like in mdsal will be better + Entry bestMatchEntry = new SimpleEntry<>( + new DOMDataTreeIdentifier(prefix.getDatastoreType(), YangInstanceIdentifier.empty()), null); + + for (Entry 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 newModuleConfigMap = new HashMap<>(moduleConfigMap); newModuleConfigMap.put(moduleConfig.getName(), moduleConfig); moduleConfigMap = ImmutableMap.copyOf(newModuleConfigMap); }