vre-modeler/src/org/gcube/vremanagement/vremodeler/impl/thread/DeployVREonGHNs.java

505 lines
20 KiB
Java
Raw Normal View History

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<Pair<String, String>> GHNList= new ArrayList<Pair<String, String>>();
String candidateGHN=null;
boolean isCandidatePresent=false;
while (resRelatedGHN.next()) {
if(resRelatedGHN.getBoolean(3)){
candidateGHN=resRelatedGHN.getString(1);
isCandidatePresent= true;
}else GHNList.add(new Pair<String, String>(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<String, String> to a ghnid List<String>
List<String> ghnEpuredList = new ArrayList<String>();
for (Pair<String, String> 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<Pair<String, String>> 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<Boolean, Object[]> resourceManagerHandler= new ResourceManagerServiceHandler<Boolean,Object[]>(){
@SuppressWarnings({ "static-access", "unchecked" })
@Override
protected Boolean makeCall(ResourceManagerPortType resourceManagerPT)
throws Exception {
String report;
try{
String vreName=(String) this.getParameter()[0];
List<Pair<String, String>> ghnList= (List<Pair<String, String>>) 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<String, String> ghnId=null;
for (Pair<String, String> 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<String> 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<EndpointReferenceType> eprs = new ArrayList<EndpointReferenceType>();
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<ResourceItem> resItemList= new ArrayList<ResourceItem>();
//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<ServiceItem> listService= new ArrayList<ServiceItem>();
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;
}
}