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=c1f687bd55f2bff272b1b6a405c6780047344161;hb=b5cb353e3553a39f576c284119af75ffa5ea66a9;hp=d88301c308d39a7944d3d058ed4cb5825c5d60f3;hpb=285e83f59f15a4a614d423a3780a607d562d030b;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 d88301c308..c1f687bd55 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 @@ -11,6 +11,7 @@ package org.opendaylight.controller.cluster.datastore.config; import com.google.common.base.Preconditions; 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,13 +19,25 @@ 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 javax.annotation.Nonnull; +import javax.annotation.Nullable; +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; @@ -36,7 +49,7 @@ public class ConfigurationImpl implements Configuration { public ConfigurationImpl(final ModuleShardConfigProvider provider) { ImmutableMap.Builder mapBuilder = ImmutableMap.builder(); - for(Map.Entry e: provider.retrieveModuleConfigs(this).entrySet()) { + for (Map.Entry e: provider.retrieveModuleConfigs(this).entrySet()) { mapBuilder.put(e.getKey(), e.getValue().build()); } @@ -48,7 +61,7 @@ public class ConfigurationImpl implements Configuration { private static Set createAllShardNames(Iterable moduleConfigs) { final ImmutableSet.Builder builder = ImmutableSet.builder(); - for(ModuleConfig moduleConfig : moduleConfigs) { + for (ModuleConfig moduleConfig : moduleConfigs) { builder.addAll(moduleConfig.getShardNames()); } @@ -57,9 +70,9 @@ public class ConfigurationImpl implements Configuration { private static Map createNamespaceToModuleName(Iterable moduleConfigs) { final ImmutableMap.Builder builder = ImmutableMap.builder(); - for(ModuleConfig moduleConfig : moduleConfigs) { - if(moduleConfig.getNameSpace() != null) { - builder.put(moduleConfig.getNameSpace(), moduleConfig.getName()); + for (ModuleConfig moduleConfig : moduleConfigs) { + if (moduleConfig.getNamespace() != null) { + builder.put(moduleConfig.getNamespace(), moduleConfig.getName()); } } @@ -67,13 +80,13 @@ public class ConfigurationImpl implements Configuration { } @Override - public Collection getMemberShardNames(final String memberName){ + public Collection getMemberShardNames(final MemberName memberName) { Preconditions.checkNotNull(memberName, "memberName should not be null"); List shards = new ArrayList<>(); - for(ModuleConfig moduleConfig: moduleConfigMap.values()) { - for(ShardConfig shardConfig: moduleConfig.getShardConfigs()) { - if(shardConfig.getReplicas().contains(memberName)) { + for (ModuleConfig moduleConfig: moduleConfigMap.values()) { + for (ShardConfig shardConfig: moduleConfig.getShardConfigs()) { + if (shardConfig.getReplicas().contains(memberName)) { shards.add(shardConfig.getName()); } } @@ -94,7 +107,7 @@ public class ConfigurationImpl implements Configuration { Preconditions.checkNotNull(moduleName, "moduleName should not be null"); ModuleConfig moduleConfig = moduleConfigMap.get(moduleName); - return moduleConfig != null ? moduleConfig.getShardStrategy(): null; + return moduleConfig != null ? moduleConfig.getShardStrategy() : null; } @Override @@ -104,20 +117,46 @@ public class ConfigurationImpl implements Configuration { ModuleConfig moduleConfig = moduleConfigMap.get(moduleName); Collection shardConfigs = moduleConfig != null ? moduleConfig.getShardConfigs() : Collections.emptySet(); - return !shardConfigs.isEmpty() ? shardConfigs.iterator().next().getName(): null; + return !shardConfigs.isEmpty() ? shardConfigs.iterator().next().getName() : null; + } + + @Nullable + @Override + public String getShardNameForPrefix(@Nonnull final DOMDataTreeIdentifier prefix) { + Preconditions.checkNotNull(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) { + public Collection getMembersFromShardName(final String shardName) { Preconditions.checkNotNull(shardName, "shardName should not be null"); - for(ModuleConfig moduleConfig: moduleConfigMap.values()) { + for (ModuleConfig moduleConfig: moduleConfigMap.values()) { ShardConfig shardConfig = moduleConfig.getShardConfig(shardName); - if(shardConfig != null) { + if (shardConfig != null) { return shardConfig.getReplicas(); } } + for (final PrefixShardConfiguration prefixConfig : prefixConfigMap.values()) { + if (shardName.equals(ClusterUtils.getCleanShardName(prefixConfig.getPrefix().getRootIdentifier()))) { + return prefixConfig.getShardMemberNames(); + } + } + return Collections.emptyList(); } @@ -127,9 +166,9 @@ public class ConfigurationImpl implements Configuration { } @Override - public Collection getUniqueMemberNamesForAllShards() { - Set allNames = new HashSet<>(); - for(String shardName: getAllShardNames()) { + public Collection getUniqueMemberNamesForAllShards() { + Set allNames = new HashSet<>(); + for (String shardName: getAllShardNames()) { allNames.addAll(getMembersFromShardName(shardName)); } @@ -140,18 +179,55 @@ public class ConfigurationImpl implements Configuration { public synchronized void addModuleShardConfiguration(ModuleShardConfiguration config) { Preconditions.checkNotNull(config, "ModuleShardConfiguration should not be null"); - ModuleConfig moduleConfig = ModuleConfig.builder(config.getModuleName()). - nameSpace(config.getNamespace().toASCIIString()). - shardStrategy(createShardStrategy(config.getModuleName(), config.getShardStrategyName())). - shardConfig(config.getShardName(), config.getShardMemberNames()).build(); + ModuleConfig moduleConfig = ModuleConfig.builder(config.getModuleName()) + .nameSpace(config.getNamespace().toASCIIString()) + .shardStrategy(createShardStrategy(config.getModuleName(), config.getShardStrategyName())) + .shardConfig(config.getShardName(), config.getShardMemberNames()).build(); updateModuleConfigMap(moduleConfig); - namespaceToModuleName = ImmutableMap.builder().putAll(namespaceToModuleName). - put(moduleConfig.getNameSpace(), moduleConfig.getName()).build(); + namespaceToModuleName = ImmutableMap.builder().putAll(namespaceToModuleName) + .put(moduleConfig.getNamespace(), moduleConfig.getName()).build(); allShardNames = ImmutableSet.builder().addAll(allShardNames).add(config.getShardName()).build(); } + @Override + public void addPrefixShardConfiguration(@Nonnull final PrefixShardConfiguration config) { + Preconditions.checkNotNull(config, "PrefixShardConfiguration cannot be null"); + addPrefixConfig(config); + allShardNames = ImmutableSet.builder().addAll(allShardNames) + .add(ClusterUtils.getCleanShardName(config.getPrefix().getRootIdentifier())).build(); + } + + @Override + public void removePrefixShardConfiguration(@Nonnull final DOMDataTreeIdentifier prefix) { + Preconditions.checkNotNull(prefix, "Prefix cannot be null"); + + removePrefixConfig(prefix); + + 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(String moduleName, String shardStrategyName) { return ShardStrategyFactory.newShardStrategyInstance(moduleName, shardStrategyName, this); } @@ -163,14 +239,14 @@ public class ConfigurationImpl implements Configuration { } @Override - public void addMemberReplicaForShard (String shardName, String newMemberName) { + public void addMemberReplicaForShard(String shardName, MemberName newMemberName) { Preconditions.checkNotNull(shardName, "shardName should not be null"); Preconditions.checkNotNull(newMemberName, "MemberName should not be null"); - for(ModuleConfig moduleConfig: moduleConfigMap.values()) { + for (ModuleConfig moduleConfig: moduleConfigMap.values()) { ShardConfig shardConfig = moduleConfig.getShardConfig(shardName); - if(shardConfig != null) { - Set replicas = new HashSet<>(shardConfig.getReplicas()); + if (shardConfig != null) { + Set replicas = new HashSet<>(shardConfig.getReplicas()); replicas.add(newMemberName); updateModuleConfigMap(ModuleConfig.builder(moduleConfig).shardConfig(shardName, replicas).build()); return; @@ -179,14 +255,14 @@ public class ConfigurationImpl implements Configuration { } @Override - public void removeMemberReplicaForShard (String shardName, String newMemberName) { + public void removeMemberReplicaForShard(String shardName, MemberName newMemberName) { Preconditions.checkNotNull(shardName, "shardName should not be null"); Preconditions.checkNotNull(newMemberName, "MemberName should not be null"); - for(ModuleConfig moduleConfig: moduleConfigMap.values()) { + for (ModuleConfig moduleConfig: moduleConfigMap.values()) { ShardConfig shardConfig = moduleConfig.getShardConfig(shardName); - if(shardConfig != null) { - Set replicas = new HashSet<>(shardConfig.getReplicas()); + if (shardConfig != null) { + Set replicas = new HashSet<>(shardConfig.getReplicas()); replicas.remove(newMemberName); updateModuleConfigMap(ModuleConfig.builder(moduleConfig).shardConfig(shardName, replicas).build()); return; @@ -194,8 +270,31 @@ public class ConfigurationImpl implements Configuration { } } - private void updateModuleConfigMap(ModuleConfig moduleConfig) { - Map newModuleConfigMap = new HashMap<>(moduleConfigMap); + @Override + public ShardStrategy getStrategyForPrefix(@Nonnull final DOMDataTreeIdentifier prefix) { + Preconditions.checkNotNull(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); }