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