1 package org.apache.helix;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.TreeMap;
29
30 import org.apache.helix.model.ConfigScope;
31 import org.apache.helix.model.HelixConfigScope;
32 import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
33 import org.apache.helix.manager.zk.ZKUtil;
34 import org.apache.helix.manager.zk.ZkClient;
35 import org.apache.helix.util.StringTemplate;
36 import org.apache.log4j.Logger;
37
38
39 public class ConfigAccessor
40 {
41 private static Logger LOG = Logger.getLogger(ConfigAccessor.class);
42
43 private static final StringTemplate template = new StringTemplate();
44 static
45 {
46
47 template.addEntry(ConfigScopeProperty.CLUSTER, 1, "/{clusterName}/CONFIGS/CLUSTER");
48 template.addEntry(ConfigScopeProperty.CLUSTER,
49 2,
50 "/{clusterName}/CONFIGS/CLUSTER/{clusterName}|SIMPLEKEYS");
51 template.addEntry(ConfigScopeProperty.PARTICIPANT,
52 1,
53 "/{clusterName}/CONFIGS/PARTICIPANT");
54 template.addEntry(ConfigScopeProperty.PARTICIPANT,
55 2,
56 "/{clusterName}/CONFIGS/PARTICIPANT/{participantName}|SIMPLEKEYS");
57 template.addEntry(ConfigScopeProperty.RESOURCE, 1, "/{clusterName}/CONFIGS/RESOURCE");
58 template.addEntry(ConfigScopeProperty.RESOURCE,
59 2,
60 "/{clusterName}/CONFIGS/RESOURCE/{resourceName}|SIMPLEKEYS");
61 template.addEntry(ConfigScopeProperty.PARTITION,
62 2,
63 "/{clusterName}/CONFIGS/RESOURCE/{resourceName}|MAPKEYS");
64 template.addEntry(ConfigScopeProperty.PARTITION,
65 3,
66 "/{clusterName}/CONFIGS/RESOURCE/{resourceName}|MAPMAPKEYS|{partitionName}");
67
68 }
69
70 private final ZkClient zkClient;
71
72 public ConfigAccessor(ZkClient zkClient)
73 {
74 this.zkClient = zkClient;
75 }
76
77
78
79
80
81
82
83
84
85 @Deprecated
86 public String get(ConfigScope scope, String key)
87 {
88 Map<String, String> map = get(scope, Arrays.asList(key));
89 return map.get(key);
90 }
91
92
93
94
95
96
97
98
99
100 @Deprecated
101 public Map<String, String> get(ConfigScope scope, List<String> keys)
102 {
103 if (scope == null || scope.getScope() == null)
104 {
105 LOG.error("Scope can't be null");
106 return null;
107 }
108
109
110 Map<String, String> map = new HashMap<String, String>();
111 String clusterName = scope.getClusterName();
112 if (!ZKUtil.isClusterSetup(clusterName, zkClient))
113 {
114 throw new HelixException("cluster " + clusterName + " is not setup yet");
115 }
116
117 String scopeStr = scope.getScopeStr();
118 String[] splits = scopeStr.split("\\|");
119
120 ZNRecord record = zkClient.readData(splits[0], true);
121
122 if (record != null)
123 {
124 if (splits.length == 1)
125 {
126 for (String key : keys) {
127 if (record.getSimpleFields().containsKey(key)) {
128 map.put(key, record.getSimpleField(key));
129 }
130 }
131 }
132 else if (splits.length == 2)
133 {
134 if (record.getMapField(splits[1]) != null)
135 {
136 for (String key : keys) {
137 if (record.getMapField(splits[1]).containsKey(key)) {
138 map.put(key, record.getMapField(splits[1]).get(key));
139 }
140 }
141 }
142 }
143 }
144 return map;
145
146 }
147
148
149
150
151
152
153
154
155 public String get(HelixConfigScope scope, String key) {
156 Map<String, String> map = get(scope, Arrays.asList(key));
157 if (map != null) {
158 return map.get(key);
159 }
160 return null;
161 }
162
163
164
165
166
167
168
169
170 public Map<String, String> get(HelixConfigScope scope, List<String> keys) {
171 if (scope == null || scope.getType()== null || !scope.isFullKey()) {
172 LOG.error("fail to get configs. invalid config scope. scope: " + scope + ", keys: " + keys);
173 return null;
174 }
175
176 String clusterName = scope.getClusterName();
177 if (!ZKUtil.isClusterSetup(clusterName, zkClient)) {
178 throw new HelixException("fail to get configs. cluster " + clusterName + " is not setup yet");
179 }
180
181 Map<String, String> map = new HashMap<String, String>();
182
183 ZNRecord record = zkClient.readData(scope.getZkPath(), true);
184 if (record == null) {
185 LOG.warn("No config found at " + scope.getZkPath());
186 return null;
187 }
188
189 String mapKey = scope.getMapKey();
190 if (mapKey == null) {
191 for (String key : keys) {
192 if (record.getSimpleFields().containsKey(key)) {
193 map.put(key, record.getSimpleField(key));
194 }
195 }
196 } else {
197 Map<String, String> configMap = record.getMapField(mapKey);
198 if (configMap == null) {
199 LOG.warn("No map-field found in " + record + " using mapKey: " + mapKey);
200 return null;
201 }
202
203 for (String key : keys) {
204 if (record.getMapField(mapKey).containsKey(key)) {
205 map.put(key, record.getMapField(mapKey).get(key));
206 }
207 }
208 }
209
210 return map;
211 }
212
213
214
215
216
217
218
219
220
221 @Deprecated
222 public void set(ConfigScope scope, String key, String value) {
223 Map<String, String> map = new HashMap<String, String>();
224 map.put(key, value);
225 set(scope, map);
226 }
227
228
229
230
231
232
233
234
235 @Deprecated
236 public void set(ConfigScope scope, Map<String, String> keyValueMap)
237 {
238 if (scope == null || scope.getScope() == null)
239 {
240 LOG.error("Scope can't be null");
241 return;
242 }
243
244 String clusterName = scope.getClusterName();
245 if (!ZKUtil.isClusterSetup(clusterName, zkClient))
246 {
247 throw new HelixException("cluster: " + clusterName + " is NOT setup.");
248 }
249
250 if (scope.getScope() == ConfigScopeProperty.PARTICIPANT) {
251 String scopeStr = scope.getScopeStr();
252 String instanceName = scopeStr.substring(scopeStr.lastIndexOf('/') + 1);
253 if (!ZKUtil.isInstanceSetup(zkClient, scope.getClusterName(), instanceName, InstanceType.PARTICIPANT)) {
254 throw new HelixException("instance: " + instanceName + " is NOT setup in cluster: " + clusterName);
255 }
256 }
257
258
259 String scopeStr = scope.getScopeStr();
260 String[] splits = scopeStr.split("\\|");
261
262 String id = splits[0].substring(splits[0].lastIndexOf('/') + 1);
263 ZNRecord update = new ZNRecord(id);
264 if (splits.length == 1)
265 {
266 for (String key: keyValueMap.keySet()) {
267 String value = keyValueMap.get(key);
268 update.setSimpleField(key, value);
269 }
270 }
271 else if (splits.length == 2)
272 {
273 if (update.getMapField(splits[1]) == null)
274 {
275 update.setMapField(splits[1], new TreeMap<String, String>());
276 }
277 for (String key: keyValueMap.keySet()) {
278 String value = keyValueMap.get(key);
279 update.getMapField(splits[1]).put(key, value);
280 }
281 }
282 ZKUtil.createOrUpdate(zkClient, splits[0], update, true, true);
283 return;
284 }
285
286
287
288
289
290
291
292
293 public void set(HelixConfigScope scope, String key, String value) {
294 Map<String, String> map = new TreeMap<String, String>();
295 map.put(key, value);
296 set(scope, map);
297 }
298
299
300
301
302
303
304
305 public void set(HelixConfigScope scope, Map<String, String> keyValueMap)
306 {
307 if (scope == null || scope.getType() == null || !scope.isFullKey()) {
308 LOG.error("fail to set config. invalid config scope. scope: " + scope);
309 return;
310 }
311
312 String clusterName = scope.getClusterName();
313 if (!ZKUtil.isClusterSetup(clusterName, zkClient)) {
314 throw new HelixException("fail to set config. cluster: " + clusterName + " is NOT setup.");
315 }
316
317 if (scope.getType() == ConfigScopeProperty.PARTICIPANT) {
318 if (!ZKUtil.isInstanceSetup(zkClient, scope.getClusterName(), scope.getParticipantName(),
319 InstanceType.PARTICIPANT)) {
320 throw new HelixException("fail to set config. instance: " + scope.getClusterName()
321 + " is NOT setup in cluster: " + clusterName);
322 }
323 }
324
325 String zkPath = scope.getZkPath();
326 String mapKey = scope.getMapKey();
327 String id = zkPath.substring(zkPath.lastIndexOf('/') + 1);
328 ZNRecord update = new ZNRecord(id);
329 if (mapKey == null) {
330 update.getSimpleFields().putAll(keyValueMap);
331 } else {
332 update.setMapField(mapKey, keyValueMap);
333 }
334 ZKUtil.createOrUpdate(zkClient, zkPath, update, true, true);
335 return;
336 }
337
338
339
340
341
342
343
344
345 @Deprecated
346 public void remove(ConfigScope scope, String key) {
347 remove(scope, Arrays.asList(key));
348 }
349
350
351
352
353
354
355
356
357 @Deprecated
358 public void remove(ConfigScope scope, List<String> keys)
359 {
360 if (scope == null || scope.getScope() == null)
361 {
362 LOG.error("Scope can't be null");
363 return;
364 }
365
366 String clusterName = scope.getClusterName();
367 if (!ZKUtil.isClusterSetup(clusterName, zkClient))
368 {
369 throw new HelixException("cluster " + clusterName + " is not setup yet");
370 }
371
372 String scopeStr = scope.getScopeStr();
373 String[] splits = scopeStr.split("\\|");
374
375 String id = splits[0].substring(splits[0].lastIndexOf('/') + 1);
376 ZNRecord update = new ZNRecord(id);
377 if (splits.length == 1)
378 {
379
380 for (String key : keys) {
381 update.setSimpleField(key, "");
382 }
383 }
384 else if (splits.length == 2)
385 {
386 if (update.getMapField(splits[1]) == null)
387 {
388 update.setMapField(splits[1], new TreeMap<String, String>());
389 }
390
391 for (String key : keys) {
392 update.getMapField(splits[1]).put(key, "");
393 }
394 }
395
396 ZKUtil.subtract(zkClient, splits[0], update);
397 return;
398 }
399
400
401
402
403
404
405
406 public void remove(HelixConfigScope scope, String key) {
407 remove(scope, Arrays.asList(key));
408 }
409
410
411
412
413
414
415
416 public void remove(HelixConfigScope scope, List<String> keys)
417 {
418 if (scope == null || scope.getType() == null || !scope.isFullKey()) {
419 LOG.error("fail to remove. invalid scope: " + scope + ", keys: " + keys);
420 return;
421 }
422
423 String clusterName = scope.getClusterName();
424 if (!ZKUtil.isClusterSetup(clusterName, zkClient)) {
425 throw new HelixException("fail to remove. cluster " + clusterName + " is not setup yet");
426 }
427
428 String zkPath = scope.getZkPath();
429 String mapKey = scope.getMapKey();
430 String id = zkPath.substring(zkPath.lastIndexOf('/') + 1);
431 ZNRecord update = new ZNRecord(id);
432 if (mapKey == null) {
433
434 for (String key : keys) {
435 update.setSimpleField(key, "");
436 }
437 } else {
438 update.setMapField(mapKey, new TreeMap<String, String>());
439
440 for (String key : keys) {
441 update.getMapField(mapKey).put(key, "");
442 }
443 }
444
445 ZKUtil.subtract(zkClient, zkPath, update);
446 return;
447 }
448
449
450
451
452
453
454
455
456
457
458 @Deprecated
459 public List<String> getKeys(ConfigScopeProperty type,
460 String clusterName,
461 String... keys)
462 {
463 if (type == null || clusterName == null)
464 {
465 LOG.error("clusterName|scope can't be null");
466 return Collections.emptyList();
467 }
468
469 try
470 {
471 if (!ZKUtil.isClusterSetup(clusterName, zkClient))
472 {
473 LOG.error("cluster " + clusterName + " is not setup yet");
474 return Collections.emptyList();
475 }
476
477 String[] args = new String[1 + keys.length];
478 args[0] = clusterName;
479 System.arraycopy(keys, 0, args, 1, keys.length);
480 String scopeStr = template.instantiate(type, args);
481 String[] splits = scopeStr.split("\\|");
482 List<String> retKeys = null;
483 if (splits.length == 1)
484 {
485 retKeys = zkClient.getChildren(splits[0]);
486 }
487 else
488 {
489 ZNRecord record = zkClient.readData(splits[0]);
490
491 if (splits[1].startsWith("SIMPLEKEYS"))
492 {
493 retKeys = new ArrayList<String>(record.getSimpleFields().keySet());
494
495 }
496 else if (splits[1].startsWith("MAPKEYS"))
497 {
498 retKeys = new ArrayList<String>(record.getMapFields().keySet());
499 }
500 else if (splits[1].startsWith("MAPMAPKEYS"))
501 {
502 retKeys = new ArrayList<String>(record.getMapField(splits[2]).keySet());
503 }
504 }
505 if (retKeys == null)
506 {
507 LOG.error("Invalid scope: " + type + " or keys: " + Arrays.toString(args));
508 return Collections.emptyList();
509 }
510
511 Collections.sort(retKeys);
512 return retKeys;
513 }
514 catch (Exception e)
515 {
516 return Collections.emptyList();
517 }
518
519 }
520
521
522
523
524
525
526
527
528 public List<String> getKeys(HelixConfigScope scope) {
529 if (scope == null || scope.getType() == null) {
530 LOG.error("fail to getKeys. invalid config scope: " + scope);
531 return null;
532 }
533
534 if (!ZKUtil.isClusterSetup(scope.getClusterName(), zkClient)){
535 LOG.error("fail to getKeys. cluster " + scope.getClusterName() + " is not setup yet");
536 return Collections.emptyList();
537 }
538
539 String zkPath = scope.getZkPath();
540 String mapKey = scope.getMapKey();
541 List<String> retKeys = null;
542
543 if (scope.isFullKey()) {
544 ZNRecord record = zkClient.readData(zkPath);
545 if (mapKey == null) {
546 retKeys = new ArrayList<String>(record.getSimpleFields().keySet());
547 } else {
548 retKeys = new ArrayList<String>(record.getMapField(mapKey).keySet());
549 }
550 } else {
551 if (scope.getType() == ConfigScopeProperty.PARTITION) {
552 ZNRecord record = zkClient.readData(zkPath);
553 retKeys = new ArrayList<String>(record.getMapFields().keySet());
554 } else {
555 retKeys = zkClient.getChildren(zkPath);
556 }
557 }
558
559 if (retKeys != null) {
560 Collections.sort(retKeys);
561 }
562 return retKeys;
563 }
564 }