/** * This file is part of Path Computation Element Emulator (PCEE). * * PCEE 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. * * PCEE 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 PCEE. If not, see <http://www.gnu.org/licenses/>. */ package com.pcee.architecture.computationmodule.threadpool; import java.util.ArrayList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.graph.elements.vertex.VertexElement; import com.graph.graphcontroller.Gcontroller; import com.graph.path.PathElement; import com.graph.path.algorithms.PathComputationAlgorithm; import com.graph.path.algorithms.constraints.Constraint; import com.graph.path.algorithms.constraints.impl.SimplePathComputationConstraint; import com.graph.path.algorithms.impl.MaxBandwidthShortestPathComputationAlgorithm; import com.graph.path.algorithms.impl.SimplePathComputationAlgorithm; import com.pcee.architecture.ModuleEnum; import com.pcee.architecture.ModuleManagement; import com.pcee.protocol.message.PCEPMessage; import com.pcee.protocol.message.PCEPMessageFactory; import com.pcee.protocol.message.objectframe.PCEPObjectFrameFactory; import com.pcee.protocol.message.objectframe.impl.PCEPBandwidthObject; import com.pcee.protocol.message.objectframe.impl.PCEPExplicitRouteObject; import com.pcee.protocol.message.objectframe.impl.PCEPNoPathObject; import com.pcee.protocol.message.objectframe.impl.PCEPRequestParametersObject; import com.pcee.protocol.message.objectframe.impl.erosubobjects.EROSubobjects; import com.pcee.protocol.message.objectframe.impl.erosubobjects.PCEPAddress; import com.pcee.protocol.request.PCEPRequestFrame; import com.pcee.protocol.request.PCEPRequestFrameFactory; import com.pcee.protocol.response.PCEPResponseFrame; import com.pcee.protocol.response.PCEPResponseFrameFactory; /** * Runnable class used by the thread pool to process path computation requests * * @author Mohit Chamania * @author Marek Drogon */ public class WorkerTask implements Runnable { private Logger logger = LoggerFactory.getLogger("WorkerTask"); // Request to be processed private PCEPMessage request; // Graph used for computation of the request private Gcontroller graph; // Module management object to send the response to the session layer private ModuleManagement lm; /** Default Constructor */ public WorkerTask(ModuleManagement layerManagement, PCEPMessage request, Gcontroller graph) { lm = layerManagement; this.request = request; this.graph = graph; } /** Function to update the graph instance used for computation */ public void updateGraph(Gcontroller newGraph) { this.graph = newGraph; } /** Function to implement the path computation operations */ public void run() { PCEPRequestFrame requestFrame = PCEPRequestFrameFactory.getPathComputationRequestFrame(request); logger.info("Starting Processing of Request: " + requestFrame.getRequestID()); processSingleDomainRequest(requestFrame); logger.info("Completed Processing of Request: " + requestFrame.getRequestID()); } private void processSingleDomainRequest(PCEPRequestFrame requestFrame) { //Check if source and destination domain are available in the graph, if not send a no path object String sourceID = requestFrame.getSourceAddress().getIPv4Address(false).trim(); String destID = requestFrame.getDestinationAddress().getIPv4Address(false).trim(); if (graph.vertexExists(sourceID) && graph.vertexExists(destID)) { //begin path computation //Check if bandwidth objecy exists in the request frame Constraint constr = null; PathComputationAlgorithm algo = null; if (requestFrame.containsBandwidthObject()) { logger.info("Request Contains bandwidth Object"); constr = new SimplePathComputationConstraint (graph.getVertex(sourceID), graph.getVertex(destID), requestFrame.extractBandwidthObject().getBandwidthFloatValue()); algo = new MaxBandwidthShortestPathComputationAlgorithm(); } else { constr = new SimplePathComputationConstraint (graph.getVertex(sourceID), graph.getVertex(destID)); algo = new SimplePathComputationAlgorithm(); } //Start Path Computation PathElement element = algo.computePath(graph, constr); if (element !=null) { logger.info("Computed path is " + element.getVertexSequence()); // return response ArrayList<EROSubobjects> vertexList = getTraversedVertexes(element.getTraversedVertices()); //Generate ERO Object PCEPExplicitRouteObject ERO = PCEPObjectFrameFactory.generatePCEPExplicitRouteObject("1", "0", vertexList); //atleast one path was computed PCEPRequestParametersObject RP = PCEPObjectFrameFactory.generatePCEPRequestParametersObject("1", "0", "0", "0", "0", "1", Integer.toString(requestFrame.getRequestID())); PCEPResponseFrame respFrame = PCEPResponseFrameFactory.generatePathComputationResponseFrame(RP); respFrame.insertExplicitRouteObject(ERO); if (requestFrame.containsBandwidthObject()) { PCEPBandwidthObject bw = PCEPObjectFrameFactory.generatePCEPBandwidthObject("1", "0", (float) element.getPathParams().getAvailableCapacity()); respFrame.insertBandwidthObject(bw); } PCEPMessage mesg = PCEPMessageFactory.generateMessage(respFrame); mesg.setAddress(request.getAddress()); logger.info("Path found in the domain. Sending back to client"); // Send response message from the computation layer to the session layer lm.getComputationModule().sendMessage(mesg, ModuleEnum.SESSION_MODULE); } else { //No path Found in the source domain return no path Object returnNoPathMessage(requestFrame.getRequestID()); } } else { //Source and/or destination not present in the PCE if (graph.vertexExists(sourceID)) logger.info("Destination IP address " + destID + " not in the topology. Returning a no path object"); else if (graph.vertexExists(destID)) logger.info("Source IP address " + sourceID + " not in the topology. Returning a no path object"); else { logger.info("Both source IP address " + sourceID + " and destination IP address " + destID + " not in the topology. Returning a no path object"); } returnNoPathMessage(requestFrame.getRequestID()); } } /**Function to return the no Path message to the Client*/ protected void returnNoPathMessage(int requestID) { //Generate a No path object PCEPRequestParametersObject RP = PCEPObjectFrameFactory.generatePCEPRequestParametersObject("1", "0", "0", "0", "0", "1", Integer.toString(requestID)); PCEPNoPathObject noPath = PCEPObjectFrameFactory.generatePCEPNoPathObject("1", "0", 1, "0"); PCEPResponseFrame responseFrame = PCEPResponseFrameFactory.generatePathComputationResponseFrame(RP); responseFrame.insertNoPathObject(noPath); PCEPMessage mesg = PCEPMessageFactory.generateMessage(responseFrame); mesg.setAddress(request.getAddress()); lm.getComputationModule().sendMessage(mesg, ModuleEnum.SESSION_MODULE); } /** * Function to get the list of traversed vertices as PCEP addresses from the List of vertices in the graph. Used to create ERO * * @param resp * @return */ protected ArrayList<EROSubobjects> getTraversedVertexes(ArrayList<VertexElement> vertexArrayList) { ArrayList<EROSubobjects> traversedVertexesList = new ArrayList<EROSubobjects>(); for (int i=0;i<vertexArrayList.size();i++) { traversedVertexesList.add(new PCEPAddress(vertexArrayList.get(i).getVertexID(), false)); } return traversedVertexesList; } }