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