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.apache.axis.message.addressing.EndpointReferenceType; import org.gcube.common.core.contexts.GCUBERemotePortTypeContext; import org.gcube.common.core.contexts.GHNContext; import org.gcube.common.core.faults.GCUBEFault; import org.gcube.common.core.informationsystem.client.ISClient; import org.gcube.common.core.informationsystem.client.queries.GCUBERIQuery; 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.GCUBERunningInstance; import org.gcube.common.core.scope.GCUBEScope; import org.gcube.common.core.utils.handlers.GCUBEServiceClientImpl; import org.gcube.common.core.utils.handlers.GCUBEServiceHandler.NoQueryResultException; 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.resourcemanager.stubs.resourcemanager.service.ResourceManagerServiceAddressingLocator; 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.ServiceContext; import org.gcube.vremanagement.vremodeler.impl.util.Pair; import org.gcube.vremanagement.vremodeler.impl.util.ResourceManagerServiceHandler; import org.gcube.vremanagement.vremodeler.portallayout.CollectionResourceCreation; import org.gcube.vremanagement.vremodeler.portallayout.GenericResourcePortlet; import org.gcube.vremanagement.vremodeler.portallayout.LayoutCreation; import org.gcube.vremanagement.vremodeler.stubs.VREState; import org.globus.wsrf.ResourceException; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class DeployVREonGHNs 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 DeployVREonGHNs(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, VRERELATEDGHN.ISCANDIDATE from VRERELATEDGHN, GHN where GHN.id=VRERELATEDGHN.ghnid and VRERELATEDGHN.vreid='"+this.resourceId+"' ORDER BY GHN.host; "); List> GHNList= new ArrayList>(); String candidateGHN=null; boolean isCandidatePresent=false; while (resRelatedGHN.next()) { if(resRelatedGHN.getBoolean(3)){ candidateGHN=resRelatedGHN.getString(1); isCandidatePresent= true; }else GHNList.add(new Pair(resRelatedGHN.getString(1),resRelatedGHN.getString(2))); } if (!(GHNList.size()>=2 || (GHNList.size()==1 && isCandidatePresent))){ getResource().setFirstReport(VREState.FAILED.getValue()+": wrong ghn definition"); getResource().store(); logger.info("Deploying of the VRE with id "+this.resourceId+" FAILED for wrong ghn definition"); throw new Exception("No ghn Selected (at least 2 GHNs have to be selected)"); } if (!deployManagerOnVRE(GHNList, candidateGHN)){ //transforming the Pair to a ghnid List List ghnEpuredList = new ArrayList(); for (Pair cpl: GHNList) ghnEpuredList.add(cpl.first); if (!createVRE(ghnEpuredList)){ DBInterface.ExecuteUpdate("UPDATE VRE SET STATUS='"+VREState.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"); getResource().setSecondReport(VREState.FAILED.getValue()); throw new Exception("Error Deployng the VRE failed on second step"); } }else{ getResource().setFirstReport(VREState.FAILED.getValue()); 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='"+VREState.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, String candidateGHN) 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 (Exception e) { logger.error("HSQLDB Error "+e); throw new GCUBEFault(e); } ResourceManagerServiceHandler resourceManagerHandler= new ResourceManagerServiceHandler(){ @SuppressWarnings({ "static-access", "unchecked" }) @Override protected Boolean makeCall(ResourceManagerPortType resourceManagerPT) throws Exception { String report; try{ String vreName=(String) this.getParameter()[0]; List> ghnList= (List>) this.getParameter()[1]; String candidateGHN=(String) this.getParameter()[2]; 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); //preparing the GHN where will be deployed the VREManager if (candidateGHN==null){ Pair ghnId=null; for (Pair cpl: ghnList){ if (this.usedhost.contains(cpl.second)){ ghnId=cpl; break; } } if (ghnId==null) ghnId=ghnList.get(0); logger.debug("deploying the ResourceManager for the vre on "+ ghnId.second); services.setGHN(new String[]{ghnId.first}); ghnList.remove(ghnId); }else services.setGHN(new String[]{candidateGHN}); arp.setServices(services); arp.setTargetScope(this.scope+"/"+vreName); String reportId=resourceManagerPT.addResources(arp); int attempt=0; do{ Thread.currentThread().sleep(20000); report=resourceManagerPT.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); } }; resourceManagerHandler.clearBlackboard(); resourceManagerHandler.setHandled(new GCUBEServiceClientImpl()); resourceManagerHandler.setParameter(new Object[]{vreName,ghnList,candidateGHN}); resourceManagerHandler.scope=this.startingScope; try { resourceManagerHandler.run(); } catch (Exception e) { logger.error("DeployingVRE step 1 -- failed "+e); return false; } this.vreName= vreName; collectionResourceCreation= new CollectionResourceCreation(this.resourceId, this.vreName); return resourceManagerHandler.getReturnValue(); } @SuppressWarnings("static-access") private boolean createVRE(List ghnList) throws Exception{ ResourceManagerPortType rmPortType=null; int attempt=0; do{ try{ try{ Thread.currentThread().sleep(30000); }catch (Exception et){} ISClient client = GHNContext.getImplementation(ISClient.class); GCUBERIQuery query = client.getQuery(GCUBERIQuery.class); query.setExpression("declare namespace is = 'http://gcube-system.org/namespaces/informationsystem/registry';" + " for $outer in collection(\"/db/Profiles/RunningInstance\")//Document/Data/is:Profile/Resource " + " let $scope:= $outer/Scopes/Scope[string() eq '"+GCUBEScope.getScope(this.startingScope+"/"+this.vreName).toString()+"'] " + " where count($scope)>0 " + " and $outer/Profile/ServiceName/string() eq 'ResourceManager' " + " return $outer"); List eprs = new ArrayList(); for (GCUBERunningInstance instance : client.execute(query, GCUBEScope.getScope(this.startingScope+"/"+this.vreName))) eprs.add(instance.getAccessPoint().getEndpoint("gcube/vremanagement/ResourceManager")); if(eprs.size()==0) throw new NoQueryResultException(); ResourceManagerServiceAddressingLocator vmsal= new ResourceManagerServiceAddressingLocator(); rmPortType= vmsal.getResourceManagerPortTypePort(eprs.get(0)); rmPortType = GCUBERemotePortTypeContext.getProxy(rmPortType,GCUBEScope.getScope(this.startingScope+"/"+this.vreName), Integer.parseInt((String)ServiceContext.getContext().getProperty("resourceManagerTimeout", true))); }catch(Exception e){ logger.warn(e); logger.warn("the query for resourceManager returned no result, re-trying in 30 secs ("+attempt+")"); }finally {attempt++;} }while(rmPortType==null && attempt<10); if (attempt>=10) throw new Exception("no ResourceMaanger can be retrieved for scope "+GCUBEScope.getScope(this.startingScope+"/"+this.vreName).toString()); 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); //creating the GenericResources for Portlets and Collection GenericResourcePortlet.createResource(getResource().getId(), vreName); collectionResourceCreation.createAndPublish(); LayoutCreation createdlayout= new LayoutCreation(getResource().getId(), vreName); createdlayout.createAndPublishLayout(); //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{ 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.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 n.mdcollid from VRERELATEDMETADATAFORMAT AS s, NATIVEMDF as n where s.vreid='"+this.resourceId+"' and n.mdfid=s.mfid;"); 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){ 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); genResItem= new ResourceItem(); genResItem.setID(createdlayout.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)); logger.debug("Needed GenericResources:"+ resItem.getID()); resItemList.add(resItem); } }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{ 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.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.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(ghnList.toArray(new String[0])); arp.setServices(serviceList); scopeParameter.setAddResourcesParameters(arp); scopeParameter.setName(GCUBEScope.getScope(this.startingScope+"/"+this.vreName).toString()); String report= "starting"; String reportId=rmPortType.createScope(scopeParameter); int reportAttempt=0; do{ try{ Thread.currentThread().sleep(20000); }catch (Exception e) {} report=rmPortType.getReport(reportId); reportAttempt++; getResource().setSecondReport(report); 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 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"; 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; } } } 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/Services/Service/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; } }