View Javadoc

1   /*
2    * Copyright (c) 1998-2004 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18   
19  package jgroup.experiment;
20  
21  import java.io.File;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import jgroup.core.ConfigManager;
26  import jgroup.core.ConfigurationException;
27  import jgroup.relacs.config.ConfigParser;
28  import jgroup.relacs.config.DistributedSystemConfig;
29  import jgroup.relacs.config.ExperimentConfig;
30  
31  import org.apache.log4j.Logger;
32  
33  import bsh.Interpreter;
34  
35  /**
36   * The experiment framework engine.
37   *
38   * @author Bjarte Svaeren
39   * @author Hein Meling
40   */
41  public class Experiment
42  {
43    ////////////////////////////////////////////////////////////////////////////////////////////
44    // Logger
45    ////////////////////////////////////////////////////////////////////////////////////////////
46  
47    /** Obtain logger for this class */
48    public static final Logger log = Logger.getLogger(Experiment.class);
49  
50  
51    ////////////////////////////////////////////////////////////////////////////////////////////
52    // Fields
53    ////////////////////////////////////////////////////////////////////////////////////////////
54  
55    private ExperimentConfig ec;
56  
57  
58    ////////////////////////////////////////////////////////////////////////////////////////////
59    // Constructor
60    ////////////////////////////////////////////////////////////////////////////////////////////
61  
62    private Experiment()
63      throws Exception
64    {
65      ConfigManager.configureLogging();
66      /*
67       * Here we parse the configuration files; we do this last to allow
68       * logging to file also during configuration parsing.
69       */
70      String expConfig = System.getProperty("jgroup.experiment.config");
71      if (expConfig != null && expConfig.length() > 0) {
72        String urlConfig = null;
73        if (expConfig.startsWith("file:")) {
74          urlConfig = expConfig;
75        } else {
76          String expDir = System.getProperty("jgroup.experiment.dir");
77          if (expDir != null && expDir.length() > 0)
78            urlConfig = "file:" + expDir + File.separator + expConfig;
79          else
80            urlConfig = "file:" + expConfig;
81        }
82        ConfigManager.init(urlConfig);
83      } else {
84        throw new ConfigurationException("No experiment configuration provided");
85      }
86      ec = (ExperimentConfig) ConfigParser.getConfig(ExperimentConfig.class);
87      /*
88       * Set up a shutdown hook for the experiment engine to ensure that
89       * the post run list is always runned to clean up everything.
90       */
91      Runtime rt = Runtime.getRuntime();
92      Thread shutdownHook = new Thread("RunPostShutdownHook") {
93        public void run() {
94          log.info("Running post experiment shutdown hook");
95          try {
96            Experiment.this.run(ec.getPostExperimentRunList());
97          } catch (Exception e) {
98            e.printStackTrace();
99          }
100       }};
101     rt.addShutdownHook(shutdownHook);
102 
103     // Run the three parts of the experiment: pre, main, post experiment
104     try {
105       run(ec.getPreExperimentRunList());
106     } catch (ConfigurationException e) {
107       // Experiment failed during initialization, remove the shutdown hook
108       rt.removeShutdownHook(shutdownHook);
109       return;
110     }
111     /*
112      * The main part of the experiment is called from the repeat script
113      * using the experiment.run() method.
114      */
115     String script = ec.getRepeatScript();
116     Interpreter bsh = new Interpreter();
117     bsh.set("properties", ec);
118     bsh.set("experiment", this);
119     if (script.endsWith(".bsh"))
120       bsh.source(script);
121     else
122       bsh.eval(script);
123     run(ec.getPostExperimentRunList());
124 
125     // Experiment completed successfully, remove the shutdown hook
126     rt.removeShutdownHook(shutdownHook);
127   }
128 
129 
130   ////////////////////////////////////////////////////////////////////////////////////////////
131   // Main method
132   ////////////////////////////////////////////////////////////////////////////////////////////
133 
134   public static void main(String[] args)
135     throws Exception
136   {
137     new Experiment();
138   }
139 
140   public void run()
141     throws Exception
142   {
143     log.info("Running experiment " + ec.getExperimentName()
144         + " round no. " + ec.getIntProperty("repeat"));
145     /* Update reachability status for all hosts in the distributed system */
146     DistributedSystemConfig.updateAll();
147     List runList = ec.getExperimentRunList();
148     run(runList);
149     log.info("Completed experiment " + ec.getExperimentName()
150         + " round no. " + ec.getIntProperty("repeat"));
151   }
152 
153   private void run(List runList)
154     throws Exception
155   {
156     for (Iterator iter = runList.iterator(); iter.hasNext();) {
157       Object runObj = iter.next();
158       /*
159        * If the next object in the runList is a String, then
160        * invoke the corresponding ant target.
161        */
162       if (runObj instanceof String) {
163         String target = (String) runObj;
164         log.info("Running   : '" + target + "'");
165         ThreadGroup antThreads = new ThreadGroup("ANT");
166         String bootHost = ec.getProperty("bootstrap.host", null);
167         if (bootHost != null && !bootHost.equals("localhost")) {
168           ShellCommand.exec(ec.ssh(bootHost) + ec.ant(target), antThreads);
169         } else {
170           ShellCommand.exec(ec.ant(target), antThreads);
171         }
172         ShellCommand.waitFor(antThreads);
173         log.info("Completed : '" + target + "'");
174       } else if (runObj instanceof Runnable) {
175         Runnable runElement = (Runnable) runObj;
176         String runnable = runObj.getClass().getName();
177         runnable = runnable.substring(runnable.lastIndexOf('.')+1);
178         log.info("Running   : " + runnable);
179         ec.updateProperties(runElement);
180         runElement.run(ec);
181         log.info("Completed : " + runnable);
182       } else if (runObj instanceof Integer) {
183         Integer delay = (Integer) runObj;
184         log.info("Sleeping  : " + delay);
185         Thread.sleep( (delay.longValue() * 1000) );
186         log.info("Continuing: " + delay);
187       } else {
188         throw new ConfigurationException("Unknown runnable object type: " + runObj);
189       }
190     }
191   }
192 
193 } // END Experiment