/**************************************************************************** * 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 Daniele Strollo ***************************************************************************/ 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 * * official wiki. * @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 checker = new Assertion(); 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 checker = new Assertion(); 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 checker = new Assertion(); 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. *
* This field is mandatory * @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. *
* This field is mandatory * @return */ public final String getName() { return this.name; } /** * All resources have a type. *
* This field is mandatory * @return */ public final AllowedResourceTypes getType() { return this.type; } /** * Resources can have a subtype (e.g. for GHNs is the domain). *
* This field is optional * @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 getResourceManagerFromScope(final GCUBEScope scope) throws Exception { System.out.println("Looking for ResourceManager in scope: " + scope); GCUBERIQuery query = this.client.getQuery(GCUBERIQuery.class); query.addAtomicConditions(new AtomicCondition("//Profile/ServiceClass", "VREManagement")); query.addAtomicConditions(new AtomicCondition("//Profile/ServiceName", "ResourceManager")); List result = client.execute(query, scope); List toReturn = new ArrayList(); for (GCUBERunningInstance ri : result) { if (ri.getScopes().containsValue(scope)) { toReturn.add(ri); } } System.out.println("Found " + toReturn.size() +" ResourceManager in scope: " + scope); 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 getResourceManagers(final GCUBEScope scope) throws ResourceAccessException, ResourceParameterException { Assertion checker = new Assertion(); checker.validate(scope != null, new ResourceParameterException("Invalid scope")); List resourceManagerList = null; try { resourceManagerList = this.getResourceManagerFromScope(scope); } catch (Exception e) { e.printStackTrace(); throw new ResourceAccessException("Cannot retrieve the managers for resource: " + this.getID()); } List retval = new Vector(); if (resourceManagerList.isEmpty()) { System.out.println("\n\n\n\n\n****** Schianta qui size: " + resourceManagerList.size() + " scope: " + scope); 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 getResourceReportManagers(final GCUBEScope scope) throws ResourceAccessException, ResourceParameterException { Assertion checker = new Assertion(); checker.validate(scope != null, new ResourceParameterException("Invalid scope")); List resourceManagerList = null; try { resourceManagerList = this.getResourceManagerFromScope(scope); } catch (Exception e) { e.printStackTrace(); throw new ResourceAccessException("Cannot retrieve the managers for resource: " + this.getID()); } List retval = new Vector(); 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 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 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 * * official wiki * for scope binding rules) this method is internally called. * @param targetScope * @return * @throws ResourceOperationException */ private String bindToScope(final GCUBEScope targetScope) throws AbstractResourceException { Assertion checker = new Assertion(); 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 checker = new Assertion(); 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 * * here for further details. * @param sourceScope * @param targetScope * @return * @throws AbstractResourceException */ public final String copyFromToVO(final GCUBEScope sourceScope, final GCUBEScope targetScope) throws AbstractResourceException { Assertion checker = new Assertion(); 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 checker = new Assertion(); 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 checker = new Assertion(); 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 checker = new Assertion(); 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 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 validateScopes(final GCUBEScope[] scopes) { List retval = new Vector(); 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 * * official wiki 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 checker = new Assertion(); 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 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() // 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); } } } } }