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

Revision 1452, 15.1 KB checked in by wojtekp, 10 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 schedframe.resources.utils.ResourceIdGenerator;
25import schedframe.scheduling.manager.tasks.JobRegistryImpl;
26import simulator.reader.ResourceReader;
27import simulator.stats.AccumulatedStatistics;
28import simulator.stats.implementation.DCWormsStatistics;
29import simulator.utils.LogErrStream;
30import simulator.workload.WorkloadLoader;
31import simulator.workload.reader.archive.AbstractWAReader;
32import simulator.workload.reader.archive.WAReader;
33import simulator.workload.reader.xmlJob.QcgXmlJobReader;
34import simulator.workload.reader.xmlJob.XMLJobReader;
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                                ResourceIdGenerator.reset();
183                                JobRegistryImpl.reset();
184
185                        } catch (Exception e) {
186                                if (log.isErrorEnabled())
187                                        log.error("ERROR in simulation run \""
188                                                        + simulationIdentifier + "\":", e);
189                                break;
190                        }
191                }
192
193                if (log.isInfoEnabled()){
194                        log.info("Done :: " + SIMULATOR_NAME + " has finished "
195                                        + noOfSimulations + " simulation runs ::");
196                        log.info("Simulation finished with status: 0");
197                }
198
199                System.out.flush();
200                System.err.flush();
201
202                try {
203                        copyFile(new File(propertiesFileName), outputPropertiesFile);
204                } catch (IOException e) {
205                        log.error("IO exception occured during copying properties file to output path");
206                }
207        }
208
209        private void runMultiuser(String rootDirPath, DataCenterWorkloadSimulator dcworms) {
210                throw new RuntimeException("not supported yet");
211        }
212
213
214        /**
215         * Starts a single simulation run.
216         *
217         * @param options
218         *            the configuration options according to which the simulation is
219         *            to be performed
220         * @param simulationStatistics
221         *            the statistics object that is to be filled after the
222         *            simulation run
223         * @throws Exception
224         *             any exception that may occur
225         */
226        private void performSimulation(String simulationIdentifier,
227                        ConfigurationOptions options) throws Exception {
228                // Startup of the random number generators must be set up with a random
229                // seed that is greater than zero
230                // if seed is not given then all consecutive simulations are the same
231                // if seed < 0 then the random numbers are equal to zero
232                Uniform uniform = new Uniform(new MersenneTwister64(new Date()));
233                // seed should be > 0 and fits to int size (which is also important)
234                long seed = uniform.nextLongFromTo(1, Integer.MAX_VALUE);
235                if (log.isDebugEnabled())
236                        log.debug("Shuffled initial seed: " + seed);
237
238                assert seed > 0 && seed <= Integer.MAX_VALUE : "Initial seed is <= 0, what is improper";
239               
240                GridSimWrapper.setSeed(seed);
241                GridSimWrapper.setTraceSettings();
242               
243                long startSimulation = System.currentTimeMillis();
244                if (log.isInfoEnabled()) {
245                        log.info(":: Starting simulation run: \"" + simulationIdentifier
246                                        + "\" ::");
247                        log.info(":: In the the mode of ");
248                }
249
250                WorkloadLoader workload = null;
251               
252                try{
253                        workload = loadWorkload(options);
254                } catch (Exception e) {
255                        if (log.isErrorEnabled())
256                                log.error("ERROR while reading workload and application profiles");
257                        throw e;
258                }
259       
260                // BEGIN: Initializing the GridSim:
261                int numUser = 1; // the number of users in the experiment simulation
262                // (default 1)
263               
264                Calendar calendar = Calendar.getInstance();
265                if(workload == null){
266                        calendar.setTimeInMillis(0L);
267                } else {
268                        Date date = workload.getSimulationStartTime();
269                        if (date == null)
270                                calendar.setTimeInMillis(0L);
271                        else
272                                calendar.setTime(date);                 
273                }
274
275
276                boolean traceFlag = false; // means: trace GridSim events/activities
277
278                GridSimWrapper.init(numUser, calendar, traceFlag);
279                DateTimeUtilsExt.initVirtualTimeAccess(calendar);
280
281                ResourceReader resourceReader = new ResourceReader(
282                                options.resdescFileName);
283                SimulatedEnvironment simEnv;
284               
285                try {
286                        simEnv= resourceReader.read();
287                } catch (Exception e){
288                        if (log.isErrorEnabled())
289                                log.error("ERROR while reading resource description");
290                        throw e;
291                }
292               
293                eventManager = new EventManager("eventManager", simEnv);
294               
295                /*for(Initializable initObj: rc.getToInit()){
296                        initObj.initiate();
297                }
298                rc.setInitList(null);*/
299               
300                DCWormsUsers users = new DCWormsUsers("Users",
301                                simEnv.getScheduler().get_name(), workload);
302               
303                System.out.println("Starting simulation...");
304
305                GridSimWrapper.startSimulation();
306                long stopSimulation = System.currentTimeMillis();
307
308                System.out.println("Simulation finished");
309
310                DCWormsStatistics stats = new DCWormsStatistics(simulationIdentifier,
311                                options, users, statsOutputPath, simEnv);
312                accumulatedStatistics.add(stats);
313                if (log.isInfoEnabled())
314                        log.info("Generating statistics...");
315                stats.generateStatistics();
316
317                long duration = (stopSimulation - startSimulation) / 1000;
318                if (log.isInfoEnabled())
319                        log.info("The simulation run took " + duration + " seconds");
320
321                // if necessary generate gifs from sjvg - need to rewrite the SJVG
322                // classes for public methods
323                if (log.isInfoEnabled())
324                        log.info(":: Finished simulation run: \"" + simulationIdentifier
325                                        + "\" ::");
326
327                System.out.flush();
328                System.err.flush();
329        }
330
331        private WorkloadLoader loadWorkload(ConfigurationOptions options) throws IOException, MarshalException, ValidationException{
332                XMLJobReader<org.qcg.broker.schemas.jobdesc.Job> xmlJobReader = null;
333                WAReader<org.qcg.broker.schemas.jobdesc.Job> workloadReader = null;
334
335                String wlFileName = options.inputWorkloadFileName;
336
337                if(wlFileName == null){
338                        return null;
339                }
340               
341                if (options.inputFolder != null) {
342                        File f = new File(options.inputFolder);
343                        xmlJobReader = new QcgXmlJobReader(f);
344
345                        wlFileName = options.inputFolder + File.separator
346                                        + options.inputWorkloadFileName;
347                }
348
349                workloadReader = AbstractWAReader.getInstace(wlFileName);
350               
351                String appProfilesFolderName = options.appProfilesFolder;
352               
353                WorkloadLoader workload = new WorkloadLoader(xmlJobReader, workloadReader, appProfilesFolderName);
354                workload.load();
355
356                return workload;
357        }
358       
359
360        private File prepareDirecotry(ConfigurationOptions options) throws Exception {
361                // String statsOutputPath = null;
362                if (options.createScenario) {
363                        File outputFolderFile = new File(options.outputFolder);
364                        if (!outputFolderFile.exists()) {
365                                if (!outputFolderFile.mkdirs())
366                                        throw new IOException("Cannot create the output path: "
367                                                        + statsOutputPath + ". Cause: ");
368                        }
369
370                        if (log.isInfoEnabled())
371                                log.info("CREATING SCENARIO ::");
372                        statsOutputPath = options.outputFolder
373                                        + options.statsOutputSubfolderNameCreate;
374                } else {
375                        if (log.isInfoEnabled())
376                                log.info("READING SCENARIO ::");
377                        String prefix = null;
378                        if (options.inputFolder != null) {
379                                prefix = options.inputFolder;
380                        } else if (options.inputWorkloadFileName != null) {
381                                prefix = FilenameUtils.getFullPath(new File(options.inputWorkloadFileName).getAbsolutePath());
382                        } else {
383                                prefix = System.getProperty("user.dir");
384                        }
385                        //statsOutputPath = prefix + File.separator
386                        //              + options.statsOutputSubfolderNameRead;
387                        statsOutputPath = options.statsOutputSubfolderNameRead;
388                }
389                statsOutputPath += File.separator;
390
391                // create the output folder
392                File statsOutputPathFile = new File(statsOutputPath);
393                if (!statsOutputPathFile.exists()) {
394                        if (!statsOutputPathFile.mkdirs())
395                                throw new IOException("Cannot create the output (stats) path: "
396                                                + statsOutputPath + ". Cause: ");
397                }
398
399                File folder = new File(statsOutputPath);
400                File fileList[] = folder.listFiles();
401                for (int i = 0; i < fileList.length; i++) {
402                        File tmpFile = fileList[i];
403                        String name = tmpFile.getName();
404                        if (name.length() > 4) {
405                                String subName = name.substring(0, 5);
406                                if (subName.compareTo("Chart") == 0
407                                                || subName.compareTo("Stats") == 0) {
408                                        tmpFile.delete();
409                                }
410                        }
411                }
412                return statsOutputPathFile;
413        }
414
415        /**
416         * Removes the given directory no matter if it is empty or non empty. If the
417         * given parameter represents a file, it is not deleted. See the description
418         * of the return statement.
419         *
420         * @param dirPath
421         *            the file representing the directory to be deleted.
422         * @return true, if the given directory with all its contents have been
423         *         remove; false if deletion of any of files ended with error (all
424         *         other files are possibly also deleted)
425         */
426        private static boolean deleteDirectory(File dirPath) {
427                if (dirPath.exists() && dirPath.isDirectory()) {
428                        boolean result = true;
429                        File[] files = dirPath.listFiles();
430                        for (File file : files) {
431                                if (file.isFile())
432                                        result |= file.delete();
433                                else
434                                        result |= deleteDirectory(file);
435                        }
436                        result |= dirPath.delete();
437                        return result;
438                }
439                return false; // it is not a directory
440        }
441       
442        /**
443         * Static method to move a file from given "from" location to "to" location
444         *
445         * @param from
446         *            from location
447         * @param to
448         *            to location
449         * @return true if the operation succeeded, false otherwise
450         */
451        private static boolean moveFile(String from, String to) {
452                File fromFile = new File(from);
453                File toFile = new File(to);
454                if (toFile.exists()) {
455                        if (!toFile.delete())
456                                return false;
457                }
458                if (!fromFile.renameTo(toFile)) {
459                        return false;
460                }
461                return true;
462        }
463       
464        private void copyFile(File inputFile, File outputFile) throws IOException {
465
466                FileReader in = new FileReader(inputFile);
467                FileWriter out = new FileWriter(outputFile);
468                int c;
469
470                while ((c = in.read()) != -1)
471                        out.write(c);
472
473                in.close();
474                out.close();
475        }
476
477        /**
478         * Returns the accumulated simulation statistics from the last run of the
479         * simulator
480         *
481         * @return the accumulated simulation statistics from the last run of the
482         *         simulator
483         */
484        public static AccumulatedStatistics getAccumulatedStatistics() {
485                return accumulatedStatistics;
486        }
487
488        public static int getSimulationRunNumber(){
489                return simulationRunNumber;
490        }
491       
492        protected class WorkloadDirectoryFilter implements java.io.FileFilter {
493
494                public boolean accept(File file) {
495                        if (file.isDirectory() && file.getName().startsWith("workload"))
496                                return true;
497                        else
498                                return false;
499                }
500        }
501
502        protected class PropertiesFileFilter implements java.io.FileFilter {
503
504                public boolean accept(File file) {
505                        if (file.isFile() && file.getName().endsWith(".properties"))
506                                return true;
507                        else
508                                return false;
509                }
510        }
511
512        private static EventManager eventManager;
513        public static EventManager getEventManager(){
514                return eventManager;
515               
516        }
517}
Note: See TracBrowser for help on using the repository browser.