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