source: DCWoRMS/trunk/build/classes/simulator/DataCenterWorkloadSimulator.java @ 539

Revision 539, 14.1 KB checked in by wojtekp, 12 years ago (diff)
  • Property svn:mime-type set to text/plain
Line 
1package simulator;
2
3import java.io.File;
4import java.io.FileReader;
5import java.io.FileWriter;
6import java.io.IOException;
7import java.io.PrintStream;
8import java.security.InvalidParameterException;
9import java.text.NumberFormat;
10import java.util.Calendar;
11import java.util.Date;
12
13import javax.swing.JFileChooser;
14import javax.swing.filechooser.FileFilter;
15
16import org.apache.commons.logging.Log;
17import org.apache.commons.logging.LogFactory;
18import org.exolab.castor.xml.MarshalException;
19import org.exolab.castor.xml.ValidationException;
20import org.joda.time.DateTimeUtilsExt;
21import org.qcg.broker.schemas.jobdesc.QcgJob;
22
23import schedframe.Initializable;
24import schedframe.ResourceController;
25import simulator.reader.ResourceReader;
26import simulator.stats.AccumulatedStatistics;
27import simulator.stats.implementation.DCWormsStatistics;
28import simulator.utils.LogErrStream;
29import simulator.workload.WorkloadLoader;
30import simulator.workload.reader.archive.AbstractWAReader;
31import simulator.workload.reader.archive.WAReader;
32import simulator.workload.reader.xmlJob.QcgXmlJobReader;
33import simulator.workload.reader.xmlJob.XMLJobReader;
34import cern.jet.random.Uniform;
35import cern.jet.random.engine.MersenneTwister64;
36
37/**
38 * The main class of the Data Center Workload Scheduling Simulator. It has the
39 * {@link #main(String[])} method used to invoke the program. This class also
40 * provides second possibility to start the simulator, namely one may use the
41 * {@link #performSimulation(ConfigurationOptions, DCWormsStatistics)} method.
42 * In this case, the input parameter, describing the simulation options, must be
43 * earlier prepared. The results of the simulation can be acquired using the
44 * {@link #getAccumulatedStatistics()} method.
45 *
46 * @author Stanislaw Szczepanowski & Wojciech Piatek
47 */
48public class DataCenterWorkloadSimulator {
49
50        /**
51         * The name of the simulator application
52         */
53        public static final String SIMULATOR_NAME = "Data Center Workload Simulator";
54
55        /**
56         * Stores the statistical data of last run of the simulator (it may consist
57         * of several runs of simulations)
58         */
59        protected static AccumulatedStatistics accumulatedStatistics;
60
61        protected static int simulationRunNumber = 0;
62
63        /**
64         * Determines the maximum fraction digits when printing floating point
65         * values
66         */
67        public static int MAXIMUM_FRACTION_DIGITS = 3;
68
69        /**
70         * The format of the numbers that will be printed
71         */
72        public static NumberFormat DFAULT_NUMBER_FORMAT = NumberFormat
73                        .getInstance();
74        static {
75                DFAULT_NUMBER_FORMAT.setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS); // 0,001
76        }
77
78        private Log log = LogFactory.getLog(DataCenterWorkloadSimulator.class);
79
80        protected String statsOutputPath;
81
82
83        /**
84         * Default empty constructor
85         */
86        public DataCenterWorkloadSimulator() {
87        }
88
89        /**
90         * The main method to start the simulation the accepted arguments are:
91         * args[0] - the name of the resource bundle file with the configuration
92         * args[1] (optional) - the number of simulations that are to be performed
93         * (the default value is 1)
94         *
95         * @param args
96         *            the arguments passed to the application
97         */
98        public static void main(String[] args) {
99                DataCenterWorkloadSimulator dcworms = new DataCenterWorkloadSimulator();
100                dcworms.run(args);
101        }
102
103        public void run(String args[]) {
104                System.setErr(new PrintStream(new LogErrStream(log)));
105
106                String propertiesFileName = null;
107                if (args.length == 0) {
108                        JFileChooser ch = new JFileChooser(".");
109                        FileFilter filter = new FileFilter() {
110                                @Override
111                                public boolean accept(File f) {
112                                        return f.getName().endsWith(".properties")
113                                                        || f.isDirectory();
114                                }
115
116                                @Override
117                                public String getDescription() {
118                                        return "DCWoRMS experiment file";
119                                }
120                        };
121                        ch.setFileFilter(filter);
122                        ch.setDialogTitle("Choose the WoRMS simulation experiment file");
123                        int result = ch.showOpenDialog(ch);
124                        if (result == JFileChooser.APPROVE_OPTION) {
125                                propertiesFileName = ch.getSelectedFile().getAbsolutePath();
126                        } else {
127                                if (log.isFatalEnabled())
128                                        log.fatal("Resource bundle file name was not provided.");
129                                return;
130                        }
131                } else if (args.length == 2 && "-multiuser".equals(args[0])) {
132                        runMultiuser(args[1], this);
133                        return;
134                } else {
135                        propertiesFileName = args[0];
136                }
137
138                ConfigurationOptions configurationOptions = ConfigurationOptions
139                                .getConfiguration(propertiesFileName);
140                int noOfSimulations = 1; // default value is one
141
142                if(configurationOptions.getNumberOfSimulations() > 1)
143                        noOfSimulations = configurationOptions.getNumberOfSimulations();
144                else if (args.length == 2) {// second parameter is given
145                        noOfSimulations = Integer.parseInt(args[1]);
146                        if (noOfSimulations < 1) {
147                                throw new InvalidParameterException(
148                                                "Number of simulations cannot be less than 1");
149                        }
150                }
151
152                if (log.isInfoEnabled())
153                        log.info(":: Starting " + SIMULATOR_NAME + ". " + noOfSimulations
154                                        + " simulation runs will be performed. ::");
155
156                File outputDir = null;
157
158                try {
159                        outputDir = prepareDirecotry(configurationOptions);
160                } catch (Exception e) {
161                        if (log.isErrorEnabled())
162                                log.error("FAILED to create the output path", e);
163                        return;
164                }
165
166                File outputPropertiesFile = new File(outputDir, "experiment.properties");
167
168                accumulatedStatistics = new AccumulatedStatistics(noOfSimulations);
169               
170                for (int i = 0; i < noOfSimulations; ++i) {
171                        simulationRunNumber++;
172                        String simulationIdentifier = "Simulation " + (i + 1);
173                        try {
174                                performSimulation(simulationIdentifier,
175                                                configurationOptions); // run the simulation
176
177                        } catch (Exception e) {
178                                if (log.isErrorEnabled())
179                                        log.error("ERROR in simulation run \""
180                                                        + simulationIdentifier + "\":", e);
181                                break;
182                        }
183                }
184
185                if (log.isInfoEnabled())
186                        log.info("Done :: " + SIMULATOR_NAME + " has finished "
187                                        + noOfSimulations + " simulation runs ::");
188
189                System.out.flush();
190                System.err.flush();
191
192                try {
193                        copyFile(new File(propertiesFileName), outputPropertiesFile);
194                } catch (IOException e) {
195                        log.error("IO exception occured during copying properties file to output path");
196                }
197        }
198
199        private void runMultiuser(String rootDirPath, DataCenterWorkloadSimulator dcworms) {
200                throw new RuntimeException("not supported yet");
201        }
202
203
204        /**
205         * Starts a single simulation run.
206         *
207         * @param options
208         *            the configuration options according to which the simulation is
209         *            to be performed
210         * @param simulationStatistics
211         *            the statistics object that is to be filled after the
212         *            simulation run
213         * @throws Exception
214         *             any exception that may occur
215         */
216        private void performSimulation(String simulationIdentifier,
217                        ConfigurationOptions options) throws Exception {
218                // Startup of the random number generators must be set up with a random
219                // seed that is greater than zero
220                // if seed is not given then all consecutive simulations are the same
221                // if seed < 0 then the random numbers are equal to zero
222                Uniform uniform = new Uniform(new MersenneTwister64(new Date()));
223                // seed should be > 0 and fits to int size (which is also important)
224                long seed = uniform.nextLongFromTo(1, Integer.MAX_VALUE);
225                if (log.isDebugEnabled())
226                        log.debug("Shuffled initial seed: " + seed);
227
228                assert seed > 0 && seed <= Integer.MAX_VALUE : "Initial seed is <= 0, what is improper";
229               
230                GridSimWrapper.setSeed(seed);
231                GridSimWrapper.setTraceSettings();
232               
233                long startSimulation = System.currentTimeMillis();
234                if (log.isInfoEnabled()) {
235                        log.info(":: Starting simulation run: \"" + simulationIdentifier
236                                        + "\" ::");
237                        log.info(":: In the the mode of ");
238                }
239
240                WorkloadLoader workload = loadWorkload(options);
241       
242                // BEGIN: Initializing the GridSim:
243                int numUser = 1; // the number of users in the experiment simulation
244                // (default 1)
245               
246                Date date = workload.getSimulationStartTime();
247                Calendar calendar = Calendar.getInstance();
248                if (date == null)
249                        calendar.setTimeInMillis(0L);
250                else
251                        calendar.setTime(date);
252
253                boolean traceFlag = true; // means: trace GridSim events/activities
254                String[] excludeFromFile = { "" }, excludeFromProcessing = { "" };
255               
256                GridSimWrapper.init(numUser, calendar, traceFlag, excludeFromFile,
257                                excludeFromProcessing, null);
258                DateTimeUtilsExt.initVirtualTimeAccess(calendar);
259
260                ResourceReader resourceReader = new ResourceReader(
261                                options);
262                ResourceController rc = resourceReader.read();
263
264                while(!rc.getToInit().isEmpty()){
265                        Initializable initObj = rc.getToInit().pop();
266                        initObj.initiate();
267                }
268                rc.setInitList(null);
269               
270                DCWormsUsers wl = new DCWormsUsers("Users",
271                                rc.getScheduler().get_name(), workload);
272               
273                GridSimWrapper.startSimulation();
274                long stopSimulation = System.currentTimeMillis();
275
276                DCWormsStatistics stats = new DCWormsStatistics(simulationIdentifier,
277                                options, wl, statsOutputPath, rc);
278                accumulatedStatistics.add(stats);
279                if (log.isInfoEnabled())
280                        log.info("Generating statistics...");
281                stats.generateStatistics();
282
283                long duration = (stopSimulation - startSimulation) / 1000;
284                if (log.isInfoEnabled())
285                        log.info("The simulation run took " + duration + " seconds");
286
287                // if necessary generate gifs from sjvg - need to rewrite the SJVG
288                // classes for public methods
289                if (log.isInfoEnabled())
290                        log.info(":: Finished simulation run: \"" + simulationIdentifier
291                                        + "\" ::");
292
293                System.out.flush();
294                System.err.flush();
295        }
296
297        private WorkloadLoader loadWorkload(ConfigurationOptions options) throws IOException, MarshalException, ValidationException{
298                XMLJobReader<QcgJob> xmlJobReader = null;
299                WAReader<QcgJob> swfReader = null;
300
301                String wlFileName = options.inputWorkloadFileName;
302
303                if (options.inputFolder != null) {
304                        File f = null;
305                        if (options.inputTar != null) {
306                                f = new File(options.inputFolder + File.separator
307                                                + options.inputTar);
308                        } else {
309                                f = new File(options.inputFolder);
310                        }
311
312                        xmlJobReader = new QcgXmlJobReader(f);
313
314                        wlFileName = options.inputFolder + File.separator
315                                        + options.inputWorkloadFileName;
316                }
317
318                swfReader = AbstractWAReader.getInstace(wlFileName);
319
320                WorkloadLoader workload = new WorkloadLoader(xmlJobReader, swfReader);
321                workload.load();
322
323                return workload;
324        }
325       
326
327        private File prepareDirecotry(ConfigurationOptions options) throws Exception {
328                // String statsOutputPath = null;
329                if (options.createScenario) {
330                        File outputFolderFile = new File(options.outputFolder);
331                        if (!outputFolderFile.exists()) {
332                                if (!outputFolderFile.mkdirs())
333                                        throw new IOException("Cannot create the output path: "
334                                                        + statsOutputPath + ". Cause: ");
335                        }
336
337                        if (log.isInfoEnabled())
338                                log.info("CREATING SCENARIO ::");
339                        statsOutputPath = options.outputFolder
340                                        + options.statsOutputSubfolderNameCreate;
341                } else {
342                        if (log.isInfoEnabled())
343                                log.info("READING SCENARIO ::");
344                        String prefix = null;
345                        if (options.inputFolder != null) {
346                                prefix = options.inputFolder;
347                        } else if (options.inputWorkloadFileName != null) {
348                                prefix = new File(options.inputWorkloadFileName).getParent();
349                        } else {
350                                prefix = System.getProperty("user.dir");
351                        }
352                        statsOutputPath = prefix + File.separator
353                                        + options.statsOutputSubfolderNameRerad;
354                }
355                statsOutputPath += File.separator;
356
357                // create the output folder
358                File statsOutputPathFile = new File(statsOutputPath);
359                if (!statsOutputPathFile.exists()) {
360                        if (!statsOutputPathFile.mkdirs())
361                                throw new IOException("Cannot create the output (stats) path: "
362                                                + statsOutputPath + ". Cause: ");
363                }
364
365                File folder = new File(statsOutputPath);
366                File fileList[] = folder.listFiles();
367                for (int i = 0; i < fileList.length; i++) {
368                        File tmpFile = fileList[i];
369                        String name = tmpFile.getName();
370                        if (name.length() > 4) {
371                                String subName = name.substring(0, 5);
372                                if (subName.compareTo("Chart") == 0
373                                                || subName.compareTo("Stats") == 0) {
374                                        tmpFile.delete();
375                                }
376                        }
377                }
378                return statsOutputPathFile;
379        }
380
381        /**
382         * Removes the given directory no matter if it is empty or non empty. If the
383         * given parameter represents a file, it is not deleted. See the description
384         * of the return statement.
385         *
386         * @param dirPath
387         *            the file representing the directory to be deleted.
388         * @return true, if the given directory with all its contents have been
389         *         remove; false if deletion of any of files ended with error (all
390         *         other files are possibly also deleted)
391         */
392        private static boolean deleteDirectory(File dirPath) {
393                if (dirPath.exists() && dirPath.isDirectory()) {
394                        boolean result = true;
395                        File[] files = dirPath.listFiles();
396                        for (File file : files) {
397                                if (file.isFile())
398                                        result |= file.delete();
399                                else
400                                        result |= deleteDirectory(file);
401                        }
402                        result |= dirPath.delete();
403                        return result;
404                }
405                return false; // it is not a directory
406        }
407       
408        /**
409         * Static method to move a file from given "from" location to "to" location
410         *
411         * @param from
412         *            from location
413         * @param to
414         *            to location
415         * @return true if the operation succeeded, false otherwise
416         */
417        private static boolean moveFile(String from, String to) {
418                File fromFile = new File(from);
419                File toFile = new File(to);
420                if (toFile.exists()) {
421                        if (!toFile.delete())
422                                return false;
423                }
424                if (!fromFile.renameTo(toFile)) {
425                        return false;
426                }
427                return true;
428        }
429       
430        private void copyFile(File inputFile, File outputFile) throws IOException {
431
432                FileReader in = new FileReader(inputFile);
433                FileWriter out = new FileWriter(outputFile);
434                int c;
435
436                while ((c = in.read()) != -1)
437                        out.write(c);
438
439                in.close();
440                out.close();
441        }
442
443        /**
444         * Returns the accumulated simulation statistics from the last run of the
445         * simulator
446         *
447         * @return the accumulated simulation statistics from the last run of the
448         *         simulator
449         */
450        public static AccumulatedStatistics getAccumulatedStatistics() {
451                return accumulatedStatistics;
452        }
453
454        public static int getSimulationRunNumber(){
455                return simulationRunNumber;
456        }
457       
458        protected class WorkloadDirectoryFilter implements java.io.FileFilter {
459
460                public boolean accept(File file) {
461                        if (file.isDirectory() && file.getName().startsWith("workload"))
462                                return true;
463                        else
464                                return false;
465                }
466        }
467
468        protected class PropertiesFileFilter implements java.io.FileFilter {
469
470                public boolean accept(File file) {
471                        if (file.isFile() && file.getName().endsWith(".properties"))
472                                return true;
473                        else
474                                return false;
475                }
476        }
477
478}
Note: See TracBrowser for help on using the repository browser.