333 lines
13 KiB
Java
333 lines
13 KiB
Java
package org.gcube.vremanagement.resourcemanager.impl.state;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.FileReader;
|
|
import java.io.FileWriter;
|
|
import java.io.IOException;
|
|
import java.io.Serializable;
|
|
import java.io.StringWriter;
|
|
import java.util.Calendar;
|
|
import java.util.Collections;
|
|
import java.util.GregorianCalendar;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Observable;
|
|
import java.util.Observer;
|
|
import java.util.Set;
|
|
|
|
import org.gcube.common.core.scope.GCUBEScope;
|
|
import org.gcube.common.core.utils.logging.GCUBELog;
|
|
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
|
|
import org.gcube.vremanagement.resourcemanager.impl.deployment.DeployerReport;
|
|
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Dependency;
|
|
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.DeployedDependency;
|
|
import org.gcube.vremanagement.resourcemanager.impl.operators.Operator.ACTION;
|
|
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
|
|
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
|
|
import org.kxml2.io.KXmlSerializer;
|
|
|
|
/**
|
|
* Integrated deployment report. It collects the report sent by the Deployer Service and build a single integrated report
|
|
*
|
|
* @author Manuele Simi (ISTI-CNR)
|
|
*
|
|
*/
|
|
public class ResourceReport implements Serializable, Observer {
|
|
|
|
protected final GCUBELog logger = new GCUBELog(this, ServiceContext.getContext());
|
|
|
|
final static String NS = "";
|
|
|
|
/** */
|
|
private static final long serialVersionUID = 1180822699138069365L;
|
|
|
|
private static final String reportDir = "reports";
|
|
|
|
/** report last update timestamp */
|
|
private Calendar lastUpdate = new GregorianCalendar();
|
|
|
|
private String id = "";
|
|
|
|
private GCUBEScope scope = null;
|
|
|
|
/** ghn id -> deployer report map*/
|
|
private Map<String, DeployerReport> node2report = Collections.synchronizedMap(new HashMap<String, DeployerReport>());
|
|
|
|
/** Status of a dependency resolver request */
|
|
public enum DEPSTATUS {SUCCESS, FAILED};
|
|
|
|
private Set<ScopedDeployedService> services = Collections.synchronizedSet(new HashSet<ScopedDeployedService>());
|
|
|
|
private Set<ScopedResource> resources = Collections.synchronizedSet(new HashSet<ScopedResource>());
|
|
|
|
/** internally used by {@link ResourceReport#loadAsString(String)}*/
|
|
private ResourceReport () {}
|
|
|
|
/**
|
|
* Builds a new empty report
|
|
* @param id the session ID assigned to the operation
|
|
*/
|
|
public ResourceReport(String id, GCUBEScope ... scope) {
|
|
this.id = id;
|
|
if ((scope == null)|| (scope[0] == null))
|
|
this.scope = ServiceContext.getContext().getInstance().getScopes().values().iterator().next();
|
|
else
|
|
this.scope = scope[0];
|
|
}
|
|
|
|
/**
|
|
* Adds a Deployer Report to the Resource Report
|
|
* @param report the string representation of the report, as sent by a Deployer service
|
|
* @throws Exception if a problem in the report parsing occurs
|
|
*/
|
|
synchronized public void addGHNReport(DeployerReport report) throws Exception {
|
|
node2report.put(report.getGHNID(), report);
|
|
this.lastUpdate = new GregorianCalendar();
|
|
}
|
|
|
|
synchronized public void addResource(ScopedResource resource) {
|
|
this.resources.add(resource);
|
|
this.lastUpdate = new GregorianCalendar();
|
|
}
|
|
|
|
synchronized public void addService(ScopedDeployedService service) {
|
|
this.services.add(service);
|
|
this.lastUpdate = new GregorianCalendar();
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
public String toXML() throws IOException {
|
|
StringWriter report = new StringWriter(); // serialises to a temporary writer first
|
|
KXmlSerializer serializer = new KXmlSerializer();
|
|
serializer.setOutput(report);
|
|
//serializer.setProperty(XmlSerializer, "\t");
|
|
try {
|
|
serializer.startDocument("UTF-8", true);
|
|
serializer.startTag(NS,"ResourceReport");
|
|
serializer.startTag(NS,"ID").text(this.id).endTag(NS, "ID");
|
|
serializer.startTag(NS,"LastUpdate").text(ProfileDate.toXMLDateAndTime(this.lastUpdate.getTime())).endTag(NS,"LastUpdate");
|
|
serializer.startTag(NS,"TargetScope").text(this.scope.toString()).endTag(NS,"TargetScope");
|
|
|
|
//resources section
|
|
serializer.startTag(NS,"Resources");
|
|
for (ScopedResource resource : resources) {
|
|
serializer.startTag(NS,"Resource");
|
|
serializer.startTag(NS,"ID").text(resource.getId()).endTag(NS,"ID");
|
|
serializer.startTag(NS,"Type").text(resource.getType()).endTag(NS,"Type");
|
|
if (resource.isSuccess()) {
|
|
if (resource.getAction().compareTo(ACTION.ADD) == 0)
|
|
serializer.startTag(NS,"Status").text("ADDED").endTag(NS,"Status");
|
|
else if (resource.getAction().compareTo(ACTION.REMOVE) == 0)
|
|
serializer.startTag(NS,"Status").text("REMOVED").endTag(NS,"Status");
|
|
serializer.startTag(NS,"ErrorDescription").text("-").endTag(NS,"ErrorDescription");
|
|
} else {
|
|
serializer.startTag(NS,"Status").text("FAILED").endTag(NS,"Status");
|
|
serializer.startTag(NS,"ErrorDescription").text(resource.getErrorMessage()).endTag(NS,"ErrorDescription");
|
|
}
|
|
serializer.endTag(NS,"Resource");
|
|
}
|
|
|
|
serializer.endTag(NS,"Resources");
|
|
//services section
|
|
|
|
serializer.startTag(NS,"Services");
|
|
for (ScopedDeployedService service : this.services) {
|
|
serializer.startTag(NS,"Service");
|
|
serializer.startTag(NS,"ID").text(service.getId()).endTag(NS, "ID");
|
|
serializer.startTag(NS,"Class").text(service.getSourceService().getClazz()).endTag(NS, "Class");
|
|
serializer.startTag(NS,"Name").text(service.getSourceService().getName()).endTag(NS, "Name");
|
|
serializer.startTag(NS,"Version").text(service.getSourceService().getVersion()).endTag(NS, "Version");
|
|
if ( (service.getMissingDependencies().size() > 0) || (service.getErrorMessage().length() > 0) ) {
|
|
serializer.startTag(NS,"DependenciesResolutionStatus").text(DEPSTATUS.FAILED.name()).endTag(NS, "DependenciesResolutionStatus");
|
|
serializer.startTag(NS,"DeployedOn").text("not deployed").endTag(NS, "DeployedOn");
|
|
serializer.startTag(NS,"ErrorDescription").text(service.getErrorMessage()).endTag(NS, "ErrorDescription");
|
|
}else {
|
|
serializer.startTag(NS,"DependenciesResolutionStatus").text(DEPSTATUS.SUCCESS.name()).endTag(NS, "DependenciesResolutionStatus");
|
|
serializer.startTag(NS,"DeployedOn").text(service.getHostedOn()).endTag(NS, "DeployedOn");
|
|
serializer.startTag(NS,"ErrorDescription").text("-").endTag(NS, "ErrorDescription");
|
|
}
|
|
serializer.startTag(NS,"DependenciesResolution");
|
|
//resolved dependencies
|
|
serializer.startTag(NS,"ResolvedDependencies");
|
|
for (Dependency dep : service.getResolvedDependencies()) {
|
|
serializer.startTag(NS,"Dependency");
|
|
serializer.startTag(NS,"ServiceClass").text(dep.getService().getClazz()).endTag(NS, "ServiceClass");
|
|
serializer.startTag(NS,"ServiceName").text(dep.getService().getName()).endTag(NS, "ServiceName");
|
|
serializer.startTag(NS,"ServiceVersion").text(dep.getService().getVersion()).endTag(NS, "ServiceVersion");
|
|
serializer.startTag(NS,"PackageName").text(dep.getName()).endTag(NS, "PackageName");
|
|
serializer.startTag(NS,"PackageVersion").text(dep.getVersion()).endTag(NS, "PackageVersion");
|
|
serializer.endTag(NS,"Dependency");
|
|
}
|
|
serializer.endTag(NS,"ResolvedDependencies");
|
|
//missing dependencies
|
|
serializer.startTag(NS,"MissingDependencies");
|
|
for (Dependency dep : service.getMissingDependencies()) {
|
|
serializer.startTag(NS,"Dependency");
|
|
serializer.startTag(NS,"ServiceClass").text(dep.getService().getClazz()).endTag(NS, "ServiceClass");
|
|
serializer.startTag(NS,"ServiceName").text(dep.getService().getName()).endTag(NS, "ServiceName");
|
|
serializer.startTag(NS,"ServiceVersion").text(dep.getService().getVersion()).endTag(NS, "ServiceVersion");
|
|
serializer.startTag(NS,"PackageName").text(dep.getName()).endTag(NS, "PackageName");
|
|
serializer.startTag(NS,"PackageVersion").text(dep.getVersion()).endTag(NS, "PackageVersion");
|
|
serializer.endTag(NS,"Dependency");
|
|
}
|
|
serializer.endTag(NS,"MissingDependencies");
|
|
serializer.endTag(NS,"DependenciesResolution");
|
|
//add the deployment report if it is available
|
|
String reportID = /*service.getId() + "-" +*/ service.getHostedOn();
|
|
serializer.startTag(NS,"DeploymentActivity");
|
|
if (node2report.keySet().contains(reportID)) {
|
|
serializer.startTag(NS,"GHN");
|
|
serializer.startTag(NS,"ID").text(service.getHostedOn()).endTag(NS, "ID");
|
|
serializer.startTag(NS,"Host").text(node2report.get(reportID).getHost()).endTag(NS,"Host");
|
|
serializer.startTag(NS,"LastReportReceivedOn").text(ProfileDate.toXMLDateAndTime(node2report.get(reportID).getLastUpdate())).endTag(NS,"LastReportReceivedOn");
|
|
serializer.startTag(NS,"LastReportReceived");
|
|
serializer.startTag(NS,"Status").text(node2report.get(reportID).getStatus()).endTag(NS, "Status");
|
|
this.addGHNReport(serializer, node2report.get(reportID));
|
|
serializer.endTag(NS, "LastReportReceived");
|
|
serializer.endTag(NS,"GHN");
|
|
} else {
|
|
if (service.isSuccess())
|
|
serializer.text("Deployment report is still not available for this service");
|
|
else
|
|
serializer.text("No report");
|
|
}
|
|
|
|
serializer.endTag(NS,"DeploymentActivity");
|
|
|
|
serializer.endTag(NS,"Service");
|
|
}
|
|
serializer.endTag(NS,"Services");
|
|
// serializer.startTag(NS,"DeploymentActivity");
|
|
// for (String ghnID : node2report.keySet()) {
|
|
// serializer.startTag(NS,"GHN");
|
|
// serializer.startTag(NS,"ID").text(ghnID).endTag(NS, "ID");
|
|
// serializer.startTag(NS,"Host").text(node2report.get(ghnID).getHost()).endTag(NS,"Host");
|
|
// serializer.startTag(NS,"LastReportReceivedOn").text(ProfileDate.toXMLDateAndTime(node2report.get(ghnID).getLastUpdate())).endTag(NS,"LastReportReceivedOn");
|
|
// serializer.startTag(NS,"LastReportReceived");
|
|
// serializer.startTag(NS,"Status").text(node2report.get(ghnID).getStatus()).endTag(NS, "Status");
|
|
// this.addGHNReport(serializer, node2report.get(ghnID));
|
|
// serializer.endTag(NS, "LastReportReceived");
|
|
// serializer.endTag(NS,"GHN");
|
|
// }
|
|
//
|
|
// serializer.endTag(NS,"DeploymentActivity");
|
|
serializer.endTag(NS,"ResourceReport");
|
|
serializer.endDocument();
|
|
}
|
|
catch (Exception e) {
|
|
logger.error("The Resource Report does not have a valid serialisation", e);
|
|
throw new IOException("The Resource Report does not have a valid serialisation");
|
|
}
|
|
finally {
|
|
report.close();
|
|
}
|
|
return report.toString();
|
|
}
|
|
|
|
/**
|
|
* @return the lastUpdate
|
|
*/
|
|
public Calendar getLastUpdate() {
|
|
return lastUpdate;
|
|
}
|
|
|
|
/**
|
|
* @return the resource report identifier
|
|
*/
|
|
public String getId() {
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* @return the scope this report belongs to
|
|
*/
|
|
public GCUBEScope getScope() {
|
|
return scope;
|
|
}
|
|
|
|
/**
|
|
* Saves the report on the local file system
|
|
*
|
|
* @throws IOException if the saving fails
|
|
*/
|
|
synchronized public void save() throws IOException {
|
|
FileWriter file = new FileWriter(getReportFile(this.id));
|
|
file.write(this.toXML());
|
|
file.close();
|
|
}
|
|
|
|
/**
|
|
* Loads the report from the file system
|
|
*
|
|
* @param id the report ID
|
|
* @return the report
|
|
* @throws IOException if the report does not have a valid serialization
|
|
*/
|
|
protected static ResourceReport load(String id) throws IOException {
|
|
ResourceReport report = new ResourceReport();
|
|
// load the report from its serialization
|
|
|
|
return report;
|
|
}
|
|
|
|
/**
|
|
* Loads the report from the file system
|
|
*
|
|
* @param id the report ID
|
|
* @return the string representation of the report
|
|
* @throws IOException if the report does not have a valid serialization
|
|
*/
|
|
protected static String loadAsString(String id) throws IOException {
|
|
|
|
// load the report serialization
|
|
|
|
File f = getReportFile(id);
|
|
if (! f.exists())
|
|
throw new IOException("Unable to find a serialized report with ID=" + id);
|
|
|
|
BufferedReader br = new BufferedReader(new FileReader(f));
|
|
StringBuilder report = new StringBuilder();
|
|
String s;
|
|
while((s = br.readLine()) != null) {
|
|
report.append(s);
|
|
}
|
|
|
|
br.close();
|
|
return report.toString();
|
|
}
|
|
|
|
private static File getReportFile(String id) throws IOException {
|
|
return new File(ServiceContext.getContext().getConfigurationFileAbsolutePath(reportDir) + File.separator + id + ".xml");
|
|
|
|
}
|
|
|
|
private void addGHNReport(KXmlSerializer serializer, DeployerReport report) throws Exception {
|
|
|
|
serializer.startTag(NS, "Packages");
|
|
for (DeployedDependency dep: report.getDependencies()) {
|
|
serializer.startTag(NS,"Package");
|
|
serializer.startTag(NS,"ServiceClass").text(dep.getService().getClazz()).endTag(NS, "ServiceClass");
|
|
serializer.startTag(NS,"ServiceName").text(dep.getService().getName()).endTag(NS, "ServiceName");
|
|
serializer.startTag(NS,"ServiceVersion").text(dep.getService().getVersion()).endTag(NS, "ServiceVersion");
|
|
serializer.startTag(NS,"PackageName").text(dep.getName()).endTag(NS, "PackageName");
|
|
serializer.startTag(NS,"PackageVersion").text(dep.getVersion()).endTag(NS, "PackageVersion");
|
|
serializer.startTag(NS,"Status").text(dep.getStatus()).endTag(NS, "Status");
|
|
serializer.startTag(NS,"Message").text(dep.getMessage()).endTag(NS, "Message");
|
|
serializer.endTag(NS,"Package");
|
|
}
|
|
serializer.endTag(NS, "Packages");
|
|
|
|
}
|
|
|
|
public void update(Observable o, Object arg) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|