/** * Copyright 2012-2013 University Of Southern California * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.workflowsim; import java.util.ArrayList; import java.util.List; import org.cloudbus.cloudsim.Log; import org.cloudbus.cloudsim.core.CloudSimTags; import org.cloudbus.cloudsim.core.SimEntity; import org.cloudbus.cloudsim.core.SimEvent; import org.workflowsim.planning.BasePlanningAlgorithm; import org.workflowsim.planning.DHEFTPlanningAlgorithm; import org.workflowsim.planning.HEFTPlanningAlgorithm; import org.workflowsim.planning.RandomPlanningAlgorithm; import org.workflowsim.utils.Parameters; import org.workflowsim.utils.Parameters.PlanningAlgorithm; /** * WorkflowPlanner supports dynamic planning. In the future we will have global * and static algorithm here. The WorkflowSim starts from WorkflowPlanner. It * picks up a planning algorithm based on the configuration * * @author Weiwei Chen * @since WorkflowSim Toolkit 1.0 * @date Apr 9, 2013 * */ public final class WorkflowPlanner extends SimEntity { /** * The task list. */ protected List< Task> taskList; /** * The workflow parser. */ protected WorkflowParser parser; /** * The associated clustering engine. */ private int clusteringEngineId; private ClusteringEngine clusteringEngine; /** * Created a new WorkflowPlanner object. * * @param name name to be associated with this entity (as required by * Sim_entity class from simjava package) * @throws Exception the exception * @pre name != null * @post $none */ public WorkflowPlanner(String name) throws Exception { this(name, 1); } public WorkflowPlanner(String name, int schedulers) throws Exception { super(name); setTaskList(new ArrayList<>()); this.clusteringEngine = new ClusteringEngine(name + "_Merger_", schedulers); this.clusteringEngineId = this.clusteringEngine.getId(); this.parser = new WorkflowParser(getClusteringEngine().getWorkflowEngine().getSchedulerId(0)); } /** * Gets the clustering engine id * * @return clustering engine id */ public int getClusteringEngineId() { return this.clusteringEngineId; } /** * Gets the clustering engine * * @return the clustering engine */ public ClusteringEngine getClusteringEngine() { return this.clusteringEngine; } /** * Gets the workflow parser * * @return the workflow parser */ public WorkflowParser getWorkflowParser() { return this.parser; } /** * Gets the workflow engine id * * @return the workflow engine id */ public int getWorkflowEngineId() { return getClusteringEngine().getWorkflowEngineId(); } /** * Gets the workflow engine * * @return the workflow engine */ public WorkflowEngine getWorkflowEngine() { return getClusteringEngine().getWorkflowEngine(); } /** * Processes events available for this Broker. * * @param ev a SimEvent object * @pre ev != null * @post $none */ @Override public void processEvent(SimEvent ev) { switch (ev.getTag()) { case WorkflowSimTags.START_SIMULATION: getWorkflowParser().parse(); setTaskList(getWorkflowParser().getTaskList()); processPlanning(); processImpactFactors(getTaskList()); sendNow(getClusteringEngineId(), WorkflowSimTags.JOB_SUBMIT, getTaskList()); break; case CloudSimTags.END_OF_SIMULATION: shutdownEntity(); break; // other unknown tags are processed by this method default: processOtherEvent(ev); break; } } private void processPlanning() { if (Parameters.getPlanningAlgorithm().equals(PlanningAlgorithm.INVALID)) { return; } BasePlanningAlgorithm planner = getPlanningAlgorithm(Parameters.getPlanningAlgorithm()); planner.setTaskList(getTaskList()); planner.setVmList(getWorkflowEngine().getAllVmList()); try { planner.run(); } catch (Exception e) { Log.printLine("Error in configuring scheduler_method"); e.printStackTrace(); } } /** * Switch between multiple planners. Based on planner.method * * @param name the SCHMethod name * @return the scheduler that extends BaseScheduler */ private BasePlanningAlgorithm getPlanningAlgorithm(PlanningAlgorithm name) { BasePlanningAlgorithm planner; // choose which scheduler to use. Make sure you have add related enum in //Parameters.java switch (name) { //by default it is FCFS_SCH case INVALID: planner = null; break; case RANDOM: planner = new RandomPlanningAlgorithm(); break; case HEFT: planner = new HEFTPlanningAlgorithm(); break; case DHEFT: planner = new DHEFTPlanningAlgorithm(); break; default: planner = null; break; } return planner; } /** * Add impact factor for each task. This is useful in task balanced * clustering algorithm It is for research purpose and thus it is optional. * * @param taskList all the tasks */ private void processImpactFactors(List<Task> taskList) { List<Task> exits = new ArrayList<>(); for (Task task : taskList) { if (task.getChildList().isEmpty()) { exits.add(task); } } double avg = 1.0 / exits.size(); for (Task task : exits) { addImpact(task, avg); } } /** * Add impact factor for one particular task * * @param task, the task * @param impact , the impact factor */ private void addImpact(Task task, double impact) { task.setImpact(task.getImpact() + impact); int size = task.getParentList().size(); if (size > 0) { double avg = impact / size; for (Task parent : task.getParentList()) { addImpact(parent, avg); } } } /** * Overrides this method when making a new and different type of Broker. * This method is called by {@link #body()} for incoming unknown tags. * * @param ev a SimEvent object * @pre ev != null * @post $none */ protected void processOtherEvent(SimEvent ev) { if (ev == null) { Log.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null."); return; } Log.printLine(getName() + ".processOtherEvent(): " + "Error - event unknown by this DatacenterBroker."); } /** * Send an internal event communicating the end of the simulation. * * @pre $none * @post $none */ protected void finishExecution() { //sendNow(getId(), CloudSimTags.END_OF_SIMULATION); } /* * (non-Javadoc) * @see cloudsim.core.SimEntity#shutdownEntity() */ @Override public void shutdownEntity() { Log.printLine(getName() + " is shutting down..."); } /* * (non-Javadoc) * @see cloudsim.core.SimEntity#startEntity() */ @Override public void startEntity() { Log.printLine("Starting WorkflowSim " + Parameters.getVersion()); Log.printLine(getName() + " is starting..."); schedule(getId(), 0, WorkflowSimTags.START_SIMULATION); } /** * Gets the task list. * * @return the task list */ @SuppressWarnings("unchecked") public List<Task> getTaskList() { return (List<Task>) taskList; } /** * Sets the task list. * * @param taskList */ protected void setTaskList(List<Task> taskList) { this.taskList = taskList; } }