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

Revision 1346, 15.0 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 = true; // means: trace GridSim events/activities
274                String[] excludeFromFile = { "" }, excludeFromProcessing = { "" };
275               
276                GridSimWrapper.init(numUser, calendar, traceFlag, excludeFromFile,
277                                excludeFromProcessing, null);
278                DateTimeUtilsExt.initVirtualTimeAccess(calendar);
279
280                ResourceReader resourceReader = new ResourceReader(
281                                options.resdescFileName);
282                SimulatedEnvironment simEnv;
283               
284                try {
285                        simEnv= resourceReader.read();
286                } catch (Exception e){
287                        if (log.isErrorEnabled())
288                                log.error("ERROR while reading resource description");
289                        throw e;
290                }
291               
292                eventManager = new EventManager("eventManager", simEnv);
293               
294                /*for(Initializable initObj: rc.getToInit()){
295                        initObj.initiate();
296                }
297                rc.setInitList(null);*/
298               
299                DCWormsUsers users = new DCWormsUsers("Users",
300                                simEnv.getScheduler().get_name(), workload);
301               
302                System.out.println("Starting simulation...");
303
304                GridSimWrapper.startSimulation();
305                long stopSimulation = System.currentTimeMillis();
306
307                System.out.println("Simulation finished");
308
309                DCWormsStatistics stats = new DCWormsStatistics(simulationIdentifier,
310                                options, users, statsOutputPath, simEnv);
311                accumulatedStatistics.add(stats);
312                if (log.isInfoEnabled())
313                        log.info("Generating statistics...");
314                stats.generateStatistics();
315
316                long duration = (stopSimulation - startSimulation) / 1000;
317                if (log.isInfoEnabled())
318                        log.info("The simulation run took " + duration + " seconds");
319
320                // if necessary generate gifs from sjvg - need to rewrite the SJVG
321                // classes for public methods
322                if (log.isInfoEnabled())
323                        log.info(":: Finished simulation run: \"" + simulationIdentifier
324                                        + "\" ::");
325
326                System.out.flush();
327                System.err.flush();
328        }
329
330        private WorkloadLoader loadWorkload(ConfigurationOptions options) throws IOException, MarshalException, ValidationException{
331                XMLJobReader<org.qcg.broker.schemas.jobdesc.Job> xmlJobReader = null;
332                WAReader<org.qcg.broker.schemas.jobdesc.Job> workloadReader = null;
333
334                String wlFileName = options.inputWorkloadFileName;
335
336                if(wlFileName == null){
337                        return null;
338                }
339               
340                if (options.inputFolder != null) {
341                        File f = new File(options.inputFolder);
342                        xmlJobReader = new QcgXmlJobReader(f);
343
344                        wlFileName = options.inputFolder + File.separator
345                                        + options.inputWorkloadFileName;
346                }
347
348                workloadReader = AbstractWAReader.getInstace(wlFileName);
349               
350                String appProfilesFolderName = options.appProfilesFolder;
351               
352                WorkloadLoader workload = new WorkloadLoader(xmlJobReader, workloadReader, appProfilesFolderName);
353                workload.load();
354
355                return workload;
356        }
357       
358
359        private File prepareDirecotry(ConfigurationOptions options) throws Exception {
360                // String statsOutputPath = null;
361                if (options.createScenario) {
362                        File outputFolderFile = new File(options.outputFolder);
363                        if (!outputFolderFile.exists()) {
364                                if (!outputFolderFile.mkdirs())
365                                        throw new IOException("Cannot create the output path: "
366                                                        + statsOutputPath + ". Cause: ");
367                        }
368
369                        if (log.isInfoEnabled())
370                                log.info("CREATING SCENARIO ::");
371                        statsOutputPath = options.outputFolder
372                                        + options.statsOutputSubfolderNameCreate;
373                } else {
374                        if (log.isInfoEnabled())
375                                log.info("READING SCENARIO ::");
376                        String prefix = null;
377                        if (options.inputFolder != null) {
378                                prefix = options.inputFolder;
379                        } else if (options.inputWorkloadFileName != null) {
380                                prefix = FilenameUtils.getFullPath(new File(options.inputWorkloadFileName).getAbsolutePath());
381                        } else {
382                                prefix = System.getProperty("user.dir");
383                        }
384                        //statsOutputPath = prefix + File.separator
385                        //              + options.statsOutputSubfolderNameRead;
386                        statsOutputPath = options.statsOutputSubfolderNameRead;
387                }
388                statsOutputPath += File.separator;
389
390                // create the output folder
391                File statsOutputPathFile = new File(statsOutputPath);
392                if (!statsOutputPathFile.exists()) {
393                        if (!statsOutputPathFile.mkdirs())
394                                throw new IOException("Cannot create the output (stats) path: "
395                                                + statsOutputPath + ". Cause: ");
396                }
397
398                File folder = new File(statsOutputPath);
399                File fileList[] = folder.listFiles();
400                for (int i = 0; i < fileList.length; i++) {
401                        File tmpFile = fileList[i];
402                        String name = tmpFile.getName();
403                        if (name.length() > 4) {
404                                String subName = name.substring(0, 5);
405                                if (subName.compareTo("Chart") == 0
406                                                || subName.compareTo("Stats") == 0) {
407                                        tmpFile.delete();
408                                }
409                        }
410                }
411                return statsOutputPathFile;
412        }
413
414        /**
415         * Removes the given directory no matter if it is empty or non empty. If the
416         * given parameter represents a file, it is not deleted. See the description
417         * of the return statement.
418         *
419         * @param dirPath
420         *            the file representing the directory to be deleted.
421         * @return true, if the given directory with all its contents have been
422         *         remove; false if deletion of any of files ended with error (all
423         *         other files are possibly also deleted)
424         */
425        private static boolean deleteDirectory(File dirPath) {
426                if (dirPath.exists() && dirPath.isDirectory()) {
427                        boolean result = true;
428                        File[] files = dirPath.listFiles();
429                        for (File file : files) {
430                                if (file.isFile())
431                                        result |= file.delete();
432                                else
433                                        result |= deleteDirectory(file);
434                        }
435                        result |= dirPath.delete();
436                        return result;
437                }
438                return false; // it is not a directory
439        }
440       
441        /**
442         * Static method to move a file from given "from" location to "to" location
443         *
444         * @param from
445         *            from location
446         * @param to
447         *            to location
448         * @return true if the operation succeeded, false otherwise
449         */
450        private static boolean moveFile(String from, String to) {
451                File fromFile = new File(from);
452                File toFile = new File(to);
453                if (toFile.exists()) {
454                        if (!toFile.delete())
455                                return false;
456                }
457                if (!fromFile.renameTo(toFile)) {
458                        return false;
459                }
460                return true;
461        }
462       
463        private void copyFile(File inputFile, File outputFile) throws IOException {
464
465                FileReader in = new FileReader(inputFile);
466                FileWriter out = new FileWriter(outputFile);
467                int c;
468
469                while ((c = in.read()) != -1)
470                        out.write(c);
471
472                in.close();
473                out.close();
474        }
475
476        /**
477         * Returns the accumulated simulation statistics from the last run of the
478         * simulator
479         *
480         * @return the accumulated simulation statistics from the last run of the
481         *         simulator
482         */
483        public static AccumulatedStatistics getAccumulatedStatistics() {
484                return accumulatedStatistics;
485        }
486
487        public static int getSimulationRunNumber(){
488                return simulationRunNumber;
489        }
490       
491        protected class WorkloadDirectoryFilter implements java.io.FileFilter {
492
493                public boolean accept(File file) {
494                        if (file.isDirectory() && file.getName().startsWith("workload"))
495                                return true;
496                        else
497                                return false;
498                }
499        }
500
501        protected class PropertiesFileFilter implements java.io.FileFilter {
502
503                public boolean accept(File file) {
504                        if (file.isFile() && file.getName().endsWith(".properties"))
505                                return true;
506                        else
507                                return false;
508                }
509        }
510
511        private static EventManager eventManager;
512        public static EventManager getEventManager(){
513                return eventManager;
514               
515        }
516}
Note: See TracBrowser for help on using the repository browser.