package es.tid.pce.computingEngine.algorithms.sson; import java.net.Inet4Address; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.jgrapht.GraphPath; import org.jgrapht.graph.SimpleDirectedWeightedGraph; import es.tid.ospf.ospfv2.lsa.tlv.subtlv.complexFields.BitmapLabelSet; import es.tid.pce.computingEngine.ComputingRequest; import es.tid.pce.computingEngine.ComputingResponse; import es.tid.pce.computingEngine.algorithms.AlgorithmReservation; import es.tid.pce.computingEngine.algorithms.ComputingAlgorithm; import es.tid.pce.computingEngine.algorithms.PCEPUtils; import es.tid.pce.computingEngine.algorithms.utilities.bandwidthToSlotConversion; import es.tid.pce.computingEngine.algorithms.utilities.channel_generator; import es.tid.pce.pcep.constructs.EndPoint; import es.tid.pce.pcep.constructs.EndPointAndRestrictions; import es.tid.pce.pcep.constructs.GeneralizedBandwidthSSON; import es.tid.pce.pcep.constructs.P2MPEndpoints; import es.tid.pce.pcep.constructs.P2PEndpoints; import es.tid.pce.pcep.constructs.Path; import es.tid.pce.pcep.constructs.Request; import es.tid.pce.pcep.constructs.Response; import es.tid.pce.pcep.objects.BandwidthRequested; import es.tid.pce.pcep.objects.BandwidthRequestedGeneralizedBandwidth; import es.tid.pce.pcep.objects.EndPoints; import es.tid.pce.pcep.objects.EndPointsIPv4; import es.tid.pce.pcep.objects.ExplicitRouteObject; import es.tid.pce.pcep.objects.GeneralizedEndPoints; import es.tid.pce.pcep.objects.Metric; import es.tid.pce.pcep.objects.Monitoring; import es.tid.pce.pcep.objects.NoPath; import es.tid.pce.pcep.objects.ObjectParameters; import es.tid.pce.pcep.objects.RequestParameters; import es.tid.pce.pcep.objects.tlvs.NoPathTLV; import es.tid.pce.server.wson.ReservationManager; import es.tid.rsvp.RSVPProtocolViolationException; import es.tid.rsvp.constructs.gmpls.DWDMWavelengthLabel; import es.tid.rsvp.objects.subobjects.GeneralizedLabelEROSubobject; import es.tid.rsvp.objects.subobjects.IPv4prefixEROSubobject; import es.tid.rsvp.objects.subobjects.UnnumberIfIDEROSubobject; import es.tid.tedb.DomainTEDB; import es.tid.tedb.IntraDomainEdge; import es.tid.tedb.SSONInformation; import es.tid.tedb.TEDB; import es.tid.util.UtilsFunctions; /** * Implementation of the algorithm "Dynamic Routing and Spectrum Allocation". * * <p>Reference: A. Castro et al., Dynamic routing and spectrum (re)allocation in future flexgrid optical networks, Comput. Netw. (2012), http://dx.doi.org/10.1016/j.comnet.2012.05.001 </p> * @author Arturo mayoral * */ public class Dynamic_RSA implements ComputingAlgorithm { /** * The Logger. */ private Logger log=LoggerFactory.getLogger("PCEServer"); /** * The Path Computing Request to calculate. */ private ComputingRequest pathReq; /** * Access to the Precomputation part of the algorithm. */ private Dynamic_RSAPreComputation preComp; private SimpleDirectedWeightedGraph<Object,IntraDomainEdge> networkGraph; /** * Access to the Reservation Manager to make reservations of Wavalengths/labels. */ private ReservationManager reservationManager; private SSONInformation SSONInfo; // /** // * Number of wavelenghts (labels). // */ //private int num_lambdas; private channel_generator genChannels; private ArrayList<BitmapLabelSet> setChannels; /** * The traffic engineering database */ private DomainTEDB ted; /** * Required number of consecutive frequency slots */ private int num_slots = 0; private GenericLambdaReservation reserv; public Dynamic_RSA(ComputingRequest pathReq,TEDB ted, ReservationManager reservationManager, int mf ){ //this.num_lambdas=((DomainTEDB)ted).getWSONinfo().getNumLambdas(); this.pathReq=pathReq; this.reservationManager=reservationManager; this.ted=(DomainTEDB)ted; } public ComputingResponse call(){ //Timestamp of the start of the algorithm; long tiempoini =System.nanoTime(); log.info("Starting DynamicRSA Algorithm"); //Create the response message //It will contain either the path or noPath ComputingResponse m_resp=new ComputingResponse(); m_resp.setEncodingType(pathReq.getEcodingType()); //The request that needs to be solved Request req=pathReq.getRequestList().get(0); //Request Id, needed for the response long reqId=req.getRequestParameters().getRequestID(); log.info("Request id: "+reqId+", getting endpoints"); //Start creating the response Response response=new Response(); RequestParameters rp = new RequestParameters(); rp.setRequestID(reqId); response.setRequestParameters(rp); m_resp.addResponse(response); SSONInfo= new SSONInformation(); SSONInfo=((DomainTEDB)ted).getSSONinfo(); //esto hay que cambiarlo para poder leer del GENERALIZED END POINTS //if (getObjectType(req.getEndPoints())) EndPoints EP= req.getEndPoints(); BandwidthRequested Bw= (BandwidthRequested)req.getBandwidth(); // Objeto bandwidth para saber la demanda de la peticion. Object source_router_id_addr = null; Object dest_router_id_addr = null; GraphPath<Object,IntraDomainEdge> gp_chosen=null; int cs; boolean end=false;//The search has not ended yet int num_labels=0; int m=0; int Bmod=0; // Spectrum efficiency b/s/Hz (Modulation formats: 16-QAM, QPSK) num_labels = SSONInfo.getNumLambdas(); log.info("Num_lambdas "+num_labels); bandwidthToSlotConversion conversion= new bandwidthToSlotConversion(); // Conversión Bw a numero de slots en función de la grid. if (Bw.getBw()!=0){ SSONInfo=((DomainTEDB)ted).getSSONinfo(); cs = SSONInfo.getCs(); num_slots=conversion.getNumSlots(Bw.getBw(), cs); } /* The set of request-channels will be bounded by the total number of frequency slots * less the number of contiguous frequency slot required for serve the demand plus one. */ log.info("Request num_slots: "+num_slots); setChannels = preComp.getTotalSetChannels().get(num_slots-1); if (EP.getOT()==ObjectParameters.PCEP_OBJECT_TYPE_ENDPOINTS_IPV4){ EndPointsIPv4 ep=(EndPointsIPv4) req.getEndPoints(); source_router_id_addr=ep.getSourceIP(); dest_router_id_addr=ep.getDestIP(); }else if (EP.getOT()==ObjectParameters.PCEP_OBJECT_TYPE_ENDPOINTS_IPV6){ }else if (EP.getOT()==ObjectParameters.PCEP_OBJECT_TYPE_GENERALIZED_ENDPOINTS){ GeneralizedEndPoints gep=(GeneralizedEndPoints) req.getEndPoints(); if(gep.getGeneralizedEndPointsType()==ObjectParameters.PCEP_GENERALIZED_END_POINTS_TYPE_P2P){ P2PEndpoints p2pep= gep.getP2PEndpoints(); EndPoint sourceep=p2pep.getSourceEndPoint(); EndPoint destep=p2pep.getDestinationEndPoint(); source_router_id_addr=sourceep.getEndPointIPv4TLV().IPv4address; dest_router_id_addr=destep.getEndPointIPv4TLV().IPv4address; } if(gep.getGeneralizedEndPointsType()==ObjectParameters.PCEP_GENERALIZED_END_POINTS_TYPE_P2MP_NEW_LEAVES){ P2MPEndpoints p2mpep= gep.getP2MPEndpoints(); EndPointAndRestrictions epandrest=p2mpep.getEndPointAndRestrictions(); EndPoint sourceep=epandrest.getEndPoint(); source_router_id_addr=sourceep.getEndPointIPv4TLV().IPv4address; int cont=0; while (cont<=p2mpep.getEndPointAndRestrictionsList().size()){ //esto est� mal epandrest=p2mpep.getEndPointAndRestrictionsList().get(cont); EndPoint destep=epandrest.getEndPoint(); source_router_id_addr=sourceep.getEndPointIPv4TLV().IPv4address; dest_router_id_addr=destep.getEndPointIPv4TLV().IPv4address; } } } //Now, check if the source and destination are in the TED. log.info("Source: "+source_router_id_addr+"; Destination:"+dest_router_id_addr); if (!(((ted.containsVertex(source_router_id_addr))&&(ted.containsVertex(dest_router_id_addr))))){ log.warn("Source or destination are NOT in the TED"); NoPath noPath= new NoPath(); noPath.setNatureOfIssue(ObjectParameters.NOPATH_NOPATH_SAT_CONSTRAINTS); NoPathTLV noPathTLV=new NoPathTLV(); if (!((ted.containsVertex(source_router_id_addr)))){ log.debug("Unknown source"); noPathTLV.setUnknownSource(true); } if (!((ted.containsVertex(dest_router_id_addr)))){ log.debug("Unknown destination"); noPathTLV.setUnknownDestination(true); } noPath.setNoPathTLV(noPathTLV); response.setNoPath(noPath); return m_resp; } // check if src and dst are the same if (source_router_id_addr.equals(dest_router_id_addr)){ log.info("Source and destination are the same!"); Path path=new Path(); ExplicitRouteObject ero= new ExplicitRouteObject(); IPv4prefixEROSubobject eroso= new IPv4prefixEROSubobject(); eroso.setIpv4address((Inet4Address)source_router_id_addr); eroso.setPrefix(32); ero.addEROSubobject(eroso); path.setEro(ero); if (req.getMetricList().size()!=0){ Metric metric=new Metric(); metric.setMetricType(req.getMetricList().get(0).getMetricType() ); log.debug("Number of hops "+0); float metricValue=0; metric.setMetricValue(metricValue); path.getMetricList().add(metric); } response.addPath(path); long tiempofin =System.nanoTime(); long tiempotot=tiempofin-tiempoini; log.info("Ha tardado "+tiempotot+" nanosegundos"); Monitoring monitoring=pathReq.getMonitoring(); if (monitoring!=null){ if (monitoring.isProcessingTimeBit()){ } } m_resp.addResponse(response); return m_resp; } boolean nopath=true;//Initially, we still have no path int central_freq=0; // It represents the central frequency slot n. double max_metric=Integer.MAX_VALUE; preComp.getGraphLock().lock(); try{ while (!end){ //SimpleDirectedWeightedGraph<Object,IntraDomainEdge> graphLambda=preComp.getNetworkGraphs().get(0); SimpleDirectedWeightedGraph<Object,IntraDomainEdge> graphLambda=preComp.getbaseSimplegraph(); //networkGraph=PCEPUtils.duplicateTEDDB(((SimpleTEDB)ted).getNetworkGraph()); // Set<IntraDomainEdge> fiberEdges= preComp.getNetworkGraphs().get(0).edgeSet(); // Iterator<IntraDomainEdge> Iterator = fiberEdges.iterator(); // while(Iterator.hasNext()){ // IntraDomainEdge fiberEdge =Iterator.next(); // FuncionesUtiles.printByte(((BitmapLabelSet)fiberEdge.getTE_info().getAvailableLabels().getLabelSet()).getBytesBitMap(), "Bitmap edge "+fiberEdge.toString()+".", log); // } log.info("Antes de DSP"+preComp.printTopology(0)); ModifiedDijkstraSP dsp=new ModifiedDijkstraSP(graphLambda, source_router_id_addr, dest_router_id_addr, Double.POSITIVE_INFINITY, setChannels, num_slots); log.info("Fin MDSP"); GraphPath<Object,IntraDomainEdge> gp=dsp.getPath(); if (gp==null){ log.debug("No path found"); NoPath noPath= new NoPath(); noPath.setNatureOfIssue(ObjectParameters.NOPATH_NOPATH_SAT_CONSTRAINTS); NoPathTLV noPathTLV=new NoPathTLV(); noPath.setNoPathTLV(noPathTLV); response.setNoPath(noPath); nopath=true; return m_resp; } else{ BitmapChannelState valid_channels = new BitmapChannelState(dsp.getVertexSpectrumState().get(dest_router_id_addr).getLength()); valid_channels.setBytesBitmap(dsp.getVertexSpectrumState().get(dest_router_id_addr).getBytesBitmap()); for (int i=0; i<valid_channels.getLength(); i++){ if ((valid_channels.getBytesBitmap()[i/8]&(0x80>>(i%8))) == (0x80>>i%8)){ BitmapLabelSet chosen_channel=setChannels.get(i); UtilsFunctions.printByte(chosen_channel.getBytesBitMap(),"Bitmap Channel "+i+">>", log); central_freq=i+(num_slots+1)/2; break; } } if (central_freq!=0){ gp_chosen=gp; max_metric=gp.getWeight(); m=(num_slots)/2; log.info("Central Frequency"+central_freq); log.info("Frequency width"+m); log.info("Path"+gp_chosen); nopath=false; end=true; }else{ throw new IllegalArgumentException("Invalid central frequency for this request"); } } } } finally{ preComp.getGraphLock().unlock(); } if (nopath==false){ Path path=new Path(); ExplicitRouteObject ero= new ExplicitRouteObject(); List<IntraDomainEdge> edge_list= gp_chosen.getEdgeList(); int i; for (i=0;i<edge_list.size();i++){ UnnumberIfIDEROSubobject eroso= new UnnumberIfIDEROSubobject(); eroso.setRouterID((Inet4Address)edge_list.get(i).getSource()); eroso.setInterfaceID(edge_list.get(i).getSrc_if_id()); eroso.setLoosehop(false); ero.addEROSubobject(eroso); //FIXME: Temp, only for HPCE algorithms preComp.setReservation(m, (central_freq)+preComp.getWSONInfo().getnMin(), edge_list.get(i).getSource(), edge_list.get(i).getTarget()); //ITU-T Format DWDMWavelengthLabel WDMlabel=new DWDMWavelengthLabel(); WDMlabel.setGrid(preComp.getWSONInfo().getGrid()); WDMlabel.setChannelSpacing(preComp.getWSONInfo().getCs()); WDMlabel.setN((central_freq)+preComp.getWSONInfo().getnMin()); WDMlabel.setIdentifier(0); WDMlabel.setM(m); try { WDMlabel.encode(); } catch (RSVPProtocolViolationException e) { // TODO Auto-generated catch block e.printStackTrace(); } GeneralizedLabelEROSubobject genLabel= new GeneralizedLabelEROSubobject(); ero.addEROSubobject(genLabel); genLabel.setLabel(WDMlabel.getBytes()); } //log.info("Label bit map: "+ted.getWSONinfo().getCommonAvailableLabels().getLabelSet().toString()); BandwidthRequestedGeneralizedBandwidth gb = new BandwidthRequestedGeneralizedBandwidth (); preComp.setTotalBandwidth((m*2*6.25)+preComp.getTotalBandwidth()); GeneralizedBandwidthSSON GB_SSON = new GeneralizedBandwidthSSON(); GB_SSON.setM(m); gb.setGeneralizedBandwidth(GB_SSON); IPv4prefixEROSubobject eroso= new IPv4prefixEROSubobject(); eroso.setIpv4address((Inet4Address)edge_list.get(edge_list.size()-1).getTarget()); eroso.setPrefix(32); ero.addEROSubobject(eroso); path.setEro(ero); path.setBandwidth(gb); PCEPUtils.completeMetric(path, req, edge_list); response.addPath(path); //FIXME: RESERVATION NEEDS TO BE IMPROVED!!! LinkedList<Object> sourceVertexList=new LinkedList<Object>(); LinkedList<Object> targetVertexList=new LinkedList<Object>(); for (i=0;i<edge_list.size();i++){ sourceVertexList.add(edge_list.get(i).getSource()); targetVertexList.add(edge_list.get(i).getTarget()); } sourceVertexList.add(edge_list.get(i-1).getSource()); targetVertexList.add(edge_list.get(i-1).getTarget()); if (req.getReservation()!=null){ reserv= new GenericLambdaReservation(); reserv.setResp(m_resp); reserv.setLambda_chosen(central_freq); reserv.setBidirectional(req.getRequestParameters().isBidirect()); reserv.setReservation(req.getReservation()); reserv.setSourceVertexList(sourceVertexList); reserv.setTargetVertexList(targetVertexList); //log.info("Bidirect = " +req.getRequestParameters().isBidirect()); reserv.setReservationManager(reservationManager); } } long tiempofin =System.nanoTime(); long tiempotot=tiempofin-tiempoini; log.info("Ha tardado "+tiempotot+" nanosegundos"); log.info("RESPONSE: "+m_resp.toString()); return m_resp; } public AlgorithmReservation getReserv() { return reserv; } public void setPreComp(Dynamic_RSAPreComputation preComp) { this.preComp = preComp; } public static String toHexString(byte [] packetBytes){ StringBuffer sb=new StringBuffer(packetBytes.length*2); for (int i=0; i<packetBytes.length;++i){ if ((packetBytes[i]&0xFF)<=0x0F){ sb.append('0'); sb.append(Integer.toHexString((packetBytes[i]&0xFF))); } else { sb.append(Integer.toHexString((packetBytes[i]&0xFF))); } } return sb.toString(); } }