package org.gcube.vremanagement.vremodeler.impl.deploy; import java.io.ByteArrayInputStream; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.gcube.common.core.faults.GCUBEFault; import org.gcube.common.core.resources.GCUBECollection; import org.gcube.common.core.resources.GCUBEGenericResource; import org.gcube.common.core.resources.GCUBEMCollection; import org.gcube.common.core.scope.GCUBEScope; import org.gcube.common.core.scope.GCUBEScope.MalformedScopeExpressionException; import org.gcube.common.core.utils.logging.GCUBELog; import org.gcube.common.resources.kxml.KGCUBEResource; import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.AddResourcesParameters; import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.CreateScopeParameters; import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.OptionsParameters; import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ResourceItem; import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ResourceList; import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ResourceManagerPortType; import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ScopeOption; import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ServiceItem; import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ServiceList; import org.gcube.vremanagement.vremodeler.db.DBInterface; import org.gcube.vremanagement.vremodeler.impl.ModelerContext; import org.gcube.vremanagement.vremodeler.impl.ModelerResource; import org.gcube.vremanagement.vremodeler.impl.ModelerService; import org.gcube.vremanagement.vremodeler.impl.util.ReportFiller; import org.gcube.vremanagement.vremodeler.impl.util.Util; import org.gcube.vremanagement.vremodeler.portallayout.CollectionResourceCreation; import org.gcube.vremanagement.vremodeler.portallayout.GenericResourcePortlet; import org.gcube.vremanagement.vremodeler.stubs.deployreport.DeployReport; import org.globus.wsrf.ResourceException; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class DeployVRE extends Thread{ private static GCUBELog logger= new GCUBELog(ModelerService.class); private ModelerResource wsResource= null; private String resourceId; private GCUBEScope startingScope; private String vreName=null; private CollectionResourceCreation collectionResourceCreation; public DeployVRE(String resourceId, GCUBEScope scope) throws GCUBEFault, Exception{ this.resourceId=resourceId; this.startingScope= scope; try{ ResultSet resGenericInfo = DBInterface.queryDB("select VRE.name from VRE where VRE.id='"+this.resourceId+"'; "); if (!resGenericInfo.next()) { throw new GCUBEFault("The VRE with ID "+this.resourceId+" cannot be retrieved on the DB"); } vreName= resGenericInfo.getString(1); System.out.println(vreName); }catch (Exception e) { logger.error("error retrieving the VRE Name",e); throw e; } } private ModelerResource getResource() throws ResourceException{ if (wsResource==null) wsResource= (ModelerResource)ModelerContext.getPortTypeContext().getWSHome().find(ModelerContext.getPortTypeContext().makeKey(resourceId)); return wsResource; } /** * */ public void run(){ try { getResource().setDeployReport(new DeployReport()); //reports initialization getResource().getDeployReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Running); getResource().store(); GHNstoUse ghnsToUse=null; if (getResource().isUseCloud()){ DeployGHNsOnCloud ghnOnCloud = new DeployGHNsOnCloud(getResource().getNumberOfVMsForCloud(), vreName); getResource().getDeployReport().setCloudDeployingReport(ghnOnCloud.getReport()); try{ ghnsToUse = ghnOnCloud.run(); }catch (Exception e) { logger.error("error creating VMs on cloud",e); getResource().getDeployReport().getCloudDeployingReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Failed); throw new Exception("error creating VMs on cloud",e); } }else { getResource().getDeployReport().getCloudDeployingReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Skipped); ResultSet resRelatedGHN=DBInterface.queryDB("select VRERELATEDGHN.ghnid, GHN.domain, VRERELATEDGHN.ISCANDIDATE from VRERELATEDGHN, GHN where GHN.id=VRERELATEDGHN.ghnid and VRERELATEDGHN.vreid='"+this.resourceId+"' ORDER BY GHN.host; "); ghnsToUse = new GHNstoUse(); while (resRelatedGHN.next()) { if(resRelatedGHN.getBoolean(3)){ ghnsToUse.setCandidateForRM(resRelatedGHN.getString(1)); }else ghnsToUse.getGhns().add(resRelatedGHN.getString(1)); } } if (deployManagerOnVRE(ghnsToUse.candidateForRM)){ getResource().getDeployReport().getResourceManagerDeployingReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Finished); if (createVRE(ghnsToUse.getGhns())){ DBInterface.ExecuteUpdate("UPDATE VRE SET STATUS='"+org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Finished+"' WHERE VRE.id='"+this.resourceId+"';"); getResource().getDeployReport().getFunctionalityDeployingReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Finished); getResource().getDeployReport().getResourceDeployingReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Finished); getResource().getDeployReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Finished); getResource().store(); logger.info("Deploying of the VRE with id "+this.resourceId+" FINISHED"); } else{ logger.info("Deploying of the VRE with id "+this.resourceId+" FAILED on second step"); getResource().getDeployReport().getResourceDeployingReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Failed); getResource().getDeployReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Failed); throw new Exception("Error Deployng the VRE failed on second step"); } }else{ getResource().getDeployReport().getResourceManagerDeployingReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Failed); logger.info("Deploying of the VRE with id "+this.resourceId+" FAILED on first step"); throw new Exception("Error Deployng the VRE filed on first step"); } }catch(Exception e){ try { DBInterface.ExecuteUpdate("UPDATE VRE SET STATUS='"+org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Failed+"' WHERE VRE.id='"+this.resourceId+"';"); getResource().getDeployReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Failed); getResource().store(); } catch (Exception e1) { logger.error("impossible to update the VRE Status",e1); } logger.error("Error deploying the VRE with id "+this.resourceId+" ",e); } } private boolean deployManagerOnVRE(String candidateGhnId) throws MalformedScopeExpressionException, Exception{ try { DBInterface.ExecuteUpdate("UPDATE VRE SET STATUS='Deploying' WHERE VRE.id='"+this.resourceId+"';"); } catch (Exception e) { logger.error("HSQLDB Error "+e); throw new GCUBEFault(e); } getResource().getDeployReport().getResourceManagerDeployingReport().setState(org.gcube.vremanagement.vremodeler.stubs.deployreport.State.Running); getResource().store(); ResourceManagerPortType rmPortType=Util.getResourceMangerPT(this.startingScope); String report; try{ AddResourcesParameters arp= new AddResourcesParameters(); ServiceList services= new ServiceList(); ServiceItem[] service= new ServiceItem[1]; service[0]=new ServiceItem(); service[0].setServiceClass("VREManagement"); service[0].setServiceName("ResourceManager"); service[0].setServiceVersion("1.00.00"); services.setService(service); services.setGHN(new String[]{candidateGhnId}); arp.setServices(services); arp.setTargetScope(this.startingScope+"/"+vreName); String reportId=rmPortType.addResources(arp); logger.trace("the report id for Rm is "+reportId); //waiting few seconds Thread.sleep(30000); int attempt=0; do{ Thread.sleep(20000); report=rmPortType.getReport(reportId); attempt++; getResource().getDeployReport().getResourceManagerDeployingReport().setResourceManagerReport(report); getResource().store(); }while (!isDeploymentStatusFinished(report) && attempt<20); }catch(Exception e){logger.error("error deploying RM on VRE",e); throw e;} logger.trace("report step 1: "+report); logger.info("is something failed in the first step?"+isSomethingFailed(report)); collectionResourceCreation= new CollectionResourceCreation(this.resourceId, this.vreName); return !isSomethingFailed(report); } @SuppressWarnings("static-access") private boolean createVRE(List ghnList) throws Exception{ //report initialization ReportFiller.initizlizeFunctionalityForReport(getResource().getDeployReport().getFunctionalityDeployingReport(),this.resourceId); ReportFiller.initializeResourcesForReport(getResource().getDeployReport().getResourceDeployingReport(), this.resourceId); ResourceManagerPortType rmPortType=Util.getResourceMangerPT(GCUBEScope.getScope(this.startingScope+"/"+this.vreName)); CreateScopeParameters scopeParameter=getScopeParameters(); //creating the GenericResources for Portlets and Collection GenericResourcePortlet.createResource(getResource().getId(), vreName); collectionResourceCreation.createAndPublish(); //waiting few seconds to be sure that generic resources will be published Thread.currentThread().sleep(120000); //Adding the resources to the new VRE AddResourcesParameters arp= new AddResourcesParameters(); ResourceList rl= new ResourceList(); List resItemList= new ArrayList(); //retrieving Collection try{ resItemList.addAll(addCollections()); }catch(SQLException sqle){logger.error("Error contacting HSQLDB "+sqle);} //adding the CollectionResource genericResource ResourceItem genResItem= new ResourceItem(); genResItem.setID(collectionResourceCreation.getCreatedResourceId()); genResItem.setType(GCUBEGenericResource.TYPE); resItemList.add(genResItem); //adding the other needed resources try{ resItemList.addAll(addGenericResources()); }catch(SQLException sqle){ logger.error("Error contacting HSQLDB "+sqle); } rl.setResource(resItemList.toArray(new ResourceItem[0])); arp.setResources(rl); //retrieve services ServiceList serviceList= new ServiceList(); try{ serviceList.setService(addServices().toArray(new ServiceItem[0])); }catch(SQLException sqle){logger.error("Error contacting HSQLDB "+sqle);} //sets the GHNs serviceList.setGHN(ghnList.toArray(new String[0])); arp.setServices(serviceList); scopeParameter.setAddResourcesParameters(arp); scopeParameter.setName(GCUBEScope.getScope(this.startingScope+"/"+this.vreName).toString()); String report=null; String reportId=rmPortType.createScope(scopeParameter); logger.trace("the report id for Rm is "+reportId); int reportAttempt=0; do{ try{ Thread.currentThread().sleep(20000); }catch (Exception e) {} report=rmPortType.getReport(reportId); reportAttempt++; getResource().getDeployReport().getFunctionalityDeployingReport().setResourceManagerReport(report); ReportFiller.reportElaboration(getResource().getDeployReport()); getResource().store(); }while (!(isDeploymentStatusFinished(report)) && reportAttempt<40); logger.info("is something failed in the second step?"+isSomethingFailed(report)); logger.trace("report step 2: "+report); return !isSomethingFailed(report); } /** * controls if something is failed deploying * @param report the VRE deployment report * @return true if Failed, else false */ private static boolean isSomethingFailed(String report){ boolean ret = false; String deploymentXpath = "/ResourceReport/DeploymentPlanCreation/Status"; String dependenciesResolutionXpath ="/ResourceReport/Services/Service/DependenciesResolutionStatus"; String serviceXpath="/ResourceReport/Services/Service/DeploymentActivity/GHN/LastReportReceived/Packages/Package/Status"; String resourceXpath="/ResourceReport/Resources/Resource[/Type/text()!='GHN']/Status"; String relatedRIXpath="/ResourceReport/Services/Service/DeploymentActivity/RelatedRunningInstance/Status"; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; try { db = dbf.newDocumentBuilder(); Document document = db.parse(new ByteArrayInputStream(report.getBytes())); XPath engine = XPathFactory.newInstance().newXPath(); NodeList nDeployment = (NodeList) engine.evaluate(deploymentXpath,document, XPathConstants.NODESET); for (int i = 0; i < nDeployment.getLength(); i++) { if(nDeployment.item(i).getFirstChild().getNodeValue().compareTo("FAILED")==0){ return true; } } NodeList nResoulution = (NodeList) engine.evaluate(dependenciesResolutionXpath,document, XPathConstants.NODESET); for (int i = 0; i < nResoulution.getLength(); i++) { if(nResoulution.item(i).getFirstChild().getNodeValue().compareTo("FAILED")==0){ return true; } } NodeList sResoulution = (NodeList) engine.evaluate(serviceXpath,document, XPathConstants.NODESET); for (int i = 0; i < sResoulution.getLength(); i++) { if(sResoulution.item(i).getFirstChild().getNodeValue().compareTo("FAILED")==0){ return true; } } NodeList resResoulution = (NodeList) engine.evaluate(resourceXpath,document, XPathConstants.NODESET); for (int i = 0; i < resResoulution.getLength(); i++) { if(resResoulution.item(i).getFirstChild().getNodeValue().compareTo("FAILED")==0){ return true; } } NodeList relResoulution = (NodeList) engine.evaluate(relatedRIXpath,document, XPathConstants.NODESET); for (int i = 0; i < relResoulution.getLength(); i++) { if(relResoulution.item(i).getFirstChild().getNodeValue().compareTo("FAILED")==0){ return true; } } } catch (ParserConfigurationException e) { return true; } catch (SAXException e) { return true; } catch (IOException e) { return true; } catch (XPathExpressionException e) { return true; } return ret; } private static boolean isDeploymentStatusFinished(String report) { boolean ret = false; String xpath = "/ResourceReport/Status"; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; try { db = dbf.newDocumentBuilder(); Document document = db.parse(new ByteArrayInputStream(report.getBytes())); XPath engine = XPathFactory.newInstance().newXPath(); NodeList nl = (NodeList) engine.evaluate(xpath,document, XPathConstants.NODESET); for (int i = 0; i < nl.getLength(); i++) { if(i==0){ ret = true; } if(nl.item(i).getFirstChild().getNodeValue().compareTo("CLOSED")!=0){ ret = false; break; } } } catch (ParserConfigurationException e) { return false; } catch (SAXException e) { return false; } catch (IOException e) { return false; } catch (XPathExpressionException e) { return false; } return ret; } private CreateScopeParameters getScopeParameters() throws Exception{ ResultSet resGenericInfo = DBInterface.queryDB("select VRE.name, VRE.vredesigner, VRE.vremanager, VRE.IntervalTo, VRE.IntervalFrom, VRE.description from VRE where VRE.id='"+this.resourceId+"'; "); if (!resGenericInfo.next()) throw new GCUBEFault("The VRE with ID "+this.resourceId+" cannot be retrieved"); CreateScopeParameters scopeParameter=new CreateScopeParameters(); OptionsParameters optPar= new OptionsParameters(); ScopeOption[] scopeOptionList= new ScopeOption[6]; ScopeOption soDesigner= new ScopeOption(); soDesigner.setName("DESIGNER"); soDesigner.setValue(resGenericInfo.getString("vredesigner")); scopeOptionList[0]= soDesigner; ScopeOption soCreator= new ScopeOption(); soCreator.setName("CREATOR"); soCreator.setValue(resGenericInfo.getString("vremanager")); scopeOptionList[1]= soCreator; ScopeOption soEndtime= new ScopeOption(); soEndtime.setName("ENDTIME"); soEndtime.setValue(KGCUBEResource.toXMLDateAndTime(resGenericInfo.getDate("IntervalTo"))); scopeOptionList[2]= soEndtime; ScopeOption soStarttime= new ScopeOption(); soStarttime.setName("STARTTIME"); soStarttime.setValue(KGCUBEResource.toXMLDateAndTime(resGenericInfo.getDate("IntervalFrom"))); scopeOptionList[3]= soStarttime; ScopeOption soDescription= new ScopeOption(); soDescription.setName("DESCRIPTION"); soDescription.setValue(resGenericInfo.getString("description")); scopeOptionList[4]= soDescription; ScopeOption soDisplayname= new ScopeOption(); soDisplayname.setName("DISPLAYNAME"); soDisplayname.setValue(resGenericInfo.getString("name")); scopeOptionList[5]= soDisplayname; optPar.setScopeOptionList(scopeOptionList); scopeParameter.setOptionsParameters(optPar); return scopeParameter; } private List addCollections() throws Exception{ List resItemList= new ArrayList(); ResourceItem resItem; ResultSet resRelatedCol =DBInterface.queryDB("select VRERELATEDCOLLECTION.collid from VRERELATEDCOLLECTION where VRERELATEDCOLLECTION.vreid='"+this.resourceId+"';"); while (resRelatedCol.next()){ resItem= new ResourceItem(); resItem.setID(resRelatedCol.getString(1)); logger.trace("selected collection:"+ resItem.getID()); resItem.setType(GCUBECollection.TYPE); resItemList.add(resItem); } return resItemList; } private List addGenericResources() throws Exception{ List resItemList= new ArrayList(); ResourceItem resItem; ResultSet neededRes =DBInterface.queryDB("select n.id, n.type from NEEDEDRESOURCES AS n;"); while (neededRes.next()){ resItem= new ResourceItem(); resItem.setID(neededRes.getString(1)); resItem.setType(neededRes.getString(2)); logger.trace("Needed GenericResources:"+ resItem.getID()); resItemList.add(resItem); } return resItemList; } private List addServices() throws Exception{ ServiceItem servItem; List listServices= new ArrayList(); ResultSet resService =DBInterface.queryDB("select DISTINCT s.name, s.class, s.version from VRERELATEDFUNCT AS vrf, SERVICES AS s where vrf.vreid='"+this.resourceId+"' AND s.id=vrf.funcid;"); while (resService.next()){ servItem= new ServiceItem(); servItem.setServiceClass(resService.getString("class")); servItem.setServiceName(resService.getString("name")); servItem.setServiceVersion(resService.getString("version")); logger.trace("selected services:"+ servItem.getServiceClass()+" "+servItem.getServiceName()+" "+servItem.getServiceVersion()); listServices.add(servItem); } return listServices; } }