Resource Manager: merging from branch 1.0

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/vre-management/ResourceManager@26023 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Manuele Simi 2010-09-02 19:26:46 +00:00
parent 54785502b7
commit 3ac49bcd77
38 changed files with 953 additions and 324 deletions

View File

@ -11,5 +11,6 @@
<classpathentry kind="lib" path="/Dependencies/XStream/xstream-1.3.1.jar"/>
<classpathentry kind="lib" path="/Dependencies/JUnit/junit.jar"/>
<classpathentry kind="lib" path="/Dependencies/ResourceBroker/org.gcube.vremanagement.resourcebroker.stubs.jar"/>
<classpathentry kind="lib" path="/Dependencies/ResourceBroker/org.gcube.vremanagement.resourcebroker.serialization.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -1,15 +0,0 @@
v. 1.2.3 (20-11-2009)
* Porting on gCore 0.6.0
v. 1.2.0 (13-05-2009)
* Porting on gCore 0.5.0
* Fixing the loading sequence of the ScopeResource
* Dedicated ScopeResource per VO and Infrastructure
* State under persistent root folder
v. 1.1.0 (14-11-2008)
* Management of ScopeResource, improved reporting and management of any GCUBEResource
v. 1.0.0 (28-09-2008)
* First release

2
README
View File

@ -13,7 +13,7 @@ Authors
Version and Release Date
------------------------
v. 1.0.0, 25/09/2008
v. 1.0.3, 30/08/2010
Description
-----------

18
changelog.xml Normal file
View File

@ -0,0 +1,18 @@
<ReleaseNotes>
<Changeset component="org.gcube.vre-management.resourcemanager.1-0-3" date="2010-08-30">
<Change>Fixing undeployment of the same RI from different scopes</Change>
<Change>Integration of the Serialization Library of the Broker Service</Change>
</Changeset>
<Changeset component="org.gcube.vre-management.resourcemanager.1-0-2" date="2010-07-21">
<Change>Fixing node2missing variable's initialization in ScopeDeployedService for backwards compatibility</Change>
</Changeset>
<Changeset component="org.gcube.vre-management.resourcemanager.1-0-1" date="2010-06-25">
<Change>Resource Report: the GHN section reports only the packages belonging the service (post-filtering)</Change>
<Change>Resolving some issues in the communication with the Broker</Change>
<Change>Resource Report: fixed the problem preventing the report of missing/resolved dependencies</Change>
<Change>Resource Report: new global Status element stating if the Report is closed or not</Change>
</Changeset>
<Changeset component="org.gcube.vre-management.resourcemanager.1-0-0" date="2010-05-20">
<Change>First release</Change>
</Changeset>
</ReleaseNotes>

View File

@ -19,28 +19,23 @@
value="org.gcube.vremanagement.resourcemanager.impl.brokerage.ServiceBroker"
type="java.lang.String"
override="false" />
<!--
<!--
<environment
name="startScopes"
value=""
type="java.lang.String"
override="false" />
-->
override="false" /> -->
</service>
<service name="gcube/vremanagement/ResourceManager">
<environment
name="name"
value="VREManager"
value="ResourceManager"
type="java.lang.String"
override="false" />
<environment
name="RPDName"
value="VREManagerResourceProperties"
type="java.lang.String"
override="false"/>
<resource name="home" type="org.gcube.vremanagement.resourcemanager.impl.state.ResourceManagerHome">
<resourceParams>

View File

@ -26,13 +26,13 @@
</Dependencies>
<Packages>
<Main deployable="true">
<Description>Service package for creating a ResourceManager instance: provide an implementation of all ResourceManager operations</Description>
<Description>ResourceManager creates and manages Scopes within a gCube infrastructure</Description>
<Name>ResourceManager-service</Name>
<Version>1.0.0</Version>
<Version>1.0.3</Version>
<Mandatory level="VRE"/>
<Shareable level="NONE"/>
<GHNRequirements>
<Requirement category="MEM_RAM_SIZE" operator="ge" value="1000"/>
<Requirement category="MEM_VIRTUAL_SIZE" operator="ge" value="1000"/>
</GHNRequirements>
<Dependencies>
<Dependency>
@ -42,7 +42,7 @@
<Version>1.00.00</Version>
</Service>
<Package>ResourceManager-stubs</Package>
<Version>1.00.00</Version>
<Version>1.0.3</Version>
<Scope level="GHN"/>
<Optional>false</Optional>
</Dependency>
@ -68,7 +68,7 @@
<Software>
<Description>Stubs for ResourceManager: provide facilities to interact with a ResourceManager instance</Description>
<Name>ResourceManager-stubs</Name>
<Version>1.0.0</Version>
<Version>1.0.3</Version>
<MultiVersion value="true"/>
<Mandatory level="GHN"/>
<Shareable level="VO"/>
@ -80,7 +80,7 @@
<Software>
<Description>Test-suite for ResourceManager: provide sample usages of interaction with a ResourceManager instance</Description>
<Name>ResourceManager-test-suite</Name>
<Version>1.0.0</Version>
<Version>1.0.3</Version>
<MultiVersion value="true"/>
<Shareable level="VO"/>
<Type>application</Type>

View File

@ -12,6 +12,7 @@ import org.gcube.common.core.scope.GCUBEScopeNotSupportedException;
import org.gcube.common.core.scope.GCUBEScope.MalformedScopeExpressionException;
import org.gcube.common.core.scope.GCUBEScopeManager.IllegalScopeException;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.brokerage.BrokerConnector;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.contexts.StatefulPortTypeContext;
import org.gcube.vremanagement.resourcemanager.impl.deployment.DeployerReport;
@ -34,11 +35,11 @@ import org.gcube.vremanagement.resourcemanager.impl.operators.DisposeScopeOperat
import org.gcube.vremanagement.resourcemanager.impl.operators.OperatorConfig;
import org.gcube.vremanagement.resourcemanager.impl.operators.RemoveResourcesOperator;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.state.ResourceReport;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
import org.gcube.vremanagement.resourcemanager.impl.state.PublishedScopeResource;
import org.gcube.vremanagement.resourcemanager.impl.state.InstanceState;
import org.gcube.vremanagement.resourcemanager.impl.state.PublishedScopeResource.UnknownScopeOptionException;
import org.gcube.vremanagement.resourcemanager.impl.state.ResourceReport.OPERATION;
import org.gcube.vremanagement.resourcemanager.impl.state.Session.OPERATION;
import org.globus.wsrf.NoSuchResourceException;
import org.globus.wsrf.ResourceException;
@ -67,19 +68,19 @@ public class ResourceManager extends GCUBEPortType {
* Adds a new group of {@link ScopedResource}s to the managed Scope
*
* @param resourcesList the resources to join
* @return the ID assigned to the operation, it can be used to retrieve the resource report by invoking the {@link ResourceManager#getReport(String)} operation
* @return the ID assigned to the operation, it can be used to retrieve the resource session by invoking the {@link ResourceManager#getReport(String)} operation
* @throws GCUBEFault if the operation fails
*/
public synchronized String addResources(AddResourcesParameters resourceList) throws ResourcesCreationFaultType, GCUBEFault {
logger.debug("AddResources operation invoked");
logger.debug("AddResources operation invoked in scope " + ServiceContext.getContext().getScope().getName());
try {
//checks the input scope
GCUBEScope targetScope = this.validateOperationScope(resourceList.getTargetScope());
ResourceReport report = new ResourceReport(UUIDGenFactory.getUUIDGen().nextUUID(),OPERATION.AddResources, targetScope);
this.getResource().addReport(report);
Session report = new Session(UUIDGenFactory.getUUIDGen().nextUUID(),OPERATION.AddResources, targetScope);
this.getResource().addSession(report);
new AddResourcesOperator(new OperatorConfig(report, this.getResource().getResourceList(), targetScope),resourceList).run();
//resource.publish();
//returns the report ID, it can be used to invoke the getReport operation
//returns the session ID, it can be used to invoke the getReport operation
return report.getId();
} catch (IllegalScopeException ise){
logger.error("The target scope (" + resourceList.getTargetScope() + ") is not valid or null or not joined to this instance", ise);
@ -100,8 +101,8 @@ public class ResourceManager extends GCUBEPortType {
try {
GCUBEScope targetScope = this.validateOperationScope(resourceList.getTargetScope());
ResourceReport report = new ResourceReport(UUIDGenFactory.getUUIDGen().nextUUID(), OPERATION.RemoveResources, targetScope);
this.getResource().addReport(report);
Session report = new Session(UUIDGenFactory.getUUIDGen().nextUUID(), OPERATION.RemoveResources, targetScope);
this.getResource().addSession(report);
new RemoveResourcesOperator(new OperatorConfig(report, this.getResource().getResourceList(), targetScope),resourceList).run();
return report.getId();
} catch (IllegalScopeException ise){
@ -132,8 +133,8 @@ public class ResourceManager extends GCUBEPortType {
throw new InvalidScopeFaultType();
}
try {
ResourceReport report = new ResourceReport(UUIDGenFactory.getUUIDGen().nextUUID(), OPERATION.Dispose,GCUBEScope.getScope(params.getName()));
this.getResource().addReport(report);
Session report = new Session(UUIDGenFactory.getUUIDGen().nextUUID(), OPERATION.Dispose,GCUBEScope.getScope(params.getName()));
this.getResource().addSession(report);
new DisposeScopeOperator(new OperatorConfig(report, this.getResource().getResourceList(), GCUBEScope.getScope(params.getName()))).run();
this.getResource().getPublishedScopeResource().dismiss();
return report.getId();
@ -207,25 +208,25 @@ public class ResourceManager extends GCUBEPortType {
}
/**
* Receives a deployment report. It is called by the Deployer services on the GHNs contacted within the {@link #addResources(AddResourcesParameters)}
* Receives a deployment session. It is called by the Deployer services on the GHNs contacted within the {@link #addResources(AddResourcesParameters)}
* operation
*
* @param report the resource report
* @throws GCUBEFault if the report does not have a valid serialization
* @param session the resource session
* @throws GCUBEFault if the session does not have a valid serialization
*/
public void sendReport(SendReportParameters reportMessage) throws GCUBEFault {
logger.info("Received report for session " + reportMessage.getCallbackID());
logger.info("Received session for session " + reportMessage.getCallbackID());
logger.trace("Report content: \n" + reportMessage.getReport());
try {
ResourceReport report = this.getResource().getReport(reportMessage.getCallbackID());
Session session = this.getResource().getSession(reportMessage.getCallbackID());
DeployerReport dreport = new DeployerReport(reportMessage.getReport());
report.addGHNReport(dreport);
report.save();
session.addGHNReport(dreport);
session.save();
PublishedScopeResource resource = this.getResource().getPublishedScopeResource();
logger.debug("Status report is: " + dreport.getStatus());
logger.debug("Status session is: " + dreport.getStatus());
if (dreport.getStatus().compareToIgnoreCase("CLOSED") == 0) {
logger.trace("Setting the gHN " + dreport.getGHNID() + " as non working");
//if the report is closed, declare the node as "non working" node
//if the session is closed, declare the node as "non working" node
VirtualNodeManager.getNode(dreport.getGHNID(), this.getResource().getManagedScope()).isNotWorking();
logger.trace("Parsing running instances (if any)...");
Set<ScopedResource> resources = new HashSet<ScopedResource>();
@ -238,12 +239,19 @@ public class ResourceManager extends GCUBEPortType {
logger.warn("Instance " + instance.getRIID() + " not found on the IS");
}
}
report.addDeployedInstances(dreport.getInstances());
session.addDeployedInstances(dreport.getInstances());
//add the newly generated RIs to the Scope State
this.getResource().getResourceList().addResources(resources);
}
resource.publish();
report.save();
session.save();
// //send feedback to the broker if needed
// if ((session.isReportClosed()
// && ((session.getOperation()==OPERATION.AddResources)
// || (session.getOperation()==OPERATION.UpdateResources)
// || (session.getOperation()==OPERATION.Create)))) {
// this.updateBroker(session);
// }
} catch (NoSuchResourceException e) {
logger.error("Unable to find ResourceManager resource", e);
@ -259,19 +267,36 @@ public class ResourceManager extends GCUBEPortType {
/**
* Gets a Resource Report
*
* @param ID the report identifier
* @return the string serialization of the report
* @throws GNoSuchReportFaultTypeCUBEFault if the report is not found or does not have a valid serialization
* @param ID the session identifier
* @return the string serialization of the session
* @throws GNoSuchReportFaultTypeCUBEFault if the session is not found or does not have a valid serialization
*/
public String getReport(String ID) throws NoSuchReportFaultType {
try {
return this.getResource().getReport(ID).toXML();
return this.getResource().getSession(ID).toXML();
} catch (Exception e) {
logger.error("Unable to retrieve the Resource Report for ID " + ID,e);
throw new NoSuchReportFaultType();
}
}
// /**
// * Sends the feedback on the deployment activity to the Broker
// * @param services the Resource Report
// * @param reports
// */
// private void updateBroker(Session session) {
// if (session.getServices().size()>0) {
// try {
// logger.info("Sending feedback to the Broker");
// BrokerConnector.getBroker(this.getResource().getManagedScope()).sendFeedback(session);
// } catch (Exception e) {
// logger.error("Can't send feedback to the Broker", e);
// }
// }
// }
/**
* Validates the input scope of each PublishedScopeResource operation
*

View File

@ -1,9 +1,11 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
*
@ -23,18 +25,19 @@ public interface Broker {
public void initialize(GCUBEScope scope) throws Exception;
/**
* Creates a deployment plan
* Creates a deployment plan for the given services
* @param session the current session
* @param services the services to deploy
* @param suggestedGHNs the GHNs suggested for the deployment, if specified, only these nodes will be used by the planner
* @param suggestedGHNs the (eventually) GHNs suggested for the deployment, if specified, only these nodes will be used by the planner
* @throws Exception if the preparation of the plan fails
*/
public void makePlan(Set<ScopedDeployedService> services, String[] suggestedGHNs) throws Exception;
public void makePlan(Session session, Set<ScopedDeployedService> services, String[] suggestedGHNs) throws Exception;
/**
* Sends feedback to the broker about the execution of the plan
* @param services the services belonging the plan
* Sends feedback to the broker about the execution of the plan for the given session
* @param session the current session
* @throws Exception if the broker is not able to manage the feedback
*/
public void sendFeedback(Set<ScopedDeployedService> services) throws Exception;
public void sendFeedback(Session session) throws Exception;
}

View File

@ -7,7 +7,8 @@ import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
/**
* Locates and connects to the current scope the Broker to use for services' deployment
* Locates and initializes the Broker to use for services' deployment. A Broker is a component capable to create a plan
* for allocating gCube packages to gHNs
*
* @author Manuele Simi (ISTI-CNR)
*
@ -18,6 +19,12 @@ public class BrokerConnector {
private static final GCUBELog logger = new GCUBELog(BrokerConnector.class);
/**
* Returns the broker to use in the given scope
* @param scope
* @return
* @throws Exception
*/
public static Broker getBroker(GCUBEScope scope) throws Exception {
Broker broker = null;
try {
@ -50,4 +57,4 @@ public class BrokerConnector {
Constructor<?> constructor = clazz.getConstructor(new Class[] {});
return (Broker) constructor.newInstance(new Object[]{});
}
}
}

View File

@ -7,10 +7,12 @@ import java.util.Set;
import org.apache.axis.types.URI.MalformedURIException;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNodeManager;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
*
@ -40,7 +42,7 @@ public class InternalBroker implements Broker {
/**
* {@inheritDoc}
*/
public void makePlan(Set<ScopedDeployedService> services, String[] suggestedGHNs) throws Exception {
public void makePlan(Session session, Set<ScopedDeployedService> services, String[] suggestedGHNs) throws Exception {
this.suggestedGHNs = suggestedGHNs;
for (ScopedDeployedService service : services) {
try {
@ -54,11 +56,7 @@ public class InternalBroker implements Broker {
}
}
/**
* {@inheritDoc}
*/
public void sendFeedback(Set<ScopedDeployedService> services) throws Exception {/* feedback is not managed by this broker*/}
/** Selects a target node for the deployment
*
* @param service the service to deploy
@ -68,12 +66,16 @@ public class InternalBroker implements Broker {
private void assignTargetGHN(ScopedDeployedService service) throws org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException {
if ( (service.getSourceService().getGHN() != null) && (service.getSourceService().getGHN().compareToIgnoreCase("") != 0)) {
//a specific GHN has been requested
logger.info("A specific GHN (" + service.getSourceService().getGHN() + ") has been requested by the caller for " + service);
service.setTargetGHN(VirtualNodeManager.getNode(service.getSourceService().getGHN(),this.scope));
logger.info("A specific GHN (" + service.getSourceService().getGHN() + ") has been requested by the caller for " + service);
VirtualNode node = VirtualNodeManager.getNode(service.getSourceService().getGHN(),this.scope);
node.setWorkingScope(this.scope);
service.setTargetGHN(node);
} else if (this.suggestedGHNs.length > 0) {
//a set of target GHNs has been requested, assign one of them with a round robin
logger.info("A set of target GHNs " + Arrays.toString(this.suggestedGHNs)+" has been requested by the caller for " + service);
service.setTargetGHN(VirtualNodeManager.getNode(this.suggestedGHNs[this.nodewalker++ % this.suggestedGHNs.length],this.scope));
VirtualNode node = VirtualNodeManager.getNode(this.suggestedGHNs[this.nodewalker++ % this.suggestedGHNs.length],this.scope);
node.setWorkingScope(this.scope);
service.setTargetGHN(node);
} else {
logger.info("no GHN has been specified as explicit target");
//no GHN has been specified as explicit target
@ -81,5 +83,12 @@ public class InternalBroker implements Broker {
}
}
/**
* {@inheritDoc}
*/
public void sendFeedback(Session session) throws Exception {
/* feedback is not managed by this broker*/
}
}

View File

@ -15,10 +15,12 @@ import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcebroker.stubs.ResourceBrokerPortType;
import org.gcube.vremanagement.resourcebroker.stubs.service.ResourceBrokerServiceAddressingLocator;
import org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.Feedback;
import org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.PlanParser;
import org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.PlanRequest;
import org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.PlanResponse;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
*
@ -51,18 +53,15 @@ public final class ServiceBroker implements Broker {
logger.info("Broker instances found: #" + this.instances.size());
}
public void makePlan(Set<ScopedDeployedService> services, String[] suggestedGHNs) throws Exception {
public void makePlan(Session session, Set<ScopedDeployedService> services, String[] suggestedGHNs) throws Exception {
String request = PlanRequest.create(services, suggestedGHNs, scope);;
logger.debug("Request for the Broker \n" + request);
ResourceBrokerPortType pt = null;
String plan = null;
for (GCUBERunningInstance instance : this.instances) {
EndpointReferenceType endpoint = instance.getAccessPoint().getEndpoint("gcube/vremanagement/ResourceBroker");
logger.debug("Querying broker instance at " + endpoint.getAddress());
try {
pt = new ResourceBrokerServiceAddressingLocator().getResourceBrokerPortTypePort(endpoint);
pt = GCUBERemotePortTypeContext.getProxy(pt, this.scope, TIMEOUT, ServiceContext.getContext());
plan = pt.getPlan(request);
try {
plan = this.getBrokerPT(endpoint).getPlan(request);
logger.debug("Plan received from the broker \n" + plan);
break;
} catch (Exception e) {
@ -70,13 +69,27 @@ public final class ServiceBroker implements Broker {
continue;
}
}
PlanResponse.parse(plan, services, scope);
PlanParser.parse(plan, services, scope);
session.setDeploymentPlan(plan);
}
public void sendFeedback(Set<ScopedDeployedService> services)
throws Exception {
/**
* {@inheritDoc}
*/
public void sendFeedback(Session session) throws Exception {
String feedback = Feedback.create(session);
logger.debug("Feedback for the Broker \n" + feedback);
for (GCUBERunningInstance instance : this.instances) {
EndpointReferenceType endpoint = instance.getAccessPoint().getEndpoint("gcube/vremanagement/ResourceBroker");
logger.debug("Sending broker feeback to " + endpoint.getAddress());
try {
this.getBrokerPT(endpoint).handleFeedback(feedback);
break;
} catch (Exception e) {
logger.error("Unable to contact the Resource Broker instance located at " + endpoint.getAddress(), e);
continue;
}
}
}
@ -95,4 +108,10 @@ public final class ServiceBroker implements Broker {
}
private ResourceBrokerPortType getBrokerPT(EndpointReferenceType endpoint) throws Exception {
ResourceBrokerPortType pt = new ResourceBrokerServiceAddressingLocator().getResourceBrokerPortTypePort(endpoint);
pt = GCUBERemotePortTypeContext.getProxy(pt, this.scope, TIMEOUT, ServiceContext.getContext());
return pt;
}
}

View File

@ -0,0 +1,63 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker;
import java.io.IOException;
import java.util.Set;
import org.gcube.vremanagement.resourcebroker.utils.serialization.parser.xstream.XStreamTransformer;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageGroup;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PlanResponse;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.feedback.DeployNode;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.feedback.FeedbackStatus;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
*
* Feedback for deployment plans. It uses the serialization API provided by the Broker Service
* to create the feedback information.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class Feedback {
/**
* Creates the feedback information for the Broker Service
* @param session the current session
* @return the XML representation of the feedback information
*/
@SuppressWarnings("deprecation")
public static String create(Session session) throws IOException {
Set<ScopedDeployedService> services = session.getServices();
XStreamTransformer transformer = new XStreamTransformer();
PlanResponse resp = transformer.getResponseFromXML(session.getDeploymentPlan(), false);
org.gcube.vremanagement.resourcebroker.utils.serialization.types.feedback.Feedback fb =
new org.gcube.vremanagement.resourcebroker.utils.serialization.types.feedback.Feedback();
fb.setPlanID(resp.getKey());
fb.setScope(resp.getScope());
for (PackageGroup group : resp.getPackageGroups()) {
ScopedDeployedService service = null;
for (ScopedDeployedService s : services) {
if (s.getId().compareToIgnoreCase(group.getServiceName()) == 0) {
service = s;
break;
}
}
//set the status of each package elemnt
for (org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageElem p : group.getPackages()) {
if (service == null)
p.setStatus(FeedbackStatus.FAILED);
else if (service.isSuccess())
p.setStatus(FeedbackStatus.SUCCESS);
else //this has to be improved by using the PARTIAL state?
p.setStatus(FeedbackStatus.FAILED);
}
DeployNode pgToAdd = new DeployNode(group);
fb.addDeployNode(pgToAdd);
}
return transformer.toXML(fb);
}
}

View File

@ -0,0 +1,70 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker;
import java.io.IOException;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcebroker.utils.serialization.parser.xstream.XStreamTransformer;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageGroup;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PlanResponse;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNodeManager;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
/**
*
* Parser for deployment plans. It uses the Serialization API provided by the Broker Service
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class PlanParser {
private static final GCUBELog logger = new GCUBELog(PlanParser.class);
/**
* Parses the current plan and assigns gHNs to services
* @param plan the plan returned by the Broker
* @param services the services to deploy
* @param scope the current scope
* @throws IOException
*/
public static void parse(String plan, Set<ScopedDeployedService> services, GCUBEScope scope) throws IOException {
XStreamTransformer transformer = new XStreamTransformer();
PlanResponse resp = transformer.getResponseFromXML(plan, false);
if (resp.getStatus().getStatus().compareToIgnoreCase("FAILED")==0) {
logger.error("The creation of the Deployment Plan failed. Broker says: " + resp.getStatus().getMsg());
throw new IOException ("Broker says: " + resp.getStatus().getMsg());
} else if (resp.getStatus().getStatus().compareToIgnoreCase("SUCCESS")==0) {
logger.info("The creation of the Deployment Plan was successful");
}
//assing ghns to services
for (PackageGroup group: resp.getPackageGroups()) {
String serviceID = group.getServiceName();
String ghnID = group.getGHN();
if (ghnID == null) {
logger.error("no gHN was assigned to service " + serviceID);
throw new IOException("no gHN was assigned to service " + serviceID);
}
for (ScopedDeployedService service : services) {
if (service.getId().compareToIgnoreCase(serviceID) == 0) {
logger.info("Assigning gHN " + ghnID + " to " +service);
VirtualNode node = null;
try {
node = VirtualNodeManager.getNode(ghnID,scope);
} catch (NoGHNFoundException e) {
logger.error("unable to find gHN " + ghnID + " returned by the Broker");
throw new IOException("unable to find gHN " + ghnID + " returned by the Broker");
}
node.setWorkingScope(scope);
service.setTargetGHN(node);
break;
}
}
}
}
}

View File

@ -1,80 +1,51 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Dependency;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.kxml2.io.KXmlSerializer;
import org.gcube.vremanagement.resourcebroker.utils.serialization.parser.xstream.XStreamTransformer;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageElem;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageGroup;
/**
*
* Creates a plan request with the Serialization API provided by the Broker Service
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class PlanRequest {
public static String create(Set<ScopedDeployedService> services, String[] suggestedGHNs, GCUBEScope scope) throws IOException {
StringWriter request = new StringWriter();
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(request);
serializer.startDocument("UTF-8", true);
serializer.setPrefix("", "http://gcube-system.org/namespaces/resourcebroker/broker/xsd/deployRequest");
serializer.startTag(null,"PlanRequest");
serializer.startTag(null,"Scope").text(scope.toString()).endTag(null,"Scope");
// for each service, a section like this:
// <PackageGroup service="service1">
// <Package reuse="true">
// <ServiceClass>PkgServiceClass</ServiceClass>
// <ServiceName>PkgServiceName</ServiceName>
// <ServiceVersion>PkgServiceVersion</ServiceVersion>
// <PackageName>PkgPackageName</PackageName>
// <PackageVersion>PkgPackageVersion</PackageVersion>
// </Package>
// <Package reuse="true">
// <ServiceClass>PkgServiceClass2</ServiceClass>
// <ServiceName>PkgServiceName2</ServiceName>
// <ServiceVersion>PkgServiceVersion2</ServiceVersion>
// <PackageName>PkgPackageName2</PackageName>
// <PackageVersion>PkgPackageVersion2</PackageVersion>
// </Package>
// <GHN>d5a5af20-ac50-11de-a928-ab32081f9f00</GHN>
// </PackageGroup>
for (ScopedDeployedService service : services) {
serializer.startTag(null,"PackageGroup").attribute(null, "service", service.getId());
for (Dependency dep : service.getResolvedDependencies()) {
serializer.startTag(null,"Package").attribute(null, "reuse", "false");
serializer.startTag(null,"ServiceClass").text(dep.getService().getClazz()).endTag(null,"ServiceClass");
serializer.startTag(null,"ServiceName").text(dep.getService().getName()).endTag(null,"ServiceName");
serializer.startTag(null,"ServiceVersion").text(dep.getService().getVersion()).endTag(null,"ServiceVersion");
serializer.startTag(null,"PackageName").text(dep.getName()).endTag(null,"PackageName");
serializer.startTag(null,"PackageVersion").text(dep.getVersion()).endTag(null,"PackageVersion");
serializer.endTag(null,"Package");
}
if (service.getSourceService().getGHN() != null)
serializer.startTag(null,"GHN").text(service.getSourceService().getGHN()).endTag(null, "GHN");
serializer.endTag(null,"PackageGroup");
}
//GHNLIST
/**
* Creates the request plan for the Broker Service
* @param services the services to deploy
* @param suggestedGHNs the GHNs suggested for the deployment
* @param scope the scope of the request
* @thrown {@link IOException} if the request cannot be created
* @return the XML representation of the request
*
*/
public static String create(Set<ScopedDeployedService> services, String[] suggestedGHNs, GCUBEScope scope) throws IOException {
org.gcube.vremanagement.resourcebroker.utils.serialization.types.PlanRequest planReq = new org.gcube.vremanagement.resourcebroker.utils.serialization.types.PlanRequest(scope.toString());
if (suggestedGHNs != null) {
serializer.startTag(null,"GHNList");
for (ScopedDeployedService service : services) {
PackageGroup group = planReq.createPackageGroup( service.getId());
for (Dependency dep : service.getLastResolvedDependencies()) {
group.addPackage(new PackageElem(false, dep.getService().getClazz(), dep.getService().getName(),
dep.getService().getVersion(), dep.getName(), dep.getVersion()));
if (service.getSourceService().getGHN() != null)
group.setGHN(service.getSourceService().getGHN());
}
}
if (suggestedGHNs != null) {
for (String ghn : suggestedGHNs)
serializer.startTag(null,"GHN").text(ghn).endTag(null, "GHN");
serializer.endTag(null,"GHNList");
}
serializer.endTag(null,"PlanRequest");
return request.toString();
planReq.getGHNList().addGHN(ghn);
}
XStreamTransformer transformer = new XStreamTransformer();
return transformer.toXML(planReq);
}
public static void main(String[] args) {
try {
System.out.println(create(new HashSet<ScopedDeployedService>(), new String[] {"ID"}, GCUBEScope.getScope("/gcube")));
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,80 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.kxml;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
import java.util.Set;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.deployment.DeployerReport;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
import org.kxml2.io.KXmlParser;
import org.kxml2.io.KXmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
/**
*
* Feedback for deployment plans. It uses the KXML library to create the feedback information.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class KFeedback {
protected static final GCUBELog logger = new GCUBELog(KFeedback.class);
/**
* Creates the feedback information for the Broker Service
* @param session the current session
* @return the XML representation of the feedback information
* @throws IOException if the feedback information cannot be created
*/
public static String create(Session session) throws IOException {
Map<String, DeployerReport> reports = session.getAllGHNReports();
Set<ScopedDeployedService> services = session.getServices();
KXmlParser parser = new KXmlParser();
try {
parser.setInput(new BufferedReader(new StringReader(session.getDeploymentPlan())));
} catch (XmlPullParserException e) {
logger.error("Unable to parse the Deployment Plan", e);
throw new IOException ("Unable to parse the Deployment Plan");
}
StringWriter feedbackRequest = new StringWriter();
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(feedbackRequest);
serializer.startDocument("UTF-8", true);
serializer.setPrefix("", "http://gcube-system.org/namespaces/resourcebroker/broker/xsd/deployFeedback");
serializer.startTag(null,"KFeedback").attribute(null, "planID", getPlanID(parser));;
serializer.startTag(null,"Scope").text(session.getScope().toString()).endTag(null,"Scope");
for (String ghnid : reports.keySet()) {
serializer.startTag(null,"DeployNode");
//TODO: to complete
serializer.startTag(null,"GHN").text(ghnid).endTag(null, "GHN");
serializer.endTag(null,"DeployNode");
}
serializer.endTag(null,"KFeedback");
return feedbackRequest.toString();
}
private static String getPlanID(KXmlParser parser) throws IOException {
String id = "";
loop: while (true) {
try {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("PlanResponse")) id = parser.getAttributeValue(null, "deployID");
break loop;
case KXmlParser.END_DOCUMENT: break loop;
}
} catch (Exception e) {
logger.error("Unable to parse the Deployment Plan", e);
throw new IOException ("The creation of the Deployment Plan failed. " + e.getMessage());
}
}
return id;
}
}

View File

@ -1,4 +1,4 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker;
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.kxml;
import java.io.BufferedReader;
import java.io.IOException;
@ -7,16 +7,31 @@ 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.deployment.VirtualNode;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNodeManager;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParserException;
public class PlanResponse {
/**
*
* Parser for deployment plans. It uses the KXML library to parse the plan.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class KPlanParser {
protected static final GCUBELog logger = new GCUBELog(PlanResponse.class);
private static final GCUBELog logger = new GCUBELog(KPlanParser.class);
/**
* Parses the current plan and assigns gHNs to services
* @param plan the plan returned by the Broker
* @param services the services to deploy
* @param scope the current scope
* @throws IOException
*/
public static void parse(String plan, Set<ScopedDeployedService> services, GCUBEScope scope) throws IOException {
KXmlParser parser = new KXmlParser();
try {
@ -91,11 +106,12 @@ public class PlanResponse {
for (ScopedDeployedService service : services) {
if (service.getId().compareToIgnoreCase(serviceID) == 0) {
logger.info("Assigning gHN " + ghnID + " to " +service);
service.setTargetGHN(VirtualNodeManager.getNode(ghnID,scope));
VirtualNode node = VirtualNodeManager.getNode(ghnID,scope);
node.setWorkingScope(scope);
service.setTargetGHN(node);
break;
}
}
}
}
}

View File

@ -0,0 +1,110 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.kxml;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Dependency;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.kxml2.io.KXmlSerializer;
/**
*
* Creates a plan request with the KXML library to create the deployment plan request.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class KPlanRequest {
/**
* Creates the request plan for the Broker Service
*
* @param services
* the services to deploy
* @param suggestedGHNs
* the GHNs suggested for the deployment
* @param scope
* the scope of the request
* @thrown {@link IOException} if the request cannot be created
* @return the XML representation of the request
*
*/
public static String create(Set<ScopedDeployedService> services,
String[] suggestedGHNs, GCUBEScope scope) throws IOException {
StringWriter request = new StringWriter();
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(request);
serializer.startDocument("UTF-8", true);
serializer.setPrefix("","http://gcube-system.org/namespaces/resourcebroker/broker/xsd/deployRequest");
serializer.startTag(null, "PlanRequest");
serializer.startTag(null, "Scope").text(scope.toString()).endTag(null,"Scope");
// for each service, prepare a section like this:
// <PackageGroup service="service1">
// <Package reuse="true">
// <ServiceClass>PkgServiceClass</ServiceClass>
// <ServiceName>PkgServiceName</ServiceName>
// <ServiceVersion>PkgServiceVersion</ServiceVersion>
// <PackageName>PkgPackageName</PackageName>
// <PackageVersion>PkgPackageVersion</PackageVersion>
// </Package>
// <Package reuse="true">
// <ServiceClass>PkgServiceClass2</ServiceClass>
// <ServiceName>PkgServiceName2</ServiceName>
// <ServiceVersion>PkgServiceVersion2</ServiceVersion>
// <PackageName>PkgPackageName2</PackageName>
// <PackageVersion>PkgPackageVersion2</PackageVersion>
// </Package>
// <GHN>d5a5af20-ac50-11de-a928-ab32081f9f00</GHN>
// </PackageGroup>
for (ScopedDeployedService service : services) {
serializer.startTag(null, "PackageGroup").attribute(null,
"service", service.getId());
for (Dependency dep : service.getLastResolvedDependencies()) {
serializer.startTag(null, "Package").attribute(null, "reuse",
"false");
serializer.startTag(null, "ServiceClass").text(
dep.getService().getClazz()).endTag(null,
"ServiceClass");
serializer.startTag(null, "ServiceName").text(
dep.getService().getName()).endTag(null, "ServiceName");
serializer.startTag(null, "ServiceVersion").text(
dep.getService().getVersion()).endTag(null,
"ServiceVersion");
serializer.startTag(null, "PackageName").text(dep.getName())
.endTag(null, "PackageName");
serializer.startTag(null, "PackageVersion").text(
dep.getVersion()).endTag(null, "PackageVersion");
serializer.endTag(null, "Package");
}
if (service.getSourceService().getGHN() != null)
serializer.startTag(null, "GHN").text(service.getSourceService().getGHN()).endTag(null, "GHN");
serializer.endTag(null, "PackageGroup");
}
// GHNLIST
if (suggestedGHNs != null) {
serializer.startTag(null, "GHNList");
for (String ghn : suggestedGHNs)
serializer.startTag(null, "GHN").text(ghn).endTag(null, "GHN");
serializer.endTag(null, "GHNList");
}
serializer.endTag(null, "PlanRequest");
return request.toString();
}
public static void main(String[] args) {
try {
System.out.println(create(new HashSet<ScopedDeployedService>(),
new String[] { "ID" }, GCUBEScope.getScope("/gcube")));
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -116,8 +116,8 @@ public final class SoftwareRepositoryRequest {
loop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("ResolvedDependencies")) this.parseResolvedDependencies(parser, service.getResolvedDependencies());
if (parser.getName().equals("MissingDependencies")) this.parseMissingDependencies(parser, service.getMissingDependencies());
if (parser.getName().equals("ResolvedDependencies")) this.parseResolvedDependencies(parser, service);
if (parser.getName().equals("MissingDependencies")) this.parseMissingDependencies(parser, service);
break;
case KXmlParser.END_DOCUMENT:
break loop;
@ -164,8 +164,7 @@ public final class SoftwareRepositoryRequest {
* @return the dependency
* @throws Exception
*/
private Dependency parseDependency(KXmlParser parser) throws Exception {
logger.trace("Parsing a resolved or missing dependency...");
private Dependency parseDependency(KXmlParser parser) throws Exception {
Dependency p = new Dependency();
loop: while (true) {
switch (parser.next()) {
@ -184,12 +183,16 @@ public final class SoftwareRepositoryRequest {
return p;
}
private void parseResolvedDependencies(KXmlParser parser, List<Dependency> listResolvedDeps) throws Exception {
private void parseResolvedDependencies(KXmlParser parser, ScopedDeployedService service) throws Exception {
logger.trace("Parsing resolved dependencies...");
List<Dependency> resolved = new ArrayList<Dependency>();
loop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("Dependency")) listResolvedDeps.add(this.parseDependency(parser));
if (parser.getName().equals("Dependency")) {
logger.trace("Dependency found");
resolved.add(this.parseDependency(parser));
} break;
case KXmlParser.END_TAG:
if (parser.getName().equals("ResolvedDependencies")) break loop;
break;
@ -197,15 +200,20 @@ public final class SoftwareRepositoryRequest {
throw new Exception("Parsing failed at ResolvedDependencies");
}
}
logger.trace("Number of deps found: " + resolved.size());
service.setResolvedDependencies(resolved);
}
private void parseMissingDependencies(KXmlParser parser, List<Dependency> listMissingDeps) throws Exception {
private void parseMissingDependencies(KXmlParser parser, ScopedDeployedService service) throws Exception {
logger.trace("Parsing missing dependencies...");
List<Dependency> missing = new ArrayList<Dependency>();
loop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("MissingDependency")) listMissingDeps.add(this.parseDependency(parser));
if (parser.getName().equals("MissingDependency")) {
logger.trace("Dependency found");
missing.add(this.parseDependency(parser));
} break;
case KXmlParser.END_TAG:
if (parser.getName().equals("MissingDependencies")) break loop;
break;
@ -213,6 +221,8 @@ public final class SoftwareRepositoryRequest {
throw new Exception("Parsing failed at MissingDependencies");
}
}
logger.trace("Number of deps found: " + missing.size());
service.setMissingDependencies(missing);
}
/**

View File

@ -49,7 +49,7 @@ public class VirtualNode {
private static final String DEPLOYER_PT_NAME = "/wsrf/services/gcube/common/vremanagement/Deployer";
//if we do not receive a deployment report from the node after one hour, we assume that the node is not working anymore
//if we do not receive a deployment session from the node after one hour, we assume that the node is not working anymore
private static final long MAX_ACTIVITY = 3600 * 1000; //1h in milliseconds
protected VirtualNode(String ID, GCUBEScope scope, String ... name) throws NoGHNFoundException {
@ -165,12 +165,13 @@ public class VirtualNode {
scope, ServiceContext.getContext());
pt.deploy(param);
this.packagesToAdd.clear();
isWorking = true;//this will prevent further requests to the ghn until the deployment report is received back
isWorking = true;//this will prevent further requests to the ghn until the deployment session is received back
this.lastActivity = System.currentTimeMillis();
}
/**
* Undeploys the packages from the node
* @param scope the scope to use for the undeployment
*
* @throws Exception if the operation fails
*/
@ -192,12 +193,12 @@ public class VirtualNode {
params.setEndpointReference(callbackEPR);
EndpointReferenceType nodeEPR = new EndpointReferenceType();
nodeEPR.setAddress(new Address("http://" + this.name + DEPLOYER_PT_NAME));
logger.trace("Undeploying from " + nodeEPR.toString());
logger.trace("Undeploying from " + nodeEPR.toString() + " in scope " + scope);
DeployerPortType pt = GCUBERemotePortTypeContext.getProxy(new DeployerServiceAddressingLocator().getDeployerPortTypePort(nodeEPR),
scope, ServiceContext.getContext());
pt.undeploy(params);
this.packagesToRemove.clear();
isWorking = true;//this will prevent further requests to the ghn until the deployment report is received back
isWorking = true;//this will prevent further requests to the ghn until the deployment session is received back
this.lastActivity = System.currentTimeMillis();
}
@ -267,14 +268,27 @@ public class VirtualNode {
}
/**
* Assigns a working scope to the node
* @param scope the scope to set
*/
public void setScope(GCUBEScope scope) {
public void setWorkingScope(GCUBEScope scope) {
this.scope = scope;
}
/**
* Gets the packages scheduled for the next deployment on this node
* @return the set of packages
*/
public Set<PackageInfo> getScheduledPackages() {
return this.packagesToAdd;
}
/**
* Gets the current scope used on this node
* @return the current scope
*/
public GCUBEScope getWorkingScope() {
return this.scope;
}
}

View File

@ -1,34 +1,53 @@
package org.gcube.vremanagement.resourcemanager.impl.deployment;
import java.util.HashMap;
import java.util.Map;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException;
/**
*
* Manager for {@link VirtualNode}s
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class VirtualNodeManager {
/** maps ghn ID to the related virtual node*/
private static Map<String, VirtualNode> nodes; // = new HashMap<String, VirtualNode>();
private static Map<String, VirtualNode> nodes;
/**
* Gets or builds the VirtualNode
* @param callback ID the callback identifier to send to the Deployer
* @param ID the node identifier
* @param scope the deployment scope
* @param name the node name (format has to be <i>host:port</i>)
* @return the Virtual Node
* @throws NoGHNFoundException
* @throws NoGHNFoundException if the node does not exist
*/
public static VirtualNode getNode(String ID, GCUBEScope scope, String ... name) throws NoGHNFoundException {
checkNodes();
if (!nodes.containsKey(ID)) {
nodes.put(ID,new VirtualNode(ID, scope, name));
}
}
return nodes.get(ID);
}
/**
* Assigns the initial set of nodes to the manager.
* @param nodes the set of nodes
*/
public static void setNodes(Map<String, VirtualNode> nodes) {
VirtualNodeManager.nodes = nodes;
}
/**
* Checks the set of node, must be called before any usage of <code>nodes</code> to check if it has been initialized
*/
private static void checkNodes(){
if (nodes == null)
nodes = new HashMap<String, VirtualNode>();
}
}

View File

@ -73,8 +73,6 @@ public class Dependency {
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Dependency other = (Dependency) obj;
if (name == null) {
if (other.name != null)
@ -84,8 +82,8 @@ public class Dependency {
if (service == null) {
if (other.service != null)
return false;
} else if (!service.equals(other.service))
return false;
} else if (!service.equals(other.service))
return false;
if (version == null) {
if (other.version != null)
return false;

View File

@ -61,8 +61,8 @@ public class AddResourcesOperator extends Operator {
throw new Exception("Unable to manage the given resource(s)", e);
}
}
//save the report
this.configuration.report.save();
//save the session
this.configuration.session.save();
}

View File

@ -10,6 +10,7 @@ import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.queries.GCUBEServiceQuery;
import org.gcube.common.core.resources.GCUBEHostingNode;
import org.gcube.common.core.resources.GCUBEService;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.scope.GCUBEScope.Type;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ServiceItem;
@ -20,6 +21,8 @@ import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedServ
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
import org.gcube.vremanagement.resourcemanager.impl.state.Session.OPERATION;
/**
* A Deployer Operator that contacts the Deployer Services on the target nodes asking for the package deployment
@ -44,7 +47,7 @@ public class DeployServiceOperator extends Operator {
public void exec() throws Exception {
this.configuration.report.save();
this.configuration.session.save();
Set<ScopedDeployedService> servicesToDeploy = new HashSet<ScopedDeployedService>();
Set<ScopedResource> servicesToUndeploy = new HashSet<ScopedResource>();
@ -76,49 +79,90 @@ public class DeployServiceOperator extends Operator {
service.findResource();//resolve the service deps
servicesToDeploy.add(service);
} else {
service.setCallbackID(this.configuration.report.getId());
service.setCallbackID(this.configuration.session.getId());
servicesToUndeploy.add(service);
}
} catch (Exception e) {
logger.warn("Failed to find the service",e);
}
this.configuration.report.addResource(service);
this.configuration.report.addService(service); //for the specific service section
this.configuration.session.addResource(service);
this.configuration.session.addService(service); //for the specific service section
}
//create the Deployment Plan with the Resource Broker
boolean brokerSuccess = true;
try {
if (servicesToDeploy.size() > 0) {
BrokerConnector.getBroker(this.configuration.scope).makePlan(servicesToDeploy, services.getGHN());
this.configuration.report.reportBrokerWork(true, "The Deployment Plan was successfully created");
}
} catch (Exception e) {
brokerSuccess = false;
this.configuration.report.reportBrokerWork(false, e.getMessage());
}
if (brokerSuccess) {
//create the Deployment Plan with the Resource Broker
if ((this.action == ACTION.ADD) && this.allocate(servicesToDeploy)) {
Set<ScopedResource> resourcesToAdd = new HashSet<ScopedResource>();
for (ScopedDeployedService service : servicesToDeploy) {
if (service.getStatus() != STATUS.LOST) {
service.setCallbackID(this.configuration.report.getId());
service.setCallbackID(this.configuration.session.getId());
resourcesToAdd.add(service);
if (this.configuration.scope.getType() == Type.VRE) {
//add also the target gHN to the scope
ScopedResource ghn = ScopedResourceFactory.newResource(service.getTargetGHNID(), GCUBEHostingNode.TYPE, this.configuration.scope);
resourcesToAdd.add(ghn);
this.configuration.report.addResource(ghn);
this.configuration.session.addResource(ghn);
}
}
}
//add the services to the ScopeState (if any)
if(servicesToDeploy.size() > 0) {
this.configuration.scopeState.addResources(resourcesToAdd);
final GCUBEScope tscope = this.configuration.scope;
final Session tsession = this.configuration.session;
//periodically check if the feedback has to be sent to the broker
new Thread() {
@Override
public void run() {
while (true) {
try { Thread.sleep(5000);
} catch (InterruptedException e) {}
//logger.trace("ServiceOperator is checking if the session is closed");
if ((tsession.isReportClosed()
&& ((tsession.getOperation()==OPERATION.AddResources)
|| (tsession.getOperation()==OPERATION.UpdateResources)
|| (tsession.getOperation()==OPERATION.Create)))) {
try {
BrokerConnector.getBroker(tscope).sendFeedback(tsession);
} catch (Exception e) {
logger.error("Failed to send the feedback to the Broker", e);
}
break;
}
}
}
}.start();
}
}
//remove the services from the ScopeState (if any)
if(servicesToUndeploy.size() > 0)
this.configuration.scopeState.removeResources(servicesToUndeploy);
//add/remove the services to/from the ScopeState
if(servicesToDeploy.size() > 0)
configuration.scopeState.addResources(resourcesToAdd);
if(servicesToUndeploy.size() > 0)
configuration.scopeState.removeResources(servicesToUndeploy);
}
this.configuration.report.save();
this.configuration.session.save();
}
/**
* Contacts the broker in order to allocate the given services
* @param servicesToDeploy the services to be deployed
* @return true if each service is correctly allocated, false otherwise
*/
private boolean allocate(Set<ScopedDeployedService> servicesToDeploy) {
try {
if (servicesToDeploy.size() > 0) {
BrokerConnector.getBroker(this.configuration.scope).makePlan(this.configuration.session, servicesToDeploy, services.getGHN());
this.configuration.session.reportBrokerWork(true, "The Deployment Plan was successfully created");
return true;
} else {
logger.warn("The Broker was not contacted. After the dependency resolution phase, there is nothing to deploy");
this.configuration.session.reportBrokerWork(false, "The Broker was not contacted. After the dependency resolution phase, there is nothing to deploy");
return true;
}
} catch (Exception e) {
logger.error("An error occurred when interacting with the broker", e);
this.configuration.session.reportBrokerWork(false, "An error occurred when interacting with the broker " + e.getMessage());
return false;
}
}
}

View File

@ -37,13 +37,13 @@ public class DisposeScopeOperator extends Operator {
&& (resource.getStatus() != STATUS.LOST)
&& (resource.getStatus() != STATUS.REMOVED)){
resources.add(resource);
this.configuration.report.addResource(resource);
this.configuration.session.addResource(resource);
}
}
configuration.scopeState.removeResources(resources);
//TODO: should we also undeploy the RM itself?
this.configuration.report.save();
this.configuration.session.save();
}
}

View File

@ -3,7 +3,7 @@ package org.gcube.vremanagement.resourcemanager.impl.operators;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.state.ScopeState;
import org.gcube.vremanagement.resourcemanager.impl.state.ResourceReport;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
* Basic configuration for every {@link Operator}
@ -13,14 +13,14 @@ import org.gcube.vremanagement.resourcemanager.impl.state.ResourceReport;
*/
public class OperatorConfig {
public final ResourceReport report;
public final Session session;
public final GCUBEScope scope;
public final ScopeState scopeState;
public OperatorConfig(ResourceReport report, ScopeState scopeState, GCUBEScope ... scope) {
this.report = report;
public OperatorConfig(Session report, ScopeState scopeState, GCUBEScope ... scope) {
this.session = report;
this.scopeState = scopeState;
this.scope = (scope!=null && scope.length >0)? scope[0] : ServiceContext.getContext().getScope();
}

View File

@ -35,15 +35,15 @@ public class ScopedResourceManagerOperator extends Operator {
try {
sresource = ScopedResourceFactory.newResource(resource.getID(), resource.getType(), this.configuration.scope);
if (this.action == ACTION.ADD) {
logger.info("Adding resource " + sresource.getId() + " (" + sresource.getType() + ") to scope " + this.configuration.scope.getName());
logger.info("Adding resource " + sresource.getId() + " (" + sresource.getType() + ") to scope " + this.configuration.scope.toString());
toadd.add(sresource);
} else if (this.action == ACTION.REMOVE) {
logger.info("Removing resource " + sresource.getId() + " (" + sresource.getType() + ") from scope " + this.configuration.scope.getName());
logger.info("Removing resource " + sresource.getId() + " (" + sresource.getType() + ") from scope " + this.configuration.scope.toString());
toremove.add(sresource);
}
//add the resource item to the report
this.configuration.report.addResource(sresource);
//add the resource item to the session
this.configuration.session.addResource(sresource);
} catch (Exception e) {
logger.error("Unable to manage the resource",e);
}
@ -53,7 +53,7 @@ public class ScopedResourceManagerOperator extends Operator {
if(toremove.size() > 0)
configuration.scopeState.removeResources(toremove);
this.configuration.report.save();
this.configuration.session.save();
}
}

View File

@ -1,6 +1,7 @@
package org.gcube.vremanagement.resourcemanager.impl.resources;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -45,12 +46,12 @@ public final class ScopedDeployedService extends ScopedResource {
/** missing dependency */
private List<Dependency> missing = new ArrayList<Dependency>();
/** the packages deployed for this service*/
/** the packages deployed for this service*/
private Map <String, List<Dependency>> node2packages = new HashMap<String, List<Dependency>>();
//private Set<PackageInfo> packages = new HashSet<PackageInfo>();
/** the packages deployed for this service*/
private Map <String, List<Dependency>> node2missing = new HashMap<String, List<Dependency>>();
private Service service;
private String lastActivityOnGHN;
@ -58,6 +59,9 @@ public final class ScopedDeployedService extends ScopedResource {
//the target ghn(s)
private List<VirtualNode> virtualNodes = new ArrayList<VirtualNode>();
/** maps node with the scope used when deploying there */
private Map<String, String> node2scope = new HashMap<String, String>();
/** maps RI id with the ghn id (where the instance is deployed on*/
private Map<String, String> ri2ghn = new HashMap<String, String>();
@ -74,20 +78,64 @@ public final class ScopedDeployedService extends ScopedResource {
}
/**
* Gets the list of resolved dependencies when the deployment was performed
* on a specific node
*
* @param ghnid the ID of the node
* @return the resolved dependencies
*/
public List<Dependency> getResolvedDependencies() {
return resolved;
public List<Dependency> getResolvedDependencies(String ghnid) {
return Collections.unmodifiableList(node2packages.get(ghnid));
}
/**
* @return the missing dependencies
/**
* Gets the list of resolved dependencies to be used in the next deployment
*
* @return the resolved dependencies
*/
public List<Dependency> getMissingDependencies() {
return missing;
public List<Dependency> getLastResolvedDependencies() {
return this.resolved;
}
/**
* Sets the list of resolved dependencies to be used in the next deployment
*
* @param dependencies the resolved dependencies
*/
public void setResolvedDependencies(List<Dependency> dependencies) {
this.resolved = dependencies;
}
/**
* Gets the list of missing dependencies when the deployment was performed
* on a specific node
*
* @param ghnid the ID of the node
* @return the missing dependencies
*/
public List<Dependency> getMissingDependencies(String ghnid) {
return Collections.unmodifiableList(node2missing.get(ghnid));
}
/**
* Gets the list of missing dependencies for the last (failed) deployment
*
* @return the missing dependencies
*/
public List<Dependency> getLastMissingDependencies() {
return this.missing;
}
/**
* Sets the list of missing dependencies for the next deployment
*
* @param dependencies the missign dependencies
*/
public void setMissingDependencies(List<Dependency> dependencies) {
///this.getLogger().trace("Setting missing deps " + dependencies.size());
missing= dependencies;
}
@Override
protected void find() throws Exception {
//looks for the service and its deps in the Software Repository
@ -96,13 +144,13 @@ public final class ScopedDeployedService extends ScopedResource {
this.setErrorMessage(""); //empty any previous message
try {
request.send();
if (this.getResolvedDependencies().size() == 0) {
if (this.resolved.size() == 0) {
this.success = false;
this.setErrorMessage("Invalid list of dependecies retrieved from the Software Repository");
}
if (this.getMissingDependencies().size() > 0) {//ops, some deps are missing!
if (this.missing.size() > 0) {//ops, some deps are missing!
this.success = false;
this.setErrorMessage("The service cannot be deployed due to one or more missing dependencies: " + this.getMissingDependencies());
this.setErrorMessage("The service cannot be deployed due to one or more missing dependencies: " + this.missing);
}
this.success = true;
} catch (Exception e) {
@ -116,6 +164,7 @@ public final class ScopedDeployedService extends ScopedResource {
@Override
protected void addToScope() throws ResourceNotFound, Exception {
logger.trace("This service belongs to " + this.scope);
if (!this.isSuccess()) {
this.noHopeForMe(this.getErrorMessage(),new Exception());
}
@ -129,12 +178,20 @@ public final class ScopedDeployedService extends ScopedResource {
try {
for (VirtualNode node : this.virtualNodes) {
node.deploy(this.getScope());
//store packages for future undeployment
List<Dependency> packages = new ArrayList<Dependency>();
//store packages for future undeployment and reporting purposes
List<Dependency> resolvedPackages = new ArrayList<Dependency>();
for (Dependency dep : this.resolved)
packages.add(dep);
node2packages.put(node.getID(), packages);
resolvedPackages.add(dep);
node2packages.put(node.getID(), resolvedPackages);
//store missing packages for reporting purposes
List<Dependency> missingPackages = new ArrayList<Dependency>();
for (Dependency dep : this.missing)
missingPackages.add(dep);
if (node2missing == null) {
logger.trace("node2missing is null");
node2missing = new HashMap<String, List<Dependency>>(); // this is here for backwards compatibility
}
node2missing.put(node.getID(), missingPackages);
}
} catch (Exception e) {
this.noHopeForMe("Unable to contact the target gHN ("+ this.lastActivityOnGHN +") where to deploy the service",e);
@ -147,6 +204,7 @@ public final class ScopedDeployedService extends ScopedResource {
@Override
protected void removeFromScope() throws ResourceNotFound, Exception {
logger.trace("This service belongs to " + this.scope);
if (!this.isSuccess()) {
//TODO: could we undeploy static packages here?
this.noHopeForMe(this.getErrorMessage(),new Exception());
@ -161,7 +219,10 @@ public final class ScopedDeployedService extends ScopedResource {
try {
for (VirtualNode node : this.virtualNodes) {
try {
node.undeploy(this.getScope());
if (node2scope.containsKey(node.getID()))
node.undeploy(GCUBEScope.getScope(node2scope.get(node.getID())));
else
node.undeploy(this.getScope()); //try the service's scope
} catch (Exception e) {
this.noHopeForMe("Failed to undeploy from "+ node ,e);
}
@ -178,8 +239,8 @@ public final class ScopedDeployedService extends ScopedResource {
* @throws Exception if the operation fails
*/
public void scheduleUndeploy() {
for (VirtualNode node : this.virtualNodes)
scheduleUndeploy(node);
for (VirtualNode node : this.virtualNodes)
scheduleUndeploy(node);
}
/**
@ -190,6 +251,10 @@ public final class ScopedDeployedService extends ScopedResource {
*/
public void scheduleUndeploy(VirtualNode node) {
getLogger().info("Scheduling undeployment of service "+ this.service+ " from GHN " + this.lastActivityOnGHN);
//notify the node to operate in the scope previously used for the deployment
this.checkNode2Scope();
if (node2scope.containsKey(node.getID())) //it has to be in, but it couldn't if the service was deployed from a previous (version < 1.1)RM instance
node.setWorkingScope(GCUBEScope.getScope(node2scope.get(node.getID())));
//prepare the input list of packagesToAdd for that GHN
List<Dependency> deps = node2packages.get(node.getID());
Set<PackageInfo> packages = new HashSet<PackageInfo>();
@ -214,10 +279,15 @@ public final class ScopedDeployedService extends ScopedResource {
* @throws Exception
*/
public void removeFromScope(String ghnID) throws VirtualNode.NoGHNFoundException, Exception {
logger.trace("This service belongs to " + this.scope);
this.action = ACTION.REMOVE;
for (VirtualNode node : this.virtualNodes)
if (node.getID().compareToIgnoreCase(ghnID) == 0) {
node.undeploy(this.getScope());
checkNode2Scope();
if (node2scope.containsKey(ghnID))
node.undeploy(GCUBEScope.getScope(node2scope.get(ghnID)));
else
node.undeploy(this.getScope()); //try the service's scope
this.virtualNodes.remove(node);
return;
}
@ -235,7 +305,7 @@ public final class ScopedDeployedService extends ScopedResource {
Set<PackageInfo> packages = new HashSet<PackageInfo>();
//prepare the input list of packagesToAdd for that GHN
List<Dependency> deps = this.getResolvedDependencies();
List<Dependency> deps = this.resolved;
for (int i = 0; i < deps.size(); i++) {
PackageInfo p = new PackageInfo();
p.setServiceName(deps.get(i).getService().getName());
@ -247,6 +317,8 @@ public final class ScopedDeployedService extends ScopedResource {
packages.add(p);
}
node.setPackagesToAdd(packages);
this.checkNode2Scope();//for backward compatibility (version <= 1.1)
node2scope.put(node.getID(), node.getWorkingScope().toString());
this.virtualNodes.add(node);
this.lastActivityOnGHN = node.getID();
}
@ -289,4 +361,20 @@ public final class ScopedDeployedService extends ScopedResource {
public List<VirtualNode> getNodes() {
return this.virtualNodes;
}
/**
* Number of times the resource is searched in the IS before to declare it lost
* @return the number of attempts to do
*/
@Override
protected int getMaxFindAttempts(){
return 3;
}
private void checkNode2Scope(){
//this is for backward compatibility, if the obj is loaded from an old serialization
//node2scope could not be initialized
if (this.node2scope == null)
this.node2scope = new HashMap<String, String>();
}
}

View File

@ -98,7 +98,7 @@ public abstract class ScopedResource {
break;
} catch (Exception e) {
logger.warn("Can't find resource "+ this + " on the IS");
if (++i <= max_attempts) {
if (i++ <= max_attempts) {
logger.warn("try again in 5 secs");
try {Thread.sleep(5000);} catch (InterruptedException e1) {}
continue;

View File

@ -1,5 +1,6 @@
package org.gcube.vremanagement.resourcemanager.impl.resources;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
@ -9,8 +10,10 @@ import org.gcube.common.core.contexts.GCUBERemotePortTypeContext;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.QueryParameter;
import org.gcube.common.core.informationsystem.client.XMLResult;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGHNQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBERIQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGenericQuery;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.vremanagement.ghnmanager.stubs.GHNManagerPortType;
@ -38,7 +41,7 @@ public final class ScopedRunningInstance extends ScopedResource {
private String hostedOnID = "";
/** Scopes the instance belongs to */
private List<String> scopes;
private List<String> scopes;
protected ScopedRunningInstance(String id, GCUBEScope scope, String ... hostedOn) {
super(id, TYPE, scope);
@ -51,18 +54,23 @@ public final class ScopedRunningInstance extends ScopedResource {
//looks for the RI to manage
try {
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBERunningInstance profile = null;
GCUBERIQuery query = client.getQuery(GCUBERIQuery.class);
query.addAtomicConditions(new AtomicCondition("/ID/text()", id));
List<GCUBERunningInstance> ris = client.execute(query, ServiceContext.getContext().getScope());
if (ris == null || ris.size() == 0) {
ris = client.execute(query, ServiceContext.getContext().getScope().getEnclosingScope());
if (ris == null || ris.size() == 0) {
//we cannot use here the GCUBERunningInstanceQuery because it returns only ready instances,
//we need to find a RI, no matter in which state it is
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
query.addParameters(new QueryParameter("FILTER", "$result/ID/text()/string() eq \""+id+"\""),
new QueryParameter ("RESULT", "$result"));
List<XMLResult> results = client.execute(query, ServiceContext.getContext().getScope());
//query.addAtomicConditions(new AtomicCondition("/ID/text()", id));
if (results == null || results.size() == 0) {
results = client.execute(query, ServiceContext.getContext().getScope().getEnclosingScope());
if (results == null || results.size() == 0) {
throw new Exception("unable to find target RI "+ this);
}
}
profile = ris.get(0);
GCUBERunningInstance profile = GHNContext.getImplementation(GCUBERunningInstance.class);
profile.load(new StringReader(results.get(0).evaluate("/").get(0)));
this.sourceService = new ServiceData();
this.sourceService.serviceID = profile.getServiceID();
this.sourceService.serviceClass = profile.getServiceClass();
@ -157,7 +165,7 @@ public final class ScopedRunningInstance extends ScopedResource {
this.noHopeForMe("Failed to remove RunningInstance from scope " + scope.toString() +". Can't find the related service to undeploy "+ e.getMessage(),e);
}
if (this.scopes.size() == 1) {
getLogger().info(this + " joins in this scope: it's going to be undeployed");
getLogger().info(this + " joins only this scope: it's going to be undeployed");
return true;
}
return false;
@ -191,6 +199,9 @@ public final class ScopedRunningInstance extends ScopedResource {
return 40;
}
/**
*
* Groups some service data

View File

@ -32,8 +32,8 @@ public final class InstanceState extends GCUBEWSResource {
protected ScopeState scopeState;
/** report id -> report map*/
static Map<String, ResourceReport> id2report = Collections.synchronizedMap(new HashMap<String, ResourceReport>());;
/** session id -> session map*/
static Map<String, Session> id2session = Collections.synchronizedMap(new HashMap<String, Session>());;
@SuppressWarnings("unchecked")
@Override
@ -87,38 +87,38 @@ public final class InstanceState extends GCUBEWSResource {
/**
* Gets the {@link ResourceReport}
* Gets the {@link Session}
*
* @param id the report ID
* @return the report
* @param id the session ID
* @return the session
* @throws IOException
*/
public ResourceReport getReport(String id) throws IOException {
if (! id2report.containsKey(id))
id2report.put(id, ResourceReport.load(id));
return id2report.get(id);
public Session getSession(String id) throws IOException {
if (! id2session.containsKey(id))
id2session.put(id, Session.load(id));
return id2session.get(id);
}
/**
* Gets the string representation of a {@link ResourceReport}
* Gets the string representation of a {@link Session}
*
* @param id the report ID
* @return the string representation of the report
* @param id the session ID
* @return the string representation of the session
* @throws IOException
*/
public String getReportAsString(String id) throws IOException {
return ResourceReport.loadAsString(id);
public String getSerializedSession(String id) throws IOException {
return Session.loadAsString(id);
}
/**
* Adds a new {@link ResourceReport} to the service's state
* Adds a new {@link Session} to the service's state
*
* @param report the report to add
* @param session the session to add
*/
public void addReport(ResourceReport report) {
this.getResourceList().setLastReport(report);
id2report.put(report.getId(), report);
public void addSession(Session session) {
this.getResourceList().setLastSession(session);
id2session.put(session.getId(), session);
}
/**

View File

@ -32,7 +32,7 @@ public class ScopeState extends Observable {
private RawScopeState rawState;
private ResourceReport report;
private Session report;
protected ScopeState() {}
@ -298,18 +298,18 @@ public class ScopeState extends Observable {
}
/**
* Gets the last active {@link ResourceReport}
* @return the report
* Gets the last active {@link Session}
* @return the session
*/
public ResourceReport getLastReport() {
public Session getLastReport() {
return this.report;
}
/**
* Sets the last active {@link ResourceReport}
* @param report the report
* Sets the last active {@link Session}
* @param session the session
*/
public void setLastReport(ResourceReport report) {
public void setLastSession(Session report) {
this.report = report;
}

View File

@ -28,12 +28,14 @@ import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STA
import org.kxml2.io.KXmlSerializer;
/**
* Integrated deployment report. It collects the report sent by the Deployer Service and build a single integrated report
* Session for each service operation.
* It holds all the information related to the activities performed to
* satisfy the caller's request.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class ResourceReport implements Serializable {
public class Session implements Serializable {
protected final GCUBELog logger = new GCUBELog(this, ServiceContext.getContext());
@ -63,7 +65,7 @@ public class ResourceReport implements Serializable {
/** Status of a dependency resolver request */
public enum DEPSTATUS {SUCCESS, FAILED};
public enum OPERATION {AddResources, UpdateResource, RemoveResources, Dispose, Create};
public enum OPERATION {Create, AddResources, UpdateResources, RemoveResources, Dispose};
private Set<ScopedDeployedService> services = Collections.synchronizedSet(new HashSet<ScopedDeployedService>());
@ -71,15 +73,17 @@ public class ResourceReport implements Serializable {
/** the instances deployed by the services included in this report*/
private Set<DeployedRunningInstance> instances = new HashSet<DeployedRunningInstance>();
private String deploymentPlan;
/** internally used by {@link ResourceReport#loadAsString(String)}*/
private ResourceReport () {}
/** internally used by {@link Session#loadAsString(String)}*/
private Session () {}
/**
* Builds a new empty report
* @param id the session ID assigned to the operation
*/
public ResourceReport(String id, OPERATION operation, GCUBEScope ... scope) {
public Session(String id, OPERATION operation, GCUBEScope ... scope) {
this.id = id;
this.operation = operation;
if ((scope == null)|| (scope[0] == null))
@ -117,8 +121,9 @@ public class ResourceReport implements Serializable {
//serializer.setProperty(XmlSerializer, "\t");
try {
serializer.startDocument("UTF-8", true);
serializer.startTag(NS,"ResourceReport");
serializer.startTag(NS,"Session");
serializer.startTag(NS,"ID").text(this.id).endTag(NS, "ID");
serializer.startTag(NS,"Status").text(this.isReportClosed()?"CLOSED" :"OPEN").endTag(NS, "Status");
serializer.startTag(NS,"Operation").text(this.operation.toString()).endTag(NS, "Operation");
serializer.startTag(NS,"LastUpdate").text(ProfileDate.toXMLDateAndTime(this.lastUpdate.getTime())).endTag(NS,"LastUpdate");
serializer.startTag(NS,"TargetScope").text(this.scope.toString()).endTag(NS,"TargetScope");
@ -160,7 +165,7 @@ public class ResourceReport implements Serializable {
serializer.startTag(NS,"Version").text(service.getSourceService().getVersion()).endTag(NS, "Version");
if (((this.operation == OPERATION.AddResources) ||(this.operation == OPERATION.Create))
&& (service.getStatus() != STATUS.LOST) && (this.brokerWasSuccessful)) {
if ( (service.getMissingDependencies().size() > 0) || (service.getErrorMessage().length() > 0) ) {
if ( (service.getMissingDependencies(service.getTargetGHNID()).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");
@ -172,7 +177,7 @@ public class ResourceReport implements Serializable {
serializer.startTag(NS,"DependenciesResolution");
//resolved dependencies
serializer.startTag(NS,"ResolvedDependencies");
for (Dependency dep : service.getResolvedDependencies()) {
for (Dependency dep : service.getResolvedDependencies(service.getTargetGHNID())) {
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");
@ -184,7 +189,7 @@ public class ResourceReport implements Serializable {
serializer.endTag(NS,"ResolvedDependencies");
//missing dependencies
serializer.startTag(NS,"MissingDependencies");
for (Dependency dep : service.getMissingDependencies()) {
for (Dependency dep : service.getMissingDependencies(service.getTargetGHNID())) {
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");
@ -209,7 +214,7 @@ public class ResourceReport implements Serializable {
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));
this.addGHNReport(serializer, node2report.get(reportID), service);
serializer.endTag(NS, "LastReportReceived");
serializer.endTag(NS,"GHN");
DeployedRunningInstance instance = this.getInstanceForService(service);
@ -226,12 +231,12 @@ public class ResourceReport implements Serializable {
} else if (node2report.get(reportID).getStatus().compareToIgnoreCase("CLOSED") == 0 ) {
serializer.startTag(NS,"RelatedRunningInstance");
serializer.startTag(NS,"Status").text("FAILED").endTag(NS,"Status");
serializer.startTag(NS,"Message").text("The Deployer service did not detect any instance of this service on the target gHN").endTag(NS,"Message");
serializer.startTag(NS,"Message").text("The Deployer service did not detect any new instance of this service on the target gHN").endTag(NS,"Message");
serializer.endTag(NS,"RelatedRunningInstance");
}
}
} else {
if (service.isSuccess())
if (service.isSuccess() && (this.brokerReportAvailable))
serializer.text("The report is still not available for this service");
else
serializer.text("No report");
@ -242,17 +247,15 @@ public class ResourceReport implements Serializable {
else
serializer.endTag(NS,"UndeploymentActivity");
serializer.endTag(NS,"Service");
}
serializer.endTag(NS,"Services");
serializer.endTag(NS,"ResourceReport");
serializer.endTag(NS,"Session");
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");
throw new IOException("The Resource Report does not have a valid serialisation "+ e.getMessage());
}
finally {
report.close();
@ -314,8 +317,8 @@ public class ResourceReport implements Serializable {
* @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();
protected static Session load(String id) throws IOException {
Session report = new Session();
// load the report from its serialization
return report;
@ -352,19 +355,20 @@ public class ResourceReport implements Serializable {
}
private void addGHNReport(KXmlSerializer serializer, DeployerReport report) throws Exception {
private void addGHNReport(KXmlSerializer serializer, DeployerReport report, ScopedDeployedService service) 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");
if (this.isDepOfService(dep, service, report.getGHNID())) {
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");
@ -389,5 +393,71 @@ public class ResourceReport implements Serializable {
this.instances.addAll(instances);
}
/**
* Checks if a dependency belongs to a specific service
* @param dep the dependency to check
* @param service the potential owner service
* @return true if the dependency belongs the service
*/
private boolean isDepOfService(DeployedDependency dep, ScopedDeployedService service,String targetGHNID) {
for (Dependency resolvedDependency : service.getResolvedDependencies(targetGHNID)) {
if (dep.equals((Dependency)resolvedDependency)) return true;
}
return false;
}
/**
* Checks whether the report is closed or no
* @return true if the report is closed, false otherwise
*/
public boolean isReportClosed() {
for ( ScopedResource resource : this.resources) {
if ((resource.getStatus() == STATUS.ADDREQUESTED) || (resource.getStatus() == STATUS.REMOVEREQUESTED))
return false;//the resource still need to be managed
}
for (ScopedDeployedService service : this.services) {
String reportID = service.getTargetGHNID();
if (service.isSuccess() && (this.brokerWasSuccessful)) {
//check the availability of the report and its status
if (! node2report.keySet().contains(reportID)) {
return false;
} else if (node2report.get(reportID).getStatus().compareToIgnoreCase("CLOSED") != 0){
return false;
}
}
}
return true;
}
public Set<ScopedDeployedService> getServices() {
return this.services;
}
/**
* Gets all the GHN reports received
* @return a map where the key is the GHN ID and the value is the related report
*/
public Map<String, DeployerReport> getAllGHNReports() {
return node2report;
}
/**
* @return the {@link OPERATION} related to this report
*/
public OPERATION getOperation() {
return operation;
}
public void setDeploymentPlan(String plan) {
this.deploymentPlan = plan;
}
public String getDeploymentPlan() throws IOException {
if (this.deploymentPlan == null)
throw new IOException("No Deployment Plan is available");
return this.deploymentPlan;
}
}

View File

@ -52,8 +52,8 @@ public class Executor extends ScopeObserver {
ScopedDeployedService service = ScopedResourceFactory.getRelatedService((ScopedRunningInstance)resource);
if (service.getNodes().size() > 1) {
logger.debug("Removing " + service + " from node " + resource.getHostedOn());
//there exists other instances of the service in the scope, we are going to remove only this one
service.scheduleUndeploy(VirtualNodeManager.getNode(hostedOnID, scopeState.getScope()));
//there exist other instances of the service in the scope, we are going to remove only this one
service.scheduleUndeploy(VirtualNodeManager.getNode(hostedOnID, resource.getScope()));
service.setCallbackID(scopeState.getLastReport().getId());
scopeState.getLastReport().addResource(service);
scopeState.getLastReport().addService(service);

View File

@ -36,7 +36,7 @@ public class DisposeScopeTest {
String reportID = pt.disposeScope(new DisposeScopeParameters(args[2]));
logger.info("Returned report ID: " + reportID);
} catch (Exception e) {
logger.fatal("Failed to create VRE",e);
logger.fatal("Failed to dispose the VRE",e);
}
}

View File

@ -10,9 +10,11 @@ callerScope=/gcube/devsec/CNR-VRE
service.1.name=MetadataManager
service.1.class=MetadataManagement
service.1.version=1.00.00
service.1.GHN=ccc70030-6225-11df-b8c4-c9bf4572cf57
service.2.name=XMLIndexer
service.2.class=MetadataManagement
service.2.version=1.00.00
service.2.GHN=ccc70030-6225-11df-b8c4-c9bf4572cf57
#GHNID(s) on which the services will be deployed
GHNSet=233ecf30-5f77-11df-a7f3-937828a57691
#GHNSet=

View File

@ -35,4 +35,4 @@ service.2.class=MetadataManagement
service.2.version=1.00.00
#GHNID(s) on which the services will be deployed
GHNSet=c0b5e940-5f6f-11df-85bd-da352f223a9e
GHNSet=b82c3290-62d3-11df-bf23-e96f2ebe5fa6

View File

@ -1,11 +1,12 @@
callerScope=/gcube/devsec/FAO-VRE
callerScope=/d4science.research-infrastructures.eu/FARM/ICIS
# scope options
creator=CN=Manuele Simi, L=NMIS-ISTI, OU=Personal Certificate, O=INFN, C=IT
designer=CN=Manuele Simi, L=NMIS-ISTI, OU=Personal Certificate, O=INFN, C=IT
creator=anton.ellenbroek
designer=andrea.manzi
securityenabled=false
displayName=FAO-VRE
description=Sample VRE for FAO
#startTime=2008-11-27T16:58:12+01:00
displayName=ICIS
description=<b>Integrated Capture Information System (ICIS)VRE</b><br/><b><i>Purpose</i></b>: Facilitate the collection, curation and dissimination of Fisheries statistics<br/><b><i>Target audience</i></b>: Fishery statisticians, marine biologists<br/><b><i>Implementation</i></b>:<br/>ICIS offers fisheries statisticians a set of tools to manage their data.Statisticians produce statistics from often very different data sources, and need a controlled process for the ingestion, validation, transformation, comparison and exploitation of statistical data for the fisheries captures domain. There is a need to:<ul><li> Collect and analyze capture data; </li><li> Check and control data and data-quality;</li><li> Produce uniform data-sets for consumption by outside clients, such as the FishStatJ application;</li><li> Provide an authoritative data-repository for fisheries data. </li></ul><br/>Also, there is a growing interest to share data and use statistical data in other use-scenarios, such as spatial analysis or reporting. The D4Science grid e-Infrastructure offers not only collaborative and computing advantages, but also promises to ease the difficult transformations from one reporting framework to another.
startTime=2010-06-07T18:42:49+02:00
endTime=2012-06-07T18:42:49+02:00

View File

@ -1 +1 @@
java -cp .:./lib/org.gcube.resourcemanagement.manager.testsuite.jar:$CLASSPATH org/gcube/vremanagement/vremanager/stubs/testsuite/SetScopeOptionsTest $1 $2 $3
java -cp .:./lib/org.gcube.resourcemanagement.manager.testsuite.jar:$CLASSPATH org/gcube/vremanagement/resourcemanager/stubs/testsuite/SetScopeOptionsTest $1 $2 $3