package es.tid.pce.parentPCE; import es.tid.pce.computingEngine.ComputingResponse; import es.tid.pce.computingEngine.algorithms.ChildPCEInitiate; import es.tid.pce.computingEngine.algorithms.ChildPCERequest; import es.tid.pce.pcep.PCEPProtocolViolationException; import es.tid.pce.pcep.constructs.StateReport; import es.tid.pce.pcep.messages.PCEPInitiate; import es.tid.pce.pcep.messages.PCEPMessage; import es.tid.pce.pcep.messages.PCEPRequest; import es.tid.pce.pcep.messages.PCEPResponse; import java.io.DataOutputStream; import java.io.IOException; import java.net.Inet4Address; import java.util.Hashtable; import java.util.LinkedList; import java.util.concurrent.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Manages the requests to the Child PCEs * Child PCE Session must register using the registerDomainSession method * The Parent PCE when asking a PCE must call the method newRequest * @author ogondio * */ public class ChildPCERequestManager { /** * Relates Child PCEs with its domain with */ //private Hashtable<String,ClientRequestManager> domain_pce; /** * Relates domain_id with the output stream of the Child PCEs */ private Hashtable<Inet4Address,DataOutputStream> domainIdOutputStream; private Hashtable<Inet4Address,Inet4Address> domainIdpceId; public Hashtable<Long,Object> locks; public Hashtable<Long,Object> inilocks; private Hashtable<Long,PCEPMessage> responses; private Hashtable<Long,StateReport> reports; private ThreadPoolExecutor executor; private LinkedBlockingQueue<Runnable> workQueue; //private BlockingQueue<ChildPCERequest> workQueue; private Logger log; private Logger logGUI; public ChildPCERequestManager(){ locks = new Hashtable<Long, Object>(); inilocks = new Hashtable<Long, Object>(); responses=new Hashtable<Long, PCEPMessage>(); domainIdOutputStream=new Hashtable<Inet4Address,DataOutputStream>(); domainIdpceId=new Hashtable<Inet4Address,Inet4Address>(); reports = new Hashtable<Long,StateReport>(); int corePoolSize=5; int maximumPoolSize=10; long keepAliveTime=120; workQueue=new LinkedBlockingQueue<Runnable>(); executor= new ThreadPoolExecutor(corePoolSize, maximumPoolSize,keepAliveTime, TimeUnit.SECONDS,workQueue); log = LoggerFactory.getLogger("PCEServer"); logGUI=LoggerFactory.getLogger("GUILogger"); } public LinkedList<ComputingResponse> executeRequests(LinkedList<PCEPRequest> requestList, LinkedList<Object> domainList){ LinkedList<ComputingResponse> response= new LinkedList<ComputingResponse>(); ChildPCERequest cpr; LinkedList<FutureTask<ComputingResponse>> ftList=new LinkedList<FutureTask<ComputingResponse>>(); FutureTask<ComputingResponse> ft; for (int i=0;i<requestList.size();++i){ cpr=new ChildPCERequest(this, requestList.get(i), domainList.get(i)); ft=new FutureTask<ComputingResponse>(cpr); ftList.add(ft); executor.execute(ft); } long time=120000; log.debug("The time is "+time+" miliseconds"); long timeIni=System.currentTimeMillis(); long time2; ComputingResponse resp; for (int i=0;i<requestList.size();++i){ try { log.debug("Waiting "+time+" miliseconds for domain "+domainList.get(i)); resp=ftList.get(i).get(time, TimeUnit.MILLISECONDS); time2=System.currentTimeMillis(); long timePassed=time2-timeIni; if (timePassed>=120000){ time=0; } else { time=time-timePassed; } response.add(resp); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (ExecutionException e) { // // TODO Auto-generated catch block // e.printStackTrace(); } catch (TimeoutException e) { resp=null; time2=System.currentTimeMillis(); time=time-time2-timeIni; // TODO Auto-generated catch block e.printStackTrace(); // } } catch (Exception e){ return null; //FIXME: REPARAR PARA MANDAR MAS!!!! } } return response; } public LinkedList<ComputingResponse> executeInitiates(LinkedList<PCEPInitiate> initiateList, LinkedList<Object> domainList){ LinkedList<ComputingResponse> response= new LinkedList<ComputingResponse>(); ChildPCEInitiate cpr; LinkedList<FutureTask<ComputingResponse>> ftList=new LinkedList<FutureTask<ComputingResponse>>(); FutureTask<ComputingResponse> ft; for (int i=0;i<initiateList.size();++i){ cpr=new ChildPCEInitiate(this, initiateList.get(i), domainList.get(i)); ft=new FutureTask<ComputingResponse>(cpr); ftList.add(ft); executor.execute(ft); } long time=120000; //log.info("The time is "+time+" miliseconds"); long timeIni=System.currentTimeMillis(); long time2; ComputingResponse resp; for (int i=0;i<initiateList.size();++i){ try { log.info("Waiting "+time+" miliseconds for initiating in domain "+domainList.get(i)); resp=ftList.get(i).get(time, TimeUnit.MILLISECONDS); time2=System.currentTimeMillis(); long timePassed=time2-timeIni; if (timePassed>=120000){ time=0; } else { time=time-timePassed; } response.add(resp); } catch (TimeoutException e) { resp=null; time2=System.currentTimeMillis(); time=time-time2-timeIni; // TODO Auto-generated catch block e.printStackTrace(); // } } catch (Exception e){ return null; //FIXME: REPARAR PARA MANDAR MAS!!!! } } return response; } // public void addRequest(PCEPRequest pcreq, Inet4Address domain){ // ChildPCERequest cpr=new ChildPCERequest(this, pcreq, domain); // FutureTask<PCEPResponse> ft=new FutureTask<PCEPResponse>(cpr); // //workQueue.add((Runnable)cpr); // log.info("Vamos a ejecutar"); // executor.execute(ft); // log.info("Salimos de ejecutar"); // } public void notifyResponse(PCEPResponse pcres){ long idRequest=pcres.getResponse(0).getRequestParameters().getRequestID(); log.debug("Entrando en Notify Response de idRequest "+idRequest); Object object_lock=locks.get(new Long(idRequest)); responses.put(new Long(idRequest), pcres); if (object_lock!=null){ object_lock.notifyAll(); } locks.remove(object_lock); } public void notifyReport(StateReport sr){ long idRequest=sr.getSRP().getSRP_ID_number(); log.debug("Entrando en Notify Report de id "+idRequest); Object object_lock=inilocks.get(new Long(idRequest)); reports.put(new Long(idRequest), sr); if (object_lock!=null){ object_lock.notifyAll(); } inilocks.remove(object_lock); } public PCEPResponse newRequest( PCEPRequest pcreq, Object domain){ log.info("New Request to Child PCE"); Object object_lock=new Object(); // RequestLock rl=new RequestLock(); //((RequestParameters)(((Request)pcreq.getRequest(0)).getReqObject(0))).getRequestID(); //long idRequest=((RequestParameters)(((Request)pcreq.getRequest(0)).getReqObject(0))).getRequestID(); long idRequest=pcreq.getRequest(0).getRequestParameters().getRequestID(); log.debug("Creo lock con idRequest "+idRequest); locks.put(new Long(idRequest), object_lock); try { if (pcreq.getPccReqId()!=null){ if (pcreq.getMonitoring()!=null){ logGUI.info(domainIdpceId.get(domain).getHostAddress()+"&file="+pcreq.getPccReqId().getPCCIpAddress().getHostAddress()+":"+pcreq.getMonitoring().getMonitoringIdNumber()); } } sendRequest(pcreq,domain); } catch (IOException e1) { locks.remove(object_lock); return null; } synchronized (object_lock) { try { log.debug("Request sent, waiting for response"); object_lock.wait(30000); } catch (InterruptedException e){ // FIXME: Ver que hacer } } log.debug("Request or timeout"); PCEPResponse resp=(PCEPResponse)responses.get(new Long(idRequest)); if (resp==null){ log.warn("NO RESPONSE!!!!!"); } return resp; } public StateReport newIni( PCEPInitiate pcini, Object domain){ Object object_lock=new Object(); long idSRP=pcini.getPcepIntiatedLSPList().get(0).getRsp().getSRP_ID_number(); log.info("Sending PCEPInitiate to domain "+domain+" srp_id "+idSRP+" : "+pcini.toString()); inilocks.put(new Long(idSRP), object_lock); try { sendInitiate(pcini,domain); } catch (IOException e1) { log.warn("Problem with response from domain "+domain+" to initiate with srp_id "+idSRP); inilocks.remove(object_lock); return null; } synchronized (object_lock) { try { log.debug("Request sent, waiting for response"); object_lock.wait(30000); } catch (InterruptedException e){ // FIXME: Ver que hacer } } StateReport resp=reports.get(new Long(idSRP)); if (resp==null){ log.warn("No response from domain "+domain+" to initiate with srp_id "+idSRP); }else { log.info("Domain "+domain+" replied to Initiate with srp_id "+idSRP+" : "+resp.toString()); } return resp; } synchronized public void sendRequest(PCEPRequest req, Object domain) throws IOException{ try { req.encode(); } catch (PCEPProtocolViolationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } DataOutputStream out= domainIdOutputStream.get(domain); if (out==null){ log.warn("There is no PCE for domain "+domain); throw new IOException(); } try { log.info("Sending Request message to domain "+domain); out.write(req.getBytes()); out.flush(); } catch (IOException e) { log.warn("Error sending REQ: " + e.getMessage()); throw e; } } synchronized public void sendInitiate(PCEPInitiate ini, Object domain) throws IOException{ try { ini.encode(); } catch (PCEPProtocolViolationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } DataOutputStream out= domainIdOutputStream.get(domain); if (out==null){ log.warn("There is no PCE for domain "+domain); throw new IOException(); } try { log.info("Sending Initiate message to domain "+domain); out.write(ini.getBytes()); out.flush(); } catch (IOException e) { log.warn("Error sending REQ: " + e.getMessage()); throw e; } } void registerDomainSession(Inet4Address domain, Inet4Address pceId, DataOutputStream out){ if (domain!=null){ log.info("domain "+domain+ "pceId "+pceId); if (domainIdOutputStream.containsKey(domain)){ domainIdOutputStream.remove(domain); } domainIdOutputStream.put(domain, out); if (domainIdpceId.containsKey(domain)){ domainIdpceId.remove(domain); } domainIdpceId.put(domain, pceId); } else { log.warn("domain is null, PCE not registered as child"); } } void removeDomain(Inet4Address domain){ if (domain!=null){ domainIdOutputStream.remove(domain); domainIdpceId.remove(domain); } } public Hashtable<Inet4Address, DataOutputStream> getDomainIdOutputStream() { return domainIdOutputStream; } public Hashtable<Inet4Address, Inet4Address> getDomainIdpceId() { return domainIdpceId; } }