package org.gcube.vremanagement.vremodeler.impl.thread; 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.resources.impl.kxml.KGCUBEResource; import org.gcube.common.core.scope.GCUBEScope; import org.gcube.common.core.utils.handlers.GCUBEServiceClientImpl; import org.gcube.common.core.utils.logging.GCUBELog; import org.gcube.vremanagement.vremanager.stubs.vremanager.AddResourcesParameters; import org.gcube.vremanagement.vremanager.stubs.vremanager.OptionsParameters; import org.gcube.vremanagement.vremanager.stubs.vremanager.ResourceItem; import org.gcube.vremanagement.vremanager.stubs.vremanager.ResourceList; import org.gcube.vremanagement.vremanager.stubs.vremanager.ScopeOption; import org.gcube.vremanagement.vremanager.stubs.vremanager.ServiceItem; import org.gcube.vremanagement.vremanager.stubs.vremanager.ServiceList; import org.gcube.vremanagement.vremanager.stubs.vremanager.VREManagerPortType; 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.Couple; import org.gcube.vremanagement.vremodeler.impl.util.VREManagerServiceHandler; import org.gcube.vremanagement.vremodeler.portallayout.CollectionResourceCreation; import org.gcube.vremanagement.vremodeler.portallayout.GenericResourcePortlet; 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){ this.resourceId=resourceId; this.startingScope= scope; } private ModelerResource getResource() throws ResourceException{ if (wsResource==null) wsResource= (ModelerResource)ModelerContext.getPortTypeContext().getWSHome().find(ModelerContext.getPortTypeContext().makeKey(resourceId)); return wsResource; } public void run() { try { ResultSet resRelatedGHN=DBInterface.queryDB("select VRERELATEDGHN.ghnid, GHN.domain from VRERELATEDGHN, GHN where GHN.id=VRERELATEDGHN.ghnid and VRERELATEDGHN.vreid='"+this.resourceId+"'; "); List> GHNList= new ArrayList>(); while (resRelatedGHN.next()) GHNList.add(new Couple(resRelatedGHN.getString(1),resRelatedGHN.getString(2))); if (GHNList.size()<2){ throw new Exception("No ghn Selected (at least 2 GHNs have to be selcted)"); } if (!deployManagerOnVRE(GHNList)){ //transforming the Couple to a ghnid List List ghnEpuredList = new ArrayList(); for (Couple cpl: GHNList) ghnEpuredList.add(cpl.first); if (!createVRE(ghnEpuredList)){ DBInterface.ExecuteUpdate("UPDATE VRE SET STATUS='"+ModelerService.DEPLOYED+"' WHERE VRE.id='"+this.resourceId+"';"); 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"); throw new Exception("Error Deployng the VRE failed on second step"); } }else{ getResource().setSecondReport("FAILED"); getResource().store(); 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='"+ModelerService.FAILED+"' WHERE VRE.id='"+this.resourceId+"';"); } 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(List> GHNList) throws GCUBEFault{ String vreName= null; try { DBInterface.ExecuteUpdate("UPDATE VRE SET STATUS='Deploying' WHERE VRE.id='"+this.resourceId+"';"); 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); } catch (SQLException e) { logger.error("HSQLDB Error "+e); throw new GCUBEFault(e); } // Couple>> is a triple with first GCUBEScope, second couple: first String is the VREName, second string is the GHNId VREManagerServiceHandler>>> vreManagerHandler= new VREManagerServiceHandler>>>(){ @SuppressWarnings("static-access") @Override protected Boolean makeCall(VREManagerPortType mbportType) throws Exception { 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("VREManager"); service[0].setServiceVersion("1.00.00"); services.setService(service); Couple ghnId=null; for (Couple cpl: getParameter().second){ if (this.usedhost.contains(cpl.second)){ ghnId=cpl; break; } } if (ghnId==null) ghnId=getParameter().second.get(0); logger.debug("deploying the VREManager for the vre on "+ ghnId.second); services.setGHN(new String[]{ghnId.first}); arp.setServices(services); arp.setTargetScope(this.scope+"/"+this.getParameter().first); getParameter().second.remove(ghnId); String reportId=mbportType.addResources(arp); int attempt=0; do{ Thread.currentThread().sleep(20000); report=mbportType.getReport(reportId); attempt++; getResource().setFirstReport(report); getResource().store(); }while (!isDeploymentStatusFinished(report) && attempt<10); }catch(Exception e){e.printStackTrace(); throw e;} logger.trace("report step 1: "+report); logger.info("is something failed in the first step?"+isSomethingFailed(report)); return isSomethingFailed(report); } }; vreManagerHandler.clearState(); vreManagerHandler.setHandled(new GCUBEServiceClientImpl()); Couple>> coupleParams= new Couple>>(vreName, GHNList); vreManagerHandler.setParameter(coupleParams); vreManagerHandler.scope=this.startingScope; try { vreManagerHandler.run(); } catch (Exception e) { logger.error("DeployingVRE step 1 -- failed "+e); return false; } this.vreName= vreName; collectionResourceCreation= new CollectionResourceCreation(this.resourceId, this.vreName); return vreManagerHandler.getReturnValue(); } private boolean createVRE(List ghnList) throws GCUBEFault{ VREManagerServiceHandler, String>> vreManagerHandler= new VREManagerServiceHandler, String>>(){ //the parameter is resourceID @SuppressWarnings("static-access") @Override protected Boolean makeCall(VREManagerPortType vreManPortType) throws Exception { OptionsParameters ops; ResultSet resGenericInfo = DBInterface.queryDB("select VRE.name, VRE.vredesigner, VRE.vremanager, VRE.IntervalTo, VRE.IntervalFrom, VRE.description from VRE where VRE.id='"+this.getParameter().second+"'; "); if (!resGenericInfo.next()) throw new GCUBEFault("The VRE with ID "+this.getParameter().second+" cannot be retrieved"); ops=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; ops.setScopeOptionList(scopeOptionList); vreManPortType.setScopeOptions(ops); //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(60000); //Adding the resources to the new VRE AddResourcesParameters arp= new AddResourcesParameters(); ResourceList rl= new ResourceList(); List resItemList= new ArrayList(); //retrieving Collection try{ ResourceItem resItem; ResultSet resRelatedCol =DBInterface.queryDB("select VRERELATEDCOLLECTION.collid from VRERELATEDCOLLECTION where VRERELATEDCOLLECTION.vreid='"+this.getParameter().second+"';"); while (resRelatedCol.next()){ resItem= new ResourceItem(); resItem.setID(resRelatedCol.getString(1)); logger.debug("selected collection:"+ resItem.getID()); resItem.setType(GCUBECollection.TYPE); resItemList.add(resItem); } }catch(SQLException sqle){logger.error("Error contacting HSQLDB "+sqle);} //retrieving MDCollection with native MDFormat try{ ResourceItem resItem; ResultSet resMdColNative =DBInterface.queryDB("select s.mdcollid from SELECTEDNATIVEMDFORMAT AS s where s.vreid='"+this.getParameter().second+"';"); while (resMdColNative.next()){ resItem= new ResourceItem(); resItem.setID(resMdColNative.getString(1)); logger.debug("selected MetadataCollection:"+ resItem.getID()); resItem.setType(GCUBEMCollection.TYPE); resItemList.add(resItem); } }catch(SQLException sqle){ sqle.printStackTrace(); logger.error("Error contacting HSQLDB "+sqle); } //adding the CollectionResource genericResource ResourceItem genResItem= new ResourceItem(); genResItem= new ResourceItem(); genResItem.setID(collectionResourceCreation.getCreatedResourceId()); genResItem.setType(GCUBEGenericResource.TYPE); resItemList.add(genResItem); //adding the other needed resources try{ 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)); resItemList.add(resItem); } }catch(SQLException sqle){ sqle.printStackTrace(); logger.error("Error contacting HSQLDB "+sqle); } rl.setResource(resItemList.toArray(new ResourceItem[0])); arp.setResources(rl); //retrieve services ServiceList serviceList= new ServiceList(); try{ ServiceItem servItem; List listService= 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.getParameter().second+"' 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.debug("selected services:"+ servItem.getServiceClass()+" "+servItem.getServiceName()+" "+servItem.getServiceVersion()); listService.add(servItem); } serviceList.setService(listService.toArray(new ServiceItem[0])); }catch(SQLException sqle){logger.error("Error contacting HSQLDB "+sqle);} //sets the GHNs serviceList.setGHN(this.getParameter().first.toArray(new String[0])); arp.setServices(serviceList); for (String ghn: this.getParameter().first){ logger.debug(ghn); } String report= "ok"; String reportId=vreManPortType.addResources(arp); int attempt=0; do{ Thread.currentThread().sleep(20000); report=vreManPortType.getReport(reportId); attempt++; getResource().setSecondReport(report); getResource().store(); }while (!isDeploymentStatusFinished(report) && attempt<20); logger.info("is something failed in the second step?"+isSomethingFailed(report)); logger.trace("report step 2: "+report); return isSomethingFailed(report); } }; vreManagerHandler.clearState(); vreManagerHandler.setHandled(new GCUBEServiceClientImpl()); vreManagerHandler.setParameter(new Couple, String>(ghnList,this.resourceId)); vreManagerHandler.scope=GCUBEScope.getScope(this.startingScope+"/"+this.vreName); try { vreManagerHandler.run(); } catch (Exception e) { e.printStackTrace(); logger.error("DeployingVRE step 2 -- failed "+e); throw new GCUBEFault(e); } return vreManagerHandler.getReturnValue(); } /** * controls if something is failed deploying * @param report the VRE deployment report * @return true if Failed, else false */ private boolean isSomethingFailed(String report){ boolean ret = false; String xpath = "/ResourceReport/DeploymentActivity/GHN/LastReportReceived/Packages/Package/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(nl.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 boolean isDeploymentStatusFinished(String report) { boolean ret = false; String xpath = "/ResourceReport/DeploymentActivity/GHN/LastReportReceived/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; } }