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

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