1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package jgroup.relacs.config;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.NoSuchElementException;
28 import java.util.Set;
29
30 import jgroup.core.ConfigurationException;
31 import jgroup.experiment.Runnable;
32
33 import org.w3c.dom.Element;
34 import org.w3c.dom.Node;
35 import org.w3c.dom.NodeList;
36
37
38
39
40
41
42
43
44
45 public class ExperimentConfig
46 implements ConfigurationObject
47 {
48
49
50
51
52
53 private static final String SERVERS_TAG = "Servers";
54 private static final String CLIENTS_TAG = "Clients";
55 private static final String PROPERTY_TAG = "Property";
56 private static final String REPEATSCRIPT_TAG = "RepeatScript";
57 private static final String PREEXP_TAG = "PreExp";
58 private static final String POSTEXP_TAG = "PostExp";
59 private static final String EXP_TAG = "Exp";
60 private static final String RUN_TAG = "Run";
61 private static final String SLEEP_TAG = "Sleep";
62 private static final String SYSPROPERTY_TAG = "sysproperty";
63
64 private static final String URL_ATTRIB = "url";
65 private static final String KEY_ATTRIB = "key";
66 private static final String SRC_ATTRIB = "src";
67 private static final String VALUE_ATTRIB = "value";
68 private static final String NAME_ATTRIB = "name";
69 private static final String TARGET_ATTRIB = "target";
70 private static final String DELAY_ATTRIB = "delay";
71
72
73
74
75
76 private DistributedSystemConfig serverConfig = null;
77 private ClientsConfig clientConfig = null;
78
79
80 private Map properties = new HashMap();
81
82
83 private Map sysproperties = new HashMap();
84
85
86 private Map varSysproperties = new HashMap();
87
88
89 private List experimentRunList = new ArrayList();
90
91
92 private List preExperimentRunList = new ArrayList();
93
94
95 private List postExperimentRunList = new ArrayList();
96
97
98 private String experimentName;
99
100
101
102
103
104 private String repeatScript =
105 "int repeats = properties.getIntProperty(\"repeat.experiment\", 1);\n" +
106 "for (int l = 1; l <= repeats; l++) {\n" +
107 " properties.set(\"repeat\", l);\n" +
108 " experiment.run();\n" +
109 "}";
110
111
112
113
114
115
116
117
118 public ExperimentConfig() {}
119
120
121
122
123
124
125
126
127
128
129
130 public void parse(Element elm)
131 throws ConfigurationException
132 {
133
134 NodeList elementList = elm.getChildNodes();
135
136 for (int i=1; i <= elementList.getLength(); i++) {
137 Node node = elementList.item(i);
138 if (node != null && !node.getNodeName().startsWith("#")) {
139 elm = (Element) node;
140 if (ConfigParser.checkTag(elm, SERVERS_TAG))
141 parseServers(elm);
142 else if (ConfigParser.checkTag(elm, CLIENTS_TAG))
143 parseClients(elm);
144 else if (ConfigParser.checkTag(elm, PROPERTY_TAG))
145 parseProperty(elm);
146 else if (ConfigParser.checkTag(elm, REPEATSCRIPT_TAG))
147 parseRepeatScript(elm);
148 else if (ConfigParser.checkTag(elm, EXP_TAG)) {
149
150 experimentName = ConfigParser.getAttrib(elm, NAME_ATTRIB, true);
151 parseExp(elm, EXP_TAG);
152 }
153 else if (ConfigParser.checkTag(elm, PREEXP_TAG))
154 parseExp(elm, PREEXP_TAG);
155 else if (ConfigParser.checkTag(elm, POSTEXP_TAG))
156 parseExp(elm, POSTEXP_TAG);
157 else
158 throw new ConfigurationException("Unknown tag: " + elm.getTagName());
159 }
160 }
161
162
163 if (clientConfig == null) {
164 clientConfig = new ClientsConfig();
165 clientConfig.getAllHosts().removeAllHosts();
166 }
167 }
168
169
170
171
172
173
174
175
176
177
178 private void parseServers(Element elm)
179 throws ConfigurationException
180 {
181
182 String serversURL = ConfigParser.getAttrib(elm, URL_ATTRIB, false);
183 serversURL = parseParameter(serversURL, properties);
184
185 System.setProperty("jgroup.system.config", serversURL);
186
187 try {
188
189 serverConfig = (DistributedSystemConfig) ConfigParser.getConfig(DistributedSystemConfig.class);
190 serverConfig.getAllHosts().removeAllHosts();
191 } catch (IllegalStateException e) {
192
193 } catch (NullPointerException e) {
194
195 }
196
197
198 if (serversURL == null || serversURL.length() == 0) {
199 serverConfig = new DistributedSystemConfig();
200 serverConfig.parse(elm);
201 } else {
202
203 ConfigParser.parse(serversURL, true);
204 serverConfig = (DistributedSystemConfig) ConfigParser.getConfig(DistributedSystemConfig.class);
205 }
206 }
207
208
209
210
211
212
213 private void parseClients(Element elm)
214 throws ConfigurationException
215 {
216 String clientsURL = ConfigParser.getAttrib(elm, URL_ATTRIB, false);
217 clientsURL = parseParameter(clientsURL, properties);
218
219 try {
220
221 clientConfig = (ClientsConfig) ConfigParser.getConfig(ClientsConfig.class);
222 clientConfig.getAllHosts().removeAllHosts();
223 } catch (IllegalStateException e) {
224
225 } catch (NullPointerException e) {
226
227 }
228
229
230 if (clientsURL.length() == 0) {
231 clientConfig = new ClientsConfig();
232 clientConfig.parse(elm);
233 } else {
234
235 ConfigParser.parse(clientsURL, true);
236 clientConfig = (ClientsConfig) ConfigParser.getConfig(ClientsConfig.class);
237 }
238 }
239
240
241
242
243
244 private void parseProperty(Element elm)
245 throws ConfigurationException
246 {
247 String key = ConfigParser.getAttrib(elm, KEY_ATTRIB, true);
248 String value = ConfigParser.getAttrib(elm, VALUE_ATTRIB, true);
249 properties.put(key, parseParameter(value, properties) );
250 }
251
252
253 private void parseRepeatScript(Element elm)
254 throws ConfigurationException
255 {
256 String src = ConfigParser.getAttrib(elm, SRC_ATTRIB, false);
257 if (src != null && src.endsWith(".bsh")) {
258 repeatScript = "config" + File.separator + src;
259 } else {
260
261 NodeList elementList = elm.getChildNodes();
262
263 for (int i=1; i <= elementList.getLength(); i++) {
264 Node node = elementList.item(i);
265 if (node != null && node.getNodeName().startsWith("#cdata-section")) {
266 repeatScript = node.getNodeValue();
267 }
268 }
269 }
270 }
271
272
273
274
275
276
277 private void parseSysProperties(Element elm, Map map)
278 throws ConfigurationException
279 {
280
281 NodeList elementList = elm.getChildNodes();
282
283
284 for (int i=1; i <= elementList.getLength(); i++) {
285 Node node = elementList.item(i);
286 if (node != null && !node.getNodeName().startsWith("#")) {
287 elm = (Element) node;
288 if (elm.getTagName().equalsIgnoreCase(SYSPROPERTY_TAG)) {
289 String key = ConfigParser.getAttrib(elm, KEY_ATTRIB, true);
290 String value = ConfigParser.getAttrib(elm, VALUE_ATTRIB, true);
291
292 if (map.containsKey(key))
293 throw new ConfigurationException("Multiply defined property key: " + key);
294 map.put(key, parseParameter(value, properties));
295 }
296 }
297 }
298 }
299
300
301
302
303
304 private void parseExp(Element elm, String expType)
305 throws ConfigurationException
306 {
307 List runList;
308 if (expType.equals(EXP_TAG)) {
309 runList = experimentRunList;
310 } else if (expType.equals(PREEXP_TAG)) {
311 runList = preExperimentRunList;
312 } else if (expType.equals(POSTEXP_TAG)) {
313 runList = postExperimentRunList;
314 } else {
315 throw new ConfigurationException("Unknown experiment type: " + expType);
316 }
317
318
319 NodeList elementList = elm.getChildNodes();
320
321 for (int i=1; i <= elementList.getLength(); i++) {
322 Node node = elementList.item(i);
323 if (node != null && !node.getNodeName().startsWith("#")) {
324 elm = (Element) node;
325 if (ConfigParser.checkTag(elm, RUN_TAG)) {
326 Object runObj = parseRun(elm);
327 if (runObj != null)
328 runList.add(runObj);
329 } else if (ConfigParser.checkTag(elm, SLEEP_TAG)) {
330 Integer delay = parseSleep(elm);
331 runList.add(delay);
332 } else {
333 throw new ConfigurationException("Unknown tag: " + elm.getTagName());
334 }
335 }
336 }
337 }
338
339
340
341
342
343 private Object parseRun(Element elm)
344 throws ConfigurationException
345 {
346 String target = ConfigParser.getAttrib(elm, TARGET_ATTRIB, false);
347
348
349 if (target == null || target.length() == 0) {
350 String name = ConfigParser.getAttrib(elm, NAME_ATTRIB, true);
351
352 if (name.startsWith("!"))
353 return null;
354 try {
355 Class runClass = Class.forName("jgroup.experiment.runnables." + name);
356 Runnable runElement = (Runnable) runClass.newInstance();
357
358 Map spMap = new HashMap();
359 parseSysProperties(elm, spMap);
360 sysproperties.put(runElement, spMap);
361 Map vspMap = new HashMap();
362 parseSysProperties(elm, vspMap);
363 varSysproperties.put(runElement, vspMap);
364
365 return runElement;
366 } catch (ClassNotFoundException e) {
367 e.printStackTrace();
368 throw new ConfigurationException("Runnable class jgroup.experiment.runnables." + name + " not found.");
369 } catch (Exception e) {
370 e.printStackTrace();
371 throw new ConfigurationException("Error creating runnable element " + name + ".");
372 }
373 } else {
374
375 if (target.startsWith("!"))
376 return null;
377 StringBuilder antCmd = new StringBuilder(target);
378 return parseTarget(elm, antCmd);
379 }
380 }
381
382
383
384
385
386 private Object parseTarget(Element elm, StringBuilder antCmd)
387 throws ConfigurationException
388 {
389
390 NodeList elementList = elm.getChildNodes();
391
392 for (int i=1; i <= elementList.getLength(); i++) {
393 Node node = elementList.item(i);
394 if (node != null && !node.getNodeName().startsWith("#")) {
395 elm = (Element) node;
396 if (elm.getTagName().equalsIgnoreCase(SYSPROPERTY_TAG)) {
397 String key = elm.getAttribute(KEY_ATTRIB);
398 String value = elm.getAttribute(VALUE_ATTRIB);
399 if (key.length() == 0)
400 throw new ConfigurationException("Missing key attribute.");
401 if (value.length() == 0)
402 throw new ConfigurationException("Missing value attribute.");
403 antCmd.append(" -D");
404 antCmd.append(key);
405 antCmd.append("=");
406 antCmd.append(value);
407 }
408 }
409 }
410
411 return antCmd.toString();
412 }
413
414
415
416
417
418
419 private Integer parseSleep(Element elm)
420 throws ConfigurationException
421 {
422 try {
423
424
425
426
427
428 Integer delay = Integer.valueOf(ConfigParser.getAttrib(elm, DELAY_ATTRIB, false));
429
430 if (delay.compareTo(new Integer(0)) < 0)
431 throw new ConfigurationException("Negative delay value for Sleep tag is not allowed");
432 return delay;
433 } catch (NumberFormatException e) {
434 e.printStackTrace();
435 throw new ConfigurationException("Illegal delay value for Sleep tag");
436 }
437 }
438
439
440
441
442
443
444
445
446
447
448 private String parseParameter(String value, Map props)
449 throws ConfigurationException
450 {
451 StringBuilder expandedValue = new StringBuilder();
452 int index = 0;
453
454 while (index < value.length()) {
455 int paramStart = value.indexOf("${", index);
456
457
458 if (paramStart == -1) {
459 expandedValue.append(value.substring(index));
460 index = value.length();
461 } else {
462 int paramEnd = value.indexOf("}", paramStart);
463 if (paramEnd == -1)
464 throw new ConfigurationException("Parameter does not end with '}'");
465
466 String parameter = value.substring(paramStart + 2, paramEnd);
467 String parameterValue = (String) props.get(parameter);
468
469
470 if (parameterValue == null)
471 parameterValue = System.getProperty(parameter);
472 if (parameterValue == null) {
473 parameterValue = value.substring(paramStart, paramEnd+1);
474 }
475
476
477 expandedValue.append(value.substring(index, paramStart));
478 expandedValue.append(parameterValue);
479 index = paramEnd + 1;
480 }
481 }
482 return new String(expandedValue);
483 }
484
485
486
487
488
489
490
491
492
493
494 public void updateProperties(Runnable runnable)
495 throws ConfigurationException
496 {
497 Set entries = ((Map) varSysproperties.get(runnable)).entrySet();
498 Map props = getProperties(runnable);
499 for (Iterator iter = entries.iterator(); iter.hasNext();) {
500 Map.Entry entry = (Map.Entry) iter.next();
501 String value = (String) entry.getValue();
502 value = parseParameter(value, properties);
503 props.put(entry.getKey(), value);
504 }
505 }
506
507
508
509
510
511 public void set(String key, Object val)
512 {
513 if (!(val instanceof String)) {
514 properties.put(key, val.toString());
515 } else {
516 properties.put(key, val);
517 }
518 }
519
520 public DistributedSystemConfig getServerConfig()
521 {
522 return serverConfig;
523 }
524
525 public ClientsConfig getClientConfig()
526 {
527 return clientConfig;
528 }
529
530 public String getExperimentName()
531 {
532 return experimentName;
533 }
534
535 public List getPreExperimentRunList()
536 {
537 return preExperimentRunList;
538 }
539
540 public List getExperimentRunList()
541 {
542 return experimentRunList;
543 }
544
545 public List getPostExperimentRunList()
546 {
547 return postExperimentRunList;
548 }
549
550 public String getRepeatScript()
551 {
552 return repeatScript;
553 }
554
555 public Map getProperties()
556 {
557 return properties;
558 }
559
560
561
562
563
564
565
566
567 public Map getProperties(Runnable runnable)
568 {
569 return (Map) sysproperties.get(runnable);
570 }
571
572
573
574
575
576
577
578 public String getProperty(String name)
579 throws NoSuchElementException
580 {
581 String strval = (String) properties.get(name);
582 if (strval == null || strval.length() == 0) {
583 strval = System.getProperty(name);
584 if (strval == null || strval.length() == 0)
585 throw new NoSuchElementException("No property named " + name);
586 }
587
588 return strval;
589 }
590
591
592
593
594
595
596 public String getProperty(String name, String defaultVal)
597 {
598 String strval = (String) properties.get(name);
599 if (strval == null || strval.length() == 0)
600 return defaultVal;
601 return strval;
602 }
603
604
605
606
607
608
609
610 public int getIntProperty(String name)
611 {
612 return Integer.valueOf(getProperty(name)).intValue();
613 }
614
615
616
617
618
619
620
621
622
623 public int getIntProperty(String name, int defaultValue)
624 {
625 String strval = (String) properties.get(name);
626 if (strval == null || strval.length() == 0)
627 return defaultValue;
628 return Integer.valueOf(strval).intValue();
629 }
630
631
632
633
634
635
636
637
638 public boolean getBooleanProperty(String name)
639 {
640 String strval = (String) properties.get(name);
641 if (strval == null || strval.length() == 0)
642 return false;
643 return Boolean.valueOf(strval).booleanValue();
644 }
645
646
647
648
649
650
651
652
653
654 public String getProperty(Runnable runnable, String name)
655 throws NoSuchElementException
656 {
657 if (!sysproperties.containsKey(runnable))
658 throw new NoSuchElementException("No sysproperties have been parsed for Runnable " + runnable.getClass().getName());
659 String strval = (String) ((Map) sysproperties.get(runnable)).get(name);
660 if (strval == null || strval.length() == 0)
661 throw new NoSuchElementException("No property named " + name + " for Runnable " + runnable.getClass().getName());
662 return strval;
663 }
664
665
666
667
668
669
670
671
672
673 public String getProperty(Runnable runnable, String name, String defaultValue)
674 {
675 try {
676 return getProperty(runnable, name);
677 } catch (NoSuchElementException e) {
678
679 Map spMap = (Map) sysproperties.get(runnable);
680 if (spMap == null) {
681 spMap = new HashMap();
682 }
683 spMap.put(name, defaultValue);
684 return defaultValue;
685 }
686 }
687
688
689
690
691
692
693
694
695 public int getIntProperty(Runnable runnable, String name)
696 {
697 return Integer.valueOf(getProperty(runnable, name)).intValue();
698 }
699
700
701
702
703
704
705
706
707
708
709
710 public int getIntProperty(Runnable runnable, String name, int defaultValue)
711 {
712 Map spMap = (Map) sysproperties.get(runnable);
713 if (spMap == null) {
714 spMap = new HashMap();
715 }
716 String strval = (String) spMap.get(name);
717 if (strval == null || strval.length() == 0) {
718
719 spMap.put(name, String.valueOf(defaultValue));
720 return defaultValue;
721 }
722 return Integer.valueOf(strval).intValue();
723 }
724
725
726
727
728
729
730
731
732
733 public boolean getBooleanProperty(Runnable runnable, String name)
734 {
735 if (!sysproperties.containsKey(runnable))
736 throw new NoSuchElementException("No sysproperties have been parsed for Runnable " + runnable.getClass().getName());
737 String strval = (String) ((Map) sysproperties.get(runnable)).get(name);
738 if (strval == null || strval.length() == 0)
739 return false;
740 return Boolean.valueOf(strval).booleanValue();
741 }
742
743
744
745
746
747
748
749
750
751
752 public boolean getBooleanProperty(Runnable runnable, String name, boolean defaultValue)
753 {
754 Map spMap = (Map) sysproperties.get(runnable);
755 if (spMap == null) {
756 spMap = new HashMap();
757 }
758 String strval = (String) ((Map) sysproperties.get(runnable)).get(name);
759 if (strval == null || strval.length() == 0) {
760
761 spMap.put(name, Boolean.valueOf(defaultValue).toString());
762 return defaultValue;
763 }
764 return Boolean.valueOf(strval).booleanValue();
765 }
766
767 private static final String DEFAULT_SSH_CMD = "ssh";
768 private static final String DEFAULT_SCP_CMD = "scp";
769 private static final String DEFAULT_ANT_CMD = "ant -emacs -buildfile ";
770 private static final String DEFAULT_JGROUP_DIR = "/tmp/Jgroup";
771
772 public String ssh(String hostname)
773 {
774 String ssh = getProperty("jgroup.cmd.ssh", DEFAULT_SSH_CMD);
775 return ssh + " -x " + hostname + " ";
776 }
777
778 public String scp(String fromHost, String fromDir, String toDir)
779 {
780 String scp = getProperty("jgroup.cmd.scp", DEFAULT_SCP_CMD);
781 return scp + " " + fromHost + ":" + fromDir + "/* " + toDir;
782 }
783
784 public String ant(String target, String[] expProperties, Runnable runnable)
785 {
786 StringBuilder buf = new StringBuilder(getProperty("jgroup.cmd.ant", DEFAULT_ANT_CMD));
787 buf.append(getProperty("jgroup.dir", DEFAULT_JGROUP_DIR));
788 buf.append(File.separator);
789
790 buf.append("build.xml -Djgroup.system.config=");
791 buf.append(System.getProperty("jgroup.system.config"));
792 if (runnable != null) {
793 for (int i = 0; i < expProperties.length; i++) {
794 String prop = getProperty(runnable, expProperties[i], null);
795 if (prop != null && prop.length() > 0) {
796 buf.append(" -D");
797 buf.append(expProperties[i]);
798 buf.append("=");
799 buf.append(prop);
800 }
801 }
802 }
803 buf.append(" ");
804 buf.append(target);
805 return buf.toString();
806 }
807
808 public String ant(String target)
809 {
810 return ant(target, null, null);
811 }
812
813 }