CharafeddineMechalikh/PureEdgeSim

View on GitHub
PureEdgeSim/com/mechalikh/pureedgesim/taskorchestrator/Orchestrator.java

Summary

Maintainability
A
1 hr
Test Coverage
/**
 *     PureEdgeSim:  A Simulation Framework for Performance Evaluation of Cloud, Edge and Mist Computing Environments 
 *
 *     This file is part of PureEdgeSim Project.
 *
 *     PureEdgeSim is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     PureEdgeSim is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with PureEdgeSim. If not, see <http://www.gnu.org/licenses/>.
 *     
 *     @author Charaf Eddine Mechalikh
 **/
package com.mechalikh.pureedgesim.taskorchestrator;
import java.util.List;
import com.mechalikh.pureedgesim.datacentersmanager.ComputingNode;
import com.mechalikh.pureedgesim.datacentersmanager.ComputingNode.LinkOrientation;
import com.mechalikh.pureedgesim.scenariomanager.SimulationParameters;
import com.mechalikh.pureedgesim.simulationengine.SimEntity;
import com.mechalikh.pureedgesim.simulationmanager.SimLog;
import com.mechalikh.pureedgesim.simulationmanager.SimulationManager;
import com.mechalikh.pureedgesim.taskgenerator.Task;

public abstract class Orchestrator extends SimEntity {
    protected List<ComputingNode> nodeList;
    protected SimulationManager simulationManager;
    protected SimLog simLog;
    protected String algorithmName;
    protected String architectureName;
    protected String[] architectureLayers;

    protected Orchestrator(SimulationManager simulationManager) {
        super(simulationManager.getSimulation());
        this.simulationManager = simulationManager;
        simulationManager.setOrchestrator(this);
        simLog = simulationManager.getSimulationLogger();
        algorithmName = simulationManager.getScenario().getStringOrchAlgorithm();
        architectureName = simulationManager.getScenario().getStringOrchArchitecture();
        initialize();
    }

    // Find an offloading location for this task
    public void orchestrate(Task task) {
        assignTaskToComputingNode(task, architectureLayers);
    }
    public void initialize() {
        if ("CLOUD_ONLY".equals(architectureName)) {
            cloudOnly();
        } else if ("MIST_ONLY".equals(architectureName)) {
            mistOnly();
        } else if ("EDGE_AND_CLOUD".equals(architectureName)) {
            edgeAndCloud();
        } else if ("ALL".equals(architectureName)) {
            all();
        } else if ("EDGE_ONLY".equals(architectureName)) {
            edgeOnly();
        } else if ("MIST_AND_CLOUD".equals(architectureName)) {
            mistAndCloud();
        } else if ("MIST_AND_EDGE".equals(architectureName)) {
            mistAndEdge();
        }
    }

    // If the orchestration scenario is MIST_ONLY send Tasks only to edge devices
    protected void mistOnly() {
        architectureLayers = new String[]{ "Mist" };
        nodeList = simulationManager.getDataCentersManager().getComputingNodesGenerator()
                .getMistOnlyListSensorsExcluded();
        
    }

    // If the orchestration scenario is ClOUD_ONLY send Tasks (cloudlets) only to
    // cloud virtual machines (vms)
    protected void cloudOnly() {
        architectureLayers = new String[] { "Cloud" };
        nodeList = simulationManager.getDataCentersManager().getComputingNodesGenerator()
                .getCloudOnlyList();
    }

    // If the orchestration scenario is EDGE_AND_CLOUD send Tasks only to edge data
    // centers or cloud virtual machines (vms)
    protected void edgeAndCloud() {
        architectureLayers = new String[]{ "Cloud", "Edge" };
        nodeList = simulationManager.getDataCentersManager().getComputingNodesGenerator()
                .getEdgeAndCloudList();
    }

    // If the orchestration scenario is MIST_AND_CLOUD send Tasks only to edge
    // devices or cloud virtual machines (vms)
    protected void mistAndCloud() {
        architectureLayers = new String[] { "Cloud", "Mist" };
        nodeList = simulationManager.getDataCentersManager().getComputingNodesGenerator()
                .getMistAndCloudListSensorsExcluded();
    }

    // If the orchestration scenario is EDGE_ONLY send Tasks only to edge data
    // centers
    protected void edgeOnly() {
        architectureLayers = new String[]{ "Edge" };
        nodeList = simulationManager.getDataCentersManager().getComputingNodesGenerator()
                .getEdgeOnlyList();
    }

    // If the orchestration scenario is MIST_AND_Edge send Tasks only to edge
    // devices or Fog virtual machines (vms)
    protected void mistAndEdge() {
        architectureLayers = new String[] { "Mist", "Edge" };
        nodeList = simulationManager.getDataCentersManager().getComputingNodesGenerator()
                .getMistAndEdgeListSensorsExcluded();
    }

    // If the orchestration scenario is ALL send Tasks to any virtual machine (vm)
    // or device
    protected void all() {
        architectureLayers = new String[]{ "Cloud", "Edge", "Mist" };
        nodeList = simulationManager.getDataCentersManager().getComputingNodesGenerator()
                .getAllNodesListSensorsExcluded();
    }

    protected abstract int findComputingNode(String[] architectureLayers, Task task);

    protected void assignTaskToComputingNode(Task task, String[] architectureLayers) {

        int nodeIndex = findComputingNode(architectureLayers, task);

        if (nodeIndex != -1) {
            ComputingNode node = nodeList.get(nodeIndex);
            try {
                checkComputingNode(node);
            } catch (Exception e) {
                e.printStackTrace();
            }

            // Send this task to this computing node
            task.setOffloadingDestination(node);

            // Application has been deployed
            task.getEdgeDevice().setApplicationPlacementLocation(node);
            simLog.deepLog(simulationManager.getSimulation().clock() + ": " + this.getClass() + " Task: " + task.getId()
                    + " assigned to " + node.getType() + " Computing Node: " + node.getId());

        }
    }

    protected void checkComputingNode(ComputingNode computingNode) {
        if (computingNode.isSensor())
            throw new IllegalArgumentException(
                    getClass().getSimpleName() + " - The forbidden happened! The orchestration algorithm \"" + algorithmName
                            + "\" has selected a sensor as an offloading destination. Kindly check it.");
    }

    protected boolean sameLocation(ComputingNode device1, ComputingNode device2, int RANGE) {
        if (device2.getType() == SimulationParameters.TYPES.CLOUD)
            return true;
        double distance = device1.getMobilityModel().distanceTo(device2);
        return (distance <= RANGE);
    }

    protected boolean arrayContains(String[] architectureLayers, String value) {
        for (String s : architectureLayers) {
            if (s.equals(value))
                return true;
        }
        return false;
    }

    protected boolean offloadingIsPossible(Task task, ComputingNode node, String[] architectureLayers) {
        SimulationParameters.TYPES nodeType = node.getType();
        return ((arrayContains(architectureLayers, "Cloud") && nodeType == SimulationParameters.TYPES.CLOUD) // cloud
                                                                                                        // computing
                || (arrayContains(architectureLayers, "Edge") && nodeType == SimulationParameters.TYPES.EDGE_DATACENTER // Edge
                                                                                                                    // computing
                // Compare destination (edge data server) and origin (edge device)
                // locations, if they are in same area offload to this edge data server
                        && (node == task.getEdgeDevice().getCurrentLink(LinkOrientation.UP_LINK).getDst()
                                // or compare the location of the orchestrator
                                || (node == task.getOrchestrator().getCurrentLink(LinkOrientation.UP_LINK).getDst())))

                || (arrayContains(architectureLayers, "Mist") && nodeType == SimulationParameters.TYPES.EDGE_DEVICE // Mist
                                                                                                                // computing
                // compare destination (edge device) location and origin (edge device) location,
                // if they are in same area offload to this device
                        && (sameLocation(node, task.getEdgeDevice(), SimulationParameters.edgeDevicesRange)
                                // or compare the location of their orchestrators
                                || (SimulationParameters.enableOrchestrators && sameLocation(node,
                                        task.getOrchestrator(), SimulationParameters.edgeDevicesRange)))
                        && !node.isDead() && !node.isSensor()));
    }

    public abstract void resultsReturned(Task task);

}