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

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