source: DCWoRMS/trunk/src/simulator/DataCenterWorkloadSimulator.java @ 481

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