source: DCWoRMS/branches/coolemall/src/simulator/DataCenterWorkloadSimulator.java @ 1207

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