You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
rmp-common-library/src/main/java/org/gcube/resourcemanagement/support/server/managers/resources/AbstractResourceManager.java

799 lines
31 KiB
Java

/****************************************************************************
* This software is part of the gCube Project.
* Site: http://www.gcube-system.org/
****************************************************************************
* The gCube/gCore software is licensed as Free Open Source software
* conveying to the EUPL (http://ec.europa.eu/idabc/eupl).
* The software and documentation is provided by its authors/distributors
* "as is" and no expressed or
* implied warranty is given for its use, quality or fitness for a
* particular case.
****************************************************************************
* Filename: ResourceManager.java
****************************************************************************
* @author <a href="mailto:daniele.strollo@isti.cnr.it">Daniele Strollo</a>
***************************************************************************/
package org.gcube.resourcemanagement.support.server.managers.resources;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Vector;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.gcube.common.core.contexts.GCUBERemotePortTypeContext;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.XMLResult;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGenericQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBERIQuery;
import org.gcube.common.core.informationsystem.publisher.ISPublisher;
import org.gcube.common.core.resources.GCUBEResource;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.scope.GCUBEScope.Type;
import org.gcube.common.core.security.GCUBESecurityManagerImpl;
import org.gcube.resourcemanagement.support.server.exceptions.AbstractResourceException;
import org.gcube.resourcemanagement.support.server.exceptions.ResourceAccessException;
import org.gcube.resourcemanagement.support.server.exceptions.ResourceOperationException;
import org.gcube.resourcemanagement.support.server.exceptions.ResourceParameterException;
import org.gcube.resourcemanagement.support.server.managers.report.ReportBuilder;
import org.gcube.resourcemanagement.support.server.managers.report.ReportEntry;
import org.gcube.resourcemanagement.support.server.managers.report.ReportOperation;
import org.gcube.resourcemanagement.support.server.managers.scope.ScopeManager;
import org.gcube.resourcemanagement.support.server.types.AllowedResourceTypes;
import org.gcube.resourcemanagement.support.server.utils.Assertion;
import org.gcube.resourcemanagement.support.server.utils.ServerConsole;
import org.gcube.vremanagement.resourcemanager.stubs.binder.AddResourcesParameters;
import org.gcube.vremanagement.resourcemanager.stubs.binder.RemoveResourcesParameters;
import org.gcube.vremanagement.resourcemanager.stubs.binder.ResourceBinderPortType;
import org.gcube.vremanagement.resourcemanager.stubs.binder.ResourceItem;
import org.gcube.vremanagement.resourcemanager.stubs.binder.ResourceList;
import org.gcube.vremanagement.resourcemanager.stubs.binder.service.ResourceBinderServiceAddressingLocator;
import org.gcube.vremanagement.resourcemanager.stubs.reporting.ReportingPortType;
import org.gcube.vremanagement.resourcemanager.stubs.reporting.service.ReportingServiceAddressingLocator;
/**
* The minimal interface all the resource managers must implement.
* Here is implemented the greatest part of the operations exposed in the
* <a href="https://gcube.wiki.gcube-system.org/gcube/index.php/Programmatic_Administration_Interface">
* official wiki</a>.
* @author Daniele Strollo (ISTI-CNR)
*/
public abstract class AbstractResourceManager {
private String id = null;
private String name = null;
private AllowedResourceTypes type = null;
private String subType = null;
private ISClient client = null;
private GCUBESecurityManagerImpl managerSec = null;
private ISPublisher publisher = null;
private static final String LOG_PREFIX = "[AbstractResMgr]";
/**
* @deprecated discouraged use. With no ID some operations cannot be accessed. For internal use only.
*/
public AbstractResourceManager(final AllowedResourceTypes type)
throws ResourceParameterException, ResourceAccessException {
Assertion<ResourceParameterException> checker = new Assertion<ResourceParameterException>();
checker.validate(type != null, new ResourceParameterException("Invalid Parameter type"));
this.type = type;
/**
* Initially the security management is disabled.
*/
this.managerSec = new GCUBESecurityManagerImpl() {
public boolean isSecurityEnabled() {
return false;
}
};
try {
client = GHNContext.getImplementation(ISClient.class);
} catch (Exception e) {
throw new ResourceAccessException("Cannot instantiate the ISClient");
}
try {
this.publisher = GHNContext.getImplementation(ISPublisher.class);
} catch (Exception e) {
ServerConsole.error(LOG_PREFIX, e);
}
}
/**
* Instantiate the handler of a resource given its identifier and its type.
* Notice that this constructor is implicitly invoked when instantiating the
* concrete resource manager (e.g. new GHNManager(id)).
* @param id the identifier of the resource the manage
* @param type the type (GHN, RI, ...).
* @throws ResourceParameterException
* @throws ResourceAccessException
*/
public AbstractResourceManager(
final String id,
final AllowedResourceTypes type)
throws ResourceParameterException, ResourceAccessException {
this(type);
Assertion<ResourceParameterException> checker = new Assertion<ResourceParameterException>();
checker.validate(id != null && id.trim().length() > 0, new ResourceParameterException("Invalid Parameter id"));
this.id = id.trim();
}
public AbstractResourceManager(
final String id,
final String name,
final AllowedResourceTypes type)
throws ResourceParameterException, ResourceAccessException {
this(id, type);
Assertion<ResourceParameterException> checker = new Assertion<ResourceParameterException>();
checker.validate(name != null && name.trim().length() > 0, new ResourceParameterException("Invalid Parameter name"));
this.name = name;
}
public AbstractResourceManager(
final String id,
final String name,
final AllowedResourceTypes type,
final String subtype)
throws ResourceParameterException, ResourceAccessException {
this(id, name, type);
if (subtype != null) {
this.subType = subtype.trim();
}
}
/**
* The singleton ISClient instance is preferred.
* All resource managers can internally access this instance
* to make queries to the IS.
* @return
*/
protected final ISClient getISClient() {
return this.client;
}
/**
* The singleton ISPublisher instance is preferred.
* All resource managers can internally access this instance
* to interact with ISPublisher to handle resources.
* @return
*/
public final ISPublisher getISPublisher() {
return publisher;
}
public final void setSecurityManager(final GCUBESecurityManagerImpl securityManager) {
this.managerSec = securityManager;
}
/**
* The security manager is initially instantiated with empty permissions.
* The {@link AbstractResourceManager#setSecurityManager} can be used to
* change it.
* @return
*/
public final GCUBESecurityManagerImpl getSecurityManager() {
return this.managerSec;
}
/**
* All resources must be identifiable through an unique ID.
* <br/>
* <b>This field is mandatory</b>
* @return
*/
public final String getID() {
return this.id;
}
public final void setID(final String id) {
this.id = id;
}
/**
* All resources must have a valid name.
* </br>
* <b>This field is mandatory</b>
* @return
*/
public final String getName() {
return this.name;
}
/**
* All resources have a type.
* </br>
* <b>This field is mandatory</b>
* @return
*/
public final AllowedResourceTypes getType() {
return this.type;
}
/**
* Resources can have a subtype (e.g. for GHNs is the domain).
* </br>
* <b>This field is optional</b>
* @return
*/
public final String getSubType() {
return this.subType;
}
/**
* Internally used by {@link AbstractResourceManager#getResourceManager(GCUBEScope)}.
* @param scope
* @return a raw list of resource manager descriptors.
* @throws Exception
*/
private List<GCUBERunningInstance> getResourceManagerFromScope(final GCUBEScope scope)
throws Exception {
GCUBERIQuery query = this.client.getQuery(GCUBERIQuery.class);
query.addAtomicConditions(new AtomicCondition("//Profile/ServiceClass", "VREManagement"));
query.addAtomicConditions(new AtomicCondition("//Profile/ServiceName", "ResourceManager"));
List<GCUBERunningInstance> result = client.execute(query, scope);
List<GCUBERunningInstance> toReturn = new ArrayList<GCUBERunningInstance>();
for (GCUBERunningInstance ri : result) {
if (ri.getScopes().containsValue(scope)) {
toReturn.add(ri);
}
}
return toReturn;
}
/**
* The the list of resource managers able to handle the resource in a given scope.
* @param scope the scope in which to operate
* @return all the available managers
* @throws ResourceAccessException if no manager can be instantiated
* @throws ResourceParameterException if the parameters are invalid
*/
public final List<ResourceBinderPortType> getResourceManagers(final GCUBEScope scope) throws ResourceAccessException, ResourceParameterException {
Assertion<ResourceParameterException> checker = new Assertion<ResourceParameterException>();
checker.validate(scope != null, new ResourceParameterException("Invalid scope"));
List<GCUBERunningInstance> resourceManagerList = null;
try {
resourceManagerList = this.getResourceManagerFromScope(scope);
} catch (Exception e) {
e.printStackTrace();
throw new ResourceAccessException("Cannot retrieve the managers for resource: " + this.getID());
}
List<ResourceBinderPortType> retval = new Vector<ResourceBinderPortType>();
if (resourceManagerList.isEmpty()) {
throw new ResourceAccessException("Unable to find ResourceManagers for resource " + this.getType() + " in scope: " + scope.toString());
}
EndpointReferenceType endpoint = null;
ResourceBinderPortType pt = null;
for (GCUBERunningInstance resourceManager : resourceManagerList) {
try {
endpoint = resourceManager.getAccessPoint().getEndpoint("gcube/vremanagement/resourcemanager/binder");
pt = GCUBERemotePortTypeContext.getProxy(
new ResourceBinderServiceAddressingLocator()
.getResourceBinderPortTypePort(endpoint),
scope,
this.managerSec);
if (pt != null) {
retval.add(pt);
}
} catch (Throwable e) {
// trying on next entry
ServerConsole.error(LOG_PREFIX, e);
}
}
if (retval != null && retval.size() > 0) {
// Return a random manager from the available ones
return retval;
}
// no managers found
throw new ResourceAccessException("Unable to find ResourceManagers for resource " + this.getID() + "in scope: " + scope.toString());
}
/**
* The the list of resource report managers able to handle the resource in a given scope.
* @param scope the scope in which to operate
* @return all the available managers
* @throws ResourceAccessException if no manager can be instantiated
* @throws ResourceParameterException if the parameters are invalid
*/
public final List<ReportingPortType> getResourceReportManagers(final GCUBEScope scope) throws ResourceAccessException, ResourceParameterException {
Assertion<ResourceParameterException> checker = new Assertion<ResourceParameterException>();
checker.validate(scope != null, new ResourceParameterException("Invalid scope"));
List<GCUBERunningInstance> resourceManagerList = null;
try {
resourceManagerList = this.getResourceManagerFromScope(scope);
} catch (Exception e) {
e.printStackTrace();
throw new ResourceAccessException("Cannot retrieve the managers for resource: " + this.getID());
}
List<ReportingPortType> retval = new Vector<ReportingPortType>();
if (resourceManagerList.isEmpty()) {
throw new ResourceAccessException("Unable to find ResourceManagers for resource " + this.getType() + " in scope: " + scope.toString());
}
EndpointReferenceType endpoint = null;
ReportingPortType pt = null;
for (GCUBERunningInstance resourceManager : resourceManagerList) {
try {
endpoint = resourceManager.getAccessPoint().getEndpoint("gcube/vremanagement/resourcemanager/reporting");
pt = GCUBERemotePortTypeContext.getProxy(
new ReportingServiceAddressingLocator().getReportingPortTypePort(endpoint),
scope,
this.managerSec);
if (pt != null) {
retval.add(pt);
}
} catch (Throwable e) {
// trying on next entry
ServerConsole.error(LOG_PREFIX, e);
}
}
if (retval != null && retval.size() > 0) {
// Return a random report manager from the available ones
return retval;
}
// no managers found
throw new ResourceAccessException("Unable to find ReportResourceManagers for resource " + this.getID() + "in scope: " + scope.toString());
}
/**
* The resource manager needed to handle the resource in a given scope.
* @param scope the scope in which to operate
* @return a random chosen manager from the avaiable ones
* @throws ResourceAccessException if no manager can be instantiated
* @throws ResourceParameterException if the parameters are invalid
*/
public final ResourceBinderPortType getResourceManager(final GCUBEScope scope)
throws AbstractResourceException {
ServerConsole.info(LOG_PREFIX, "Getting Resource Manager in scope [" + scope.toString() + "]");
List<ResourceBinderPortType> retval = this.getResourceManagers(scope);
if (retval != null && retval.size() > 0) {
Random generator = new Random();
// Return a random manager from the available ones
ResourceBinderPortType manager = retval.get(generator.nextInt(retval.size()));
return manager;
}
// no managers found
throw new ResourceAccessException("Unable to find ResourceManagers for resource " + this.getType() + " in scope: " + scope.toString());
}
/**
* The report resource manager needed to handle the resource in a given scope.
* @param scope the scope in which to operate
* @return a random chosen manager from the avaiable ones
* @throws ResourceAccessException if no manager can be instantiated
* @throws ResourceParameterException if the parameters are invalid
*/
public final ReportingPortType getReportResourceManager(final GCUBEScope scope)
throws AbstractResourceException {
ServerConsole.info(LOG_PREFIX, "Getting Resource Manager in scope [" + scope.toString() + "]");
List<ReportingPortType> retval = this.getResourceReportManagers(scope);
if (retval != null && retval.size() > 0) {
Random generator = new Random();
// Return a random manager from the available ones
ReportingPortType manager = retval.get(generator.nextInt(retval.size()));
return manager;
}
// no managers found
throw new ResourceAccessException("Unable to find ResourceManagers for resource " + this.getType() + " in scope: " + scope.toString());
}
/**
* Once the conditions for binding a resource to a target scope are satisfied
* (see the
* <a href="https://gcube.wiki.gcube-system.org/gcube/index.php/Programmatic_Administration_Interface">
* official wiki</a>
* for scope binding rules) this method is internally called.
* @param targetScope
* @return
* @throws ResourceOperationException
*/
private String bindToScope(final GCUBEScope targetScope) throws AbstractResourceException {
Assertion<AbstractResourceException> checker = new Assertion<AbstractResourceException>();
checker.validate(targetScope != null, new ResourceParameterException("Invalid parameter targetScope. null not allowed."));
checker.validate(this.getID() != null, new ResourceOperationException("Invalid resource ID. null not allowed."));
ServerConsole.trace(
LOG_PREFIX,
"[BIND-SCOPE-ENTER] Adding " + this.getType() + " " + this.getID() + " to scope [" +
targetScope.toString() + "]");
AddResourcesParameters addParam = new AddResourcesParameters();
ResourceItem toAdd = new ResourceItem();
toAdd.setID(this.getID());
toAdd.setType(this.getType().name());
ResourceList r = new ResourceList();
r.setResource(new ResourceItem[]{toAdd});
addParam.setResources(r);
addParam.setTargetScope(targetScope.toString());
ResourceBinderPortType manager = this.getResourceManager(targetScope);
try {
String reportID = manager.addResources(addParam);
ServerConsole.trace(
LOG_PREFIX,
"[BIND-SCOPE-EXIT] Applyed Adding " + this.getType() + " " + this.getID() + " to scope [" +
targetScope.toString() + "]... reportID: " + reportID);
ReportingPortType pt = this.getReportResourceManager(targetScope);
return pt.getReport(reportID);
} catch (Exception e) {
e.printStackTrace();
ServerConsole.trace(
LOG_PREFIX,
"[BIND-SCOPE-EXIT] [FAILURE]");
throw new ResourceOperationException("During resource::addToScope: " + e.getMessage());
}
}
/**
* Add a scope to a gHN and the related Service Map is already available on the gHN.
* @param nestingPublication true for resources different from gHN and RI.
* @return the reportID generated
*/
public final String addToExistingScope(
final GCUBEScope sourceScope, final GCUBEScope targetScope)
throws AbstractResourceException {
Assertion<AbstractResourceException> checker = new Assertion<AbstractResourceException>();
checker.validate(sourceScope != null, new ResourceParameterException("Invalid parameter sourceScope. null not allowed."));
checker.validate(targetScope != null, new ResourceParameterException("Invalid parameter targetScope. null not allowed."));
checker.validate(this.getID() != null, new ResourceOperationException("Invalid resource ID. null not allowed."));
ReportBuilder report = new ReportBuilder();
ServerConsole.trace(
LOG_PREFIX,
"[ADD-ToExistingScope] Adding from scope [" +
sourceScope.toString() +
"] to existing scope [" +
targetScope.toString() +
"] " + this.getType() + " " + this.getID());
// If not RI or GHN and the scopes are sibling and VO copyFromToVO
if (!(this.getType() == AllowedResourceTypes.GHN) &&
!(this.getType() == AllowedResourceTypes.RunningInstance) &&
sourceScope.getType() == Type.VO && targetScope.getType() == Type.VO) {
return copyFromToVO(sourceScope, targetScope);
}
// Add a gCube Resource to
// (i) a VRE scope from the parent VO or
// (ii) a VO scope from the infrastructure scope
if (!targetScope.isEnclosedIn(sourceScope)) {
throw new ResourceOperationException(
"You are not allowed to apply to this scope. Target scope is not enclosed in the source one.");
}
report.addEntry(new ReportEntry(ReportOperation.AddToScope, this,
"Added " + this.getType() + " " + this.getID() + " to parent scope " +
targetScope.toString() + " the remote report ID is: " +
this.bindToScope(targetScope), true));
return report.getXML();
}
/**
* Similar to the {@link AbstractResourceManager#addToExistingScope} method but involves
* two scopes of type VO.
* Notice that this operation in reserved for resources different from gHN and RI.
* See
* <a href="https://gcube.wiki.gcube-system.org/gcube/index.php/Programmatic_Administration_Interface#Add_a_gCube_Resource_from_a_VO_to_another_VO">
* here</a> for further details.
* @param sourceScope
* @param targetScope
* @return
* @throws AbstractResourceException
*/
public final String copyFromToVO(final GCUBEScope sourceScope, final GCUBEScope targetScope)
throws AbstractResourceException {
Assertion<AbstractResourceException> checker = new Assertion<AbstractResourceException>();
checker.validate(
sourceScope != null && sourceScope.getType() == Type.VO,
new ResourceParameterException("The sourceScope is invalid or not of type VO."));
checker.validate(
targetScope != null && targetScope.getType() == Type.VO,
new ResourceParameterException("The targetScope is invalid or not of type VO."));
checker.validate(
sourceScope.getEnclosingScope() == targetScope.getEnclosingScope(),
new ResourceParameterException("The sourceScope and targetScope must be children of the same root VO."));
checker.validate(this.getType() != AllowedResourceTypes.GHN && this.getType() != AllowedResourceTypes.RunningInstance,
new ResourceAccessException("Operation not allowed for RI and GHNs."));
checker.validate(this.getID() != null,
new ResourceAccessException("Operation not allowed on resources with no ID."));
// Phase 1. retrieve the resource to copy
GCUBEResource resStub = this.getGCUBEResource(sourceScope);
// Phase 2. Before to register the resource, the scope must be
// bound to the local GCUBEResource
this.bindToScope(targetScope);
// Phase 3. Register to the new VO through the ISPublisher
try {
return this.getISPublisher().registerGCUBEResource(resStub, targetScope, this.getSecurityManager());
} catch (Exception e) {
throw new ResourceAccessException(e.getMessage());
}
}
/**
* Given the XML profile representation of a gcube resource, its GCUBEResource is built.
* Since it depends on the type of the resource, each concrete implementation of resource
* managers must implement it.
* @param xmlRepresentation
* @return
* @throws AbstractResourceException
*/
protected abstract GCUBEResource buildGCUBEResource(final String xmlRepresentation) throws AbstractResourceException;
/**
* From a resource retrieves its GCUBEResource depending on the scope in which it is
* published.
* @param scope
* @return
* @throws AbstractResourceException
*/
public final GCUBEResource getGCUBEResource(final GCUBEScope scope) throws AbstractResourceException {
return this.buildGCUBEResource(this.getXMLDescription(scope));
}
/**
* Returns the XML profile of a resource (given its ID that is encapsulated inside the resource
* manager).
* @param scope
* @return
* @throws AbstractResourceException
*/
protected final String getXMLDescription(final GCUBEScope scope) throws AbstractResourceException {
Assertion<AbstractResourceException> checker = new Assertion<AbstractResourceException>();
checker.validate(this.getID() != null, new ResourceAccessException("Cannot execute on resources with no ID."));
// Phase 1. retrieve the resource to copy
GCUBEGenericQuery query = null;
try {
query = this.getISClient().getQuery(GCUBEGenericQuery.class);
query.setExpression(
"for $resource in collection('/db/Profiles/" + this.getType().name() + "')//Resource " +
"where ( $resource/ID/string() eq '" +
this.getID() +
"') " +
"return $resource"
);
} catch (Exception e) {
throw new ResourceAccessException(e);
}
XMLResult resDescription = null;
try {
resDescription = this.getISClient().execute(query, scope).get(0);
return resDescription.toString();
} catch (Exception e) {
throw new ResourceAccessException("Cannot retrieve the IS profile for resource: " + this.getID() +
" in scope: " + scope.toString());
}
}
/**
* The first phase of remove form scope.
* This is common to all the resources (RI and GHNs).
* @param scope
* @return
* @throws AbstractResourceException
*/
private String basicRemoveFromScope(final GCUBEScope scope)
throws AbstractResourceException {
Assertion<AbstractResourceException> checker = new Assertion<AbstractResourceException>();
checker.validate(scope != null, new ResourceParameterException("Invalid parameter scope. null not allowed."));
checker.validate(this.getID() != null, new ResourceOperationException("Invalid ID. null not allowed."));
ServerConsole.trace(LOG_PREFIX, "[REMOVE-FROM-SCOPE] Removing from scope [" + scope.toString() + "] " + this.getType() + " " + this.getID());
String retval = null;
RemoveResourcesParameters params = new RemoveResourcesParameters();
ResourceItem toRemove = new ResourceItem();
toRemove.setID(this.getID());
toRemove.setType(this.getType().name());
ResourceList resourcesToRemove = new ResourceList();
resourcesToRemove.setResource(new ResourceItem[]{toRemove});
params.setResources(resourcesToRemove);
params.setTargetScope(scope.toString());
ServerConsole.trace(LOG_PREFIX, "[REMOVE-FROM-SCOPE] Sending the Remove Resource request....");
try {
ResourceBinderPortType manager = this.getResourceManager(scope);
retval = manager.removeResources(params);
} catch (Exception e) {
throw new ResourceOperationException("During removeFrom scope of "
+ this.getType()
+ " " + this.getID() + ": " + e.getMessage());
}
return retval;
}
/**
* Removes the current resource from the scope.
* @param nestingRemoval true for resources different from gHN and RI
*/
public final String removeFromScope(final GCUBEScope scope)
throws AbstractResourceException {
Assertion<AbstractResourceException> checker = new Assertion<AbstractResourceException>();
checker.validate(scope != null, new ResourceParameterException("Invalid parameter scope. null not allowed."));
checker.validate(this.getID() != null, new ResourceOperationException("Invalid ID. null not allowed."));
String retval = this.basicRemoveFromScope(scope);
// -- PHASE 2 - optional
// Builds the stub without the removed scope
GCUBEResource resStub = this.getGCUBEResource(scope);
// Refreshes the local profile
resStub.removeScope(scope);
/*
* These steps are for resources different from GHN and RI
*/
if (!this.getType().equals(AllowedResourceTypes.GHN.name()) &&
!this.getType().equals(AllowedResourceTypes.RunningInstance.name())) {
// Phase 1
// if the resource joins only the current scope, after the removal it has also to be deleted
try {
List<GCUBEScope> boundedScopes = this.validateScopes(resStub.getScopes().values().toArray(new GCUBEScope[]{}));
if (boundedScopes == null) {
ServerConsole.warn(LOG_PREFIX, "[REMOVE-FROM-SCOPE] The resource " + this.getType() + " has no bound scopes");
return retval;
}
if (boundedScopes.size() == 0) {
ServerConsole.trace(LOG_PREFIX, "[REMOVE-FROM-SCOPE] [DELETE-BRANCH] deleting resource since no more scopes remained");
this.getISPublisher().removeGCUBEResource(
this.getID(), this.getType().name(), scope, this.getSecurityManager());
return retval;
} else {
// requires the update of the resources in all other scopes
for (GCUBEScope _scope : boundedScopes) {
if (!scope.equals(_scope)) {
try {
ServerConsole.trace(LOG_PREFIX, "[REMOVE-FROM-SCOPE] [UPDATE-BRANCH] Updating profile in scope [" + _scope.toString() + "]");
this.getISPublisher().updateGCUBEResource(resStub, _scope, getSecurityManager());
} catch (Exception e) {
ServerConsole.error(LOG_PREFIX, e);
}
}
}
}
} catch (Exception e) {
throw new ResourceOperationException(e);
}
}
return retval;
}
/**
* Adds to scopes the required maps (if needed).
* Internally used to ensure that the scopes at Infrastructure or VO level
* have correctly setup the maps.
* @param scopes
* @return
*/
protected List<GCUBEScope> validateScopes(final GCUBEScope[] scopes) {
List<GCUBEScope> retval = new Vector<GCUBEScope>();
for (GCUBEScope scope : scopes) {
try {
retval.add(ScopeManager.getScope(scope.toString()));
} catch (Exception e) {
ServerConsole.error(LOG_PREFIX, e);
}
}
return retval;
}
/**
* @deprecated you must be sure before requiring this operation... take care
* @param scope where the resource is bound
* @throws AbstractResourceException
*/
public final void forceDelete(final GCUBEScope scope) throws AbstractResourceException {
ServerConsole.trace(LOG_PREFIX, "[DELETE] [DELETE-BRANCH] deleting resource since no more scopes remained");
try {
this.getISPublisher().removeGCUBEResource(
this.getID(), this.getType().name(), scope, this.getSecurityManager());
} catch (Exception e) {
ServerConsole.error(LOG_PREFIX, e);
}
}
/**
* Removes a resource.
* According to the
* <a href="https://gcube.wiki.gcube-system.org/gcube/index.php/Programmatic_Administration_Interface">
* official wiki</a> the resource is deleted only if is not bound in other scopes. Otherwise this
* operation simply corresponds to the in deep remove from scope.
* @param scope
* @throws ResourceOperationException
*/
public final void delete(final GCUBEScope scope) throws AbstractResourceException {
Assertion<AbstractResourceException> checker = new Assertion<AbstractResourceException>();
checker.validate(scope != null, new ResourceParameterException("Invalid parameter scope. null not allowed."));
checker.validate(this.getID() != null, new ResourceOperationException("Invalid ID. null not allowed."));
System.out.println("DELETING TYPE: "+ this.getType());
GCUBEResource resStub = this.getGCUBEResource(scope);
List<GCUBEScope> boundedScopes = this.validateScopes(resStub.getScopes().values().toArray(new GCUBEScope[]{}));
ServerConsole.trace(LOG_PREFIX, "[DELETE] " + this.getType() + " " + this.getID() + " in scope [" + scope + "]");
ServerConsole.trace(LOG_PREFIX, "[DELETE] " + this.getType() + " " + this.getID() + " is bound to (" + boundedScopes.size() + ") scopes");
/*
* Removefromscope accetta un boolean piu la resource gia ottenuta.
* boolean per decidere se saltare fase due di update che la ripeto piu volte
* rispetto a qui che lo faccio una volta sola.
*/
for (GCUBEScope _scope : boundedScopes) {
// Removing from the children scopes
if (_scope.isEnclosedIn(scope) || scope.equals(_scope)) {
this.basicRemoveFromScope(_scope);
resStub.removeScope(_scope);
}
}
// Phase 2
// after the removal, the resource must be also updated in the other scopes it belongs to,
// otherwise it will wrongly report there a scope where actually it is not registered anymore.
// In order to do so, the just removed scope must be removed from the local
// GCUBEResource object by invoking the method GCUBEResource.removeScope(<scope to remove>)
// and then the resource must be updated in all the remaining scopes.
if (resStub.getScopes().isEmpty()) {
ServerConsole.trace(LOG_PREFIX, "[DELETE] [DELETE-BRANCH] deleting resource since no more scopes remained");
try {
this.getISPublisher().removeGCUBEResource(
this.getID(), this.getType().name(), scope, this.getSecurityManager());
} catch (Exception e) {
}
} else {
boundedScopes = this.validateScopes(resStub.getScopes().values().toArray(new GCUBEScope[]{}));
for (GCUBEScope _scope : boundedScopes) {
try {
ServerConsole.trace(LOG_PREFIX, "[DELETE] [UPDATE-BRANCH]" + this.getType() + " " + this.getID() + " in scope [" + _scope + "]");
this.getISPublisher().updateGCUBEResource(resStub, _scope, getSecurityManager());
} catch (Exception e) {
ServerConsole.error(LOG_PREFIX, e);
}
}
}
}
}