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

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