Optimize getModuleNameToShardStrategyMap()
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / ConfigurationImpl.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.cluster.datastore;
10
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.collect.ImmutableList;
14 import com.google.common.collect.ImmutableList.Builder;
15 import com.google.common.collect.ImmutableMap;
16 import com.typesafe.config.Config;
17 import com.typesafe.config.ConfigFactory;
18 import com.typesafe.config.ConfigObject;
19 import java.io.File;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.LinkedHashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import org.opendaylight.controller.cluster.datastore.shardstrategy.DefaultShardStrategy;
28 import org.opendaylight.controller.cluster.datastore.shardstrategy.ModuleShardStrategy;
29 import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategy;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 public class ConfigurationImpl implements Configuration {
34
35     private final List<ModuleShard> moduleShards;
36
37     private final List<Module> modules;
38
39     private static final Logger
40         LOG = LoggerFactory.getLogger(DistributedDataStore.class);
41
42     // Look up maps to speed things up
43
44     // key = memberName, value = list of shardNames
45     private final Map<String, List<String>> memberShardNames = new HashMap<>();
46
47     // key = shardName, value = list of replicaNames (replicaNames are the same as memberNames)
48     private final Map<String, List<String>> shardReplicaNames = new HashMap<>();
49
50     private final Map<String, String> namespaceToModuleName;
51     private final Map<String, ShardStrategy> moduleNameToStrategy;
52
53     public ConfigurationImpl(final String moduleShardsConfigPath,
54
55         final String modulesConfigPath){
56
57         Preconditions.checkNotNull(moduleShardsConfigPath, "moduleShardsConfigPath should not be null");
58         Preconditions.checkNotNull(modulesConfigPath, "modulesConfigPath should not be null");
59
60
61         File moduleShardsFile = new File("./configuration/initial/" + moduleShardsConfigPath);
62         File modulesFile = new File("./configuration/initial/" + modulesConfigPath);
63
64         Config moduleShardsConfig = null;
65         if(moduleShardsFile.exists()) {
66             LOG.info("module shards config file exists - reading config from it");
67             moduleShardsConfig = ConfigFactory.parseFile(moduleShardsFile);
68         } else {
69             LOG.warn("module shards configuration read from resource");
70             moduleShardsConfig = ConfigFactory.load(moduleShardsConfigPath);
71         }
72
73         Config modulesConfig = null;
74         if(modulesFile.exists()) {
75             LOG.info("modules config file exists - reading config from it");
76             modulesConfig = ConfigFactory.parseFile(modulesFile);
77         } else {
78             LOG.warn("modules configuration read from resource");
79             modulesConfig = ConfigFactory.load(modulesConfigPath);
80         }
81
82         this.moduleShards = readModuleShards(moduleShardsConfig);
83         this.modules = readModules(modulesConfig);
84
85         this.moduleNameToStrategy = createModuleNameToStrategy(modules);
86         this.namespaceToModuleName = createNamespaceToModuleName(modules);
87     }
88
89     private static Map<String, ShardStrategy> createModuleNameToStrategy(Iterable<Module> modules) {
90         final com.google.common.collect.ImmutableMap.Builder<String, ShardStrategy> b = ImmutableMap.builder();
91         for (Module m : modules) {
92             b.put(m.getName(), m.getShardStrategy());
93         }
94         return b.build();
95     }
96
97     private static Map<String, String> createNamespaceToModuleName(Iterable<Module> modules) {
98         final com.google.common.collect.ImmutableMap.Builder<String, String> b = ImmutableMap.builder();
99         for (Module m : modules) {
100             b.put(m.getNameSpace(), m.getName());
101         }
102         return b.build();
103     }
104
105     @Override public List<String> getMemberShardNames(final String memberName){
106
107         Preconditions.checkNotNull(memberName, "memberName should not be null");
108
109         if(memberShardNames.containsKey(memberName)){
110             return memberShardNames.get(memberName);
111         }
112
113         List<String> shards = new ArrayList<>();
114         for(ModuleShard ms : moduleShards){
115             for(Shard s : ms.getShards()){
116                 for(String m : s.getReplicas()){
117                     if(memberName.equals(m)){
118                         shards.add(s.getName());
119                     }
120                 }
121             }
122         }
123
124         memberShardNames.put(memberName, shards);
125
126         return shards;
127
128     }
129
130     @Override
131     public Optional<String> getModuleNameFromNameSpace(final String nameSpace) {
132         Preconditions.checkNotNull(nameSpace, "nameSpace should not be null");
133         return Optional.fromNullable(namespaceToModuleName.get(nameSpace));
134     }
135
136     @Override
137     public Map<String, ShardStrategy> getModuleNameToShardStrategyMap() {
138         return moduleNameToStrategy;
139     }
140
141     @Override public List<String> getShardNamesFromModuleName(final String moduleName) {
142
143         Preconditions.checkNotNull(moduleName, "moduleName should not be null");
144
145         // FIXME: can be constant view of moduleShards
146         for(ModuleShard m : moduleShards){
147             if(m.getModuleName().equals(moduleName)){
148                 List<String> l = new ArrayList<>();
149                 for(Shard s : m.getShards()){
150                     l.add(s.getName());
151                 }
152                 return l;
153             }
154         }
155
156         return Collections.emptyList();
157     }
158
159     @Override public List<String> getMembersFromShardName(final String shardName) {
160
161         Preconditions.checkNotNull(shardName, "shardName should not be null");
162
163         if(shardReplicaNames.containsKey(shardName)){
164             return shardReplicaNames.get(shardName);
165         }
166
167         for(ModuleShard ms : moduleShards){
168             for(Shard s : ms.getShards()) {
169                 if(s.getName().equals(shardName)){
170                     List<String> replicas = s.getReplicas();
171                     shardReplicaNames.put(shardName, replicas);
172                     return replicas;
173                 }
174             }
175         }
176         shardReplicaNames.put(shardName, Collections.<String>emptyList());
177         return Collections.emptyList();
178     }
179
180     @Override public Set<String> getAllShardNames() {
181         Set<String> shardNames = new LinkedHashSet<>();
182         for(ModuleShard ms : moduleShards){
183             for(Shard s : ms.getShards()) {
184                 shardNames.add(s.getName());
185             }
186         }
187         return shardNames;
188     }
189
190
191
192     private List<Module> readModules(final Config modulesConfig) {
193         List<? extends ConfigObject> modulesConfigObjectList =
194             modulesConfig.getObjectList("modules");
195
196         final Builder<Module> b = ImmutableList.builder();
197         for(ConfigObject o : modulesConfigObjectList){
198             ConfigObjectWrapper w = new ConfigObjectWrapper(o);
199             b.add(new Module(w.stringValue("name"), w.stringValue(
200                 "namespace"), w.stringValue("shard-strategy")));
201         }
202
203         return b.build();
204     }
205
206     private static List<ModuleShard> readModuleShards(final Config moduleShardsConfig) {
207         List<? extends ConfigObject> moduleShardsConfigObjectList =
208             moduleShardsConfig.getObjectList("module-shards");
209
210         final Builder<ModuleShard> b = ImmutableList.builder();
211         for(ConfigObject moduleShardConfigObject : moduleShardsConfigObjectList){
212
213             String moduleName = moduleShardConfigObject.get("name").unwrapped().toString();
214
215             List<? extends ConfigObject> shardsConfigObjectList =
216                 moduleShardConfigObject.toConfig().getObjectList("shards");
217
218             List<Shard> shards = new ArrayList<>();
219
220             for(ConfigObject shard : shardsConfigObjectList){
221                 String shardName = shard.get("name").unwrapped().toString();
222                 List<String> replicas = shard.toConfig().getStringList("replicas");
223                 shards.add(new Shard(shardName, replicas));
224             }
225
226             b.add(new ModuleShard(moduleName, shards));
227         }
228
229         return b.build();
230     }
231
232
233     private static class ModuleShard {
234         private final String moduleName;
235         private final List<Shard> shards;
236
237         public ModuleShard(final String moduleName, final List<Shard> shards) {
238             this.moduleName = moduleName;
239             this.shards = shards;
240         }
241
242         public String getModuleName() {
243             return moduleName;
244         }
245
246         public List<Shard> getShards() {
247             return shards;
248         }
249     }
250
251     private static class Shard {
252         private final String name;
253         private final List<String> replicas;
254
255         Shard(final String name, final List<String> replicas) {
256             this.name = name;
257             this.replicas = replicas;
258         }
259
260         public String getName() {
261             return name;
262         }
263
264         public List<String> getReplicas() {
265             return replicas;
266         }
267     }
268
269     private class Module {
270
271         private final String name;
272         private final String nameSpace;
273         private final ShardStrategy shardStrategy;
274
275         Module(final String name, final String nameSpace, final String shardStrategy) {
276             this.name = name;
277             this.nameSpace = nameSpace;
278             if(ModuleShardStrategy.NAME.equals(shardStrategy)){
279                 this.shardStrategy = new ModuleShardStrategy(name, ConfigurationImpl.this);
280             } else {
281                 this.shardStrategy = new DefaultShardStrategy();
282             }
283         }
284
285         public String getName() {
286             return name;
287         }
288
289         public String getNameSpace() {
290             return nameSpace;
291         }
292
293         public ShardStrategy getShardStrategy() {
294             return shardStrategy;
295         }
296     }
297
298
299     private static class ConfigObjectWrapper{
300
301         private final ConfigObject configObject;
302
303         ConfigObjectWrapper(final ConfigObject configObject){
304             this.configObject = configObject;
305         }
306
307         public String stringValue(final String name){
308             return configObject.get(name).unwrapped().toString();
309         }
310     }
311 }