resource-manager-gcore/src/org/gcube/vremanagement/resourcemanager/impl/state/ResourceReport.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
}
}